ASCII Serial Com
Serial communication library between computers, microcontrollers, FPGAs, etc. Uses only ASCII. Not the most efficient protocol, but meant to be easy to read
Loading...
Searching...
No Matches
ascii_serial_com_dummy_loopback_device.c
1#include <errno.h>
2#include <poll.h>
3#include <stdio.h>
4#include <string.h>
5#include <unistd.h>
6
7#include "asc_exception.h"
8#include "ascii_serial_com.h"
9#include "circular_buffer.h"
11
12#define bufCap 64
13#define littleBufCap 8
15uint8_t buffer_raw[bufCap];
16uint8_t little_buffer[littleBufCap];
17
18char dataBuffer[MAXDATALEN];
19
21circular_buffer_uint8 *asc_in_buf;
22circular_buffer_uint8 *asc_out_buf;
23
25
26CEXCEPTION_T e;
27bool rawLoopback;
28char ascVersion, appVersion, command;
29size_t dataLen;
30
31int timeout = -1;
32
33int main(int argc, char *argv[]) {
34
35 rawLoopback = false;
36 if (argc > 1) {
37 if (strncmp("-h", argv[1], 2) == 0) {
38 fprintf(stderr,
39 "\n ascii_serial_com_dummy_loopback_device [-h] [-l] <infile> "
40 "<outfile>\n\n");
41 fprintf(stderr,
42 " If no filenames are provided, then stdin and stdout are used\n"
43 " -h: show help and exit\n"
44 " -l: Raw loopback mode, ASCII Serial Com will not be used\n"
45 "\n");
46 return 0;
47 }
48 if (strncmp("-l", argv[1], 2) == 0) {
49 fprintf(stderr,
50 "\nRaw loopback mode enabled, ASCII Serial Com will not be "
51 "used.\n\n");
52 rawLoopback = true;
53 }
54 }
55 if (argc == 2 && !rawLoopback) {
56 fprintf(stderr, "Error: either 0 or 2 arguments required:\n");
57 fprintf(stderr,
58 "\n ascii_serial_com_dummy_loopback_device [-h] [-l] <infile> "
59 "<outfile>\n\n");
60 fprintf(stderr,
61 " If no filenames are provided, then stdin and stdout are used\n"
62 " -h: show help and exit\n"
63 " -l: Raw loopback mode, ASCII Serial Com will not be used\n"
64 "\n");
65 return 1;
66 }
67
68 FILE *infile;
69 FILE *outfile;
70 int infileno;
71 int outfileno;
72 if (argc == 3) {
73 const char *infilename = argv[1];
74 const char *outfilename = argv[2];
75 fprintf(stdout, "infile: %s\noutfile: %s\n", infilename, outfilename);
76
77 infile = fopen(infilename, "r");
78 if (!infile) {
79 perror("Error opening input file");
80 fprintf(stderr, "Exiting.\n");
81 return 1;
82 }
83 infileno = fileno(infile);
84 if (infileno < 0) {
85 perror("Error getting infile descriptor");
86 fprintf(stderr, "Exiting.\n");
87 return 1;
88 }
89 outfile = fopen(outfilename, "a+");
90 if (!outfile) {
91 perror("Error opening output file");
92 fprintf(stderr, "Exiting.\n");
93 return 1;
94 }
95 outfileno = fileno(outfile);
96 if (outfileno < 0) {
97 perror("Error getting infile descriptor");
98 fprintf(stderr, "Exiting.\n");
99 return 1;
100 }
101
102 } else { // no args
103 fprintf(stderr, "infile: stdin\noutfile: stdout\n");
104 infile = stdin;
105 outfile = stdout;
106 infileno = STDIN_FILENO;
107 outfileno = STDOUT_FILENO;
108 }
109
110 Try {
111 circular_buffer_init_uint8(&buffer, bufCap, buffer_raw);
112
114 asc_in_buf = ascii_serial_com_get_input_buffer(&asc);
115 asc_out_buf = ascii_serial_com_get_output_buffer(&asc);
116
117 if (rawLoopback) {
118 circular_buffer_io_fd_poll_init(&cb_io, &buffer, &buffer, infileno,
119 outfileno);
120 } else {
121 circular_buffer_io_fd_poll_init(&cb_io, asc_in_buf, asc_out_buf, infileno,
122 outfileno);
123 }
124 }
125 Catch(e) {
126 fprintf(stderr, "Uncaught exception: %u, during init, exiting.\n", e);
127 return 1;
128 }
129
130 while (true) {
131 Try {
132 int poll_ret_code = circular_buffer_io_fd_poll_do_poll(&cb_io, timeout);
133 if (poll_ret_code != 0) {
134 return 1;
135 }
136 // fprintf(stderr,"Input buffer before reading from input\n");
137 // circular_buffer_print_uint8(asc_in_buf, stderr,0);
139
140 if (!rawLoopback && !circular_buffer_is_empty_uint8(asc_in_buf)) {
141 // fprintf(stderr, "About to try to receive message:\n");
142 // fprintf(stderr,"Input buffer before extracting message\n");
143 // circular_buffer_print_uint8(asc_in_buf, stderr,0);
145 &asc, &ascVersion, &appVersion, &command, dataBuffer, &dataLen);
146 if (command != '\0') {
147 fprintf(
148 stderr,
149 "Received message:\n asc and app versions: %c %c\n command: "
150 "%c dataLen: %zu\n data: ",
151 ascVersion, appVersion, command, dataLen);
152 for (size_t iData = 0; iData < dataLen; iData++) {
153 fprintf(stderr, "%c", dataBuffer[iData]);
154 }
155 fprintf(stderr, "\n");
156 fflush(stderr);
158 &asc, ascVersion, appVersion, command, dataBuffer, dataLen);
159 // fprintf(stderr,"Output buffer after receiving outbound message\n");
160 // circular_buffer_print_uint8(asc_out_buf, stderr,0);
161 }
162 }
163
165 // fprintf(stderr,"Output buffer after possibly writing to output\n");
166 // circular_buffer_print_uint8(asc_out_buf, stderr,0);
167
168 // Do we need to process data in the input buffer?
169 // If so, poll with short timeout, otherwise just poll
170 // (all else is just waiting on IO)
171 if (!rawLoopback && !circular_buffer_is_empty_uint8(asc_in_buf)) {
172 timeout = 5; // ms
173 } else {
174 timeout = -1; // unlimited
175 }
176 }
177 Catch(e) { fprintf(stderr, "Uncaught exception: %u, continuing.\n", e); }
178 }
179
180 return 0;
181}
circular_buffer_uint8 * ascii_serial_com_get_output_buffer(ascii_serial_com *asc)
ASCII Serial Com get output buffer.
void ascii_serial_com_init(ascii_serial_com *asc)
ASCII Serial Com Interface init method.
void ascii_serial_com_put_message_in_output_buffer(ascii_serial_com *asc, char ascVersion, char appVersion, char command, const char *data, size_t dataLen)
ASCII Serial Com Pack and put message in output buffer.
void ascii_serial_com_get_message_from_input_buffer(ascii_serial_com *asc, char *ascVersion, char *appVersion, char *command, char *data, size_t *dataLen)
ASCII Serial Com pop message from input buffer and unpack.
circular_buffer_uint8 * ascii_serial_com_get_input_buffer(ascii_serial_com *asc)
ASCII Serial Com get input buffer.
void circular_buffer_init_uint8(circular_buffer_uint8 *circ_buf, const size_t capacity, uint8_t *buffer)
circular buffer init method
bool circular_buffer_is_empty_uint8(const circular_buffer_uint8 *circ_buf)
circular buffer get if empty
uint8_t circular_buffer_io_fd_poll_do_poll(circular_buffer_io_fd_poll *cb_io, int timeout)
poll circular buffer IO with file descriptor polling object
void circular_buffer_io_fd_poll_init(circular_buffer_io_fd_poll *cb_io, circular_buffer_uint8 *in_buf, circular_buffer_uint8 *out_buf, int fd_in, int fd_out)
Initialize circular buffer IO with file descriptor polling object.
size_t circular_buffer_io_fd_poll_do_input(circular_buffer_io_fd_poll *cb_io)
circular buffer IO with file descriptor polling object: read from input fd
size_t circular_buffer_io_fd_poll_do_output(circular_buffer_io_fd_poll *cb_io)
circular buffer IO with file descriptor polling object: write to output fd
Circular buffer IO with file descriptor polling.
ASCII Serial Com Interface State struct.
Circular buffer IO with file descriptor polling struct.
circular buffer struct