26 #include <sys/types.h>
31 #define PRINT_ERROR(M)
32 #define PRINTF_ERROR(M, ...)
33 #define PRINT_SYSCALL_ERROR(M)
35 #define PRINT_ERROR(M) do { if (za_verbose) { fprintf(stderr, "(%s: %d) " M\
36 "\n", __FILE__, __LINE__); } } while(0)
37 #define PRINTF_ERROR(M, ...) do { if (za_verbose) { fprintf(stderr,\
38 "(%s: %d) " M "\n", __FILE__, __LINE__, __VA_ARGS__); } } while(0)
40 #define PRINT_SYSCALL_ERROR(M) do { if (za_verbose) {\
41 fprintf(stderr, "(%s: %d) [ERROR] " M " failed: %s.\n",\
42 __FILE__, __LINE__, strerror(errno)); } } while(0)
50 #define SYSCALL(F) do { if ((F) < 0) { PRINT_SYSCALL_ERROR(#F);\
51 return Z_ERROR_SYSTEM_ERROR; } } while(0)
55 struct termios tio, orig_tio;
57 if (port == NULL || port_name == NULL)
59 PRINT_ERROR(
"[ERROR] port and port_name cannot be NULL.");
64 SYSCALL(*port = open(port_name, O_RDWR | O_NOCTTY));
65 SYSCALL(tcgetattr(*port, &orig_tio));
66 memcpy(&tio, &orig_tio,
sizeof(
struct termios));
69 tio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR
70 | IGNCR | ICRNL | IXON);
71 tio.c_oflag &= ~OPOST;
72 tio.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
73 tio.c_cflag &= ~(CSIZE | PARENB);
75 tio.c_cflag = CS8|CREAD|CLOCAL;
88 SYSCALL(cfsetospeed(&tio, B115200) & cfsetispeed(&tio, B115200));
90 while(memcmp(&orig_tio, &tio,
sizeof(
struct termios)) != 0)
92 SYSCALL(tcsetattr(*port, TCSAFLUSH, &tio));
93 SYSCALL(tcgetattr(*port, &orig_tio));
124 if (command[0] !=
'/')
126 SYSCALL(nlast = write(port,
"/", 1));
129 length = strlen(command);
130 SYSCALL(nlast = write(port, command, length));
134 PRINTF_ERROR(
"[ERROR] write did not write entire message: "
135 "could only write %d bytes of %d.", nlast, length);
139 if (length == 0 || command[length-1] !=
'\n')
141 SYSCALL(nlast = write(port,
"\n", 1));
156 SYSCALL(nlast = (
int) read(port, &c, 1));
165 if (destination != NULL)
167 destination[nread] = c;
173 PRINTF_ERROR(
"[ERROR] Read destination buffer not large "
174 "enough. Recommended size: 256B. Your size: %dB.",
184 PRINT_ERROR(
"[ERROR] Reply too short. It is likely that "
185 "only a partial reply was read.");
188 if (destination != NULL)
190 destination[nread] =
'\0';
219 PRINTF_ERROR(
"[ERROR] Invalid baud rate. Valid rates are "
220 "9600, 19200, 38400, 57600, and 115200 (default).\n"
221 "Your rate: %d.", baud);
225 SYSCALL(tcgetattr(port, &tio));
226 SYSCALL(cfsetospeed(&tio, tbaud) & cfsetispeed(&tio, tbaud));
227 SYSCALL(tcsetattr(port, TCSAFLUSH, &tio));
239 SYSCALL(tcgetattr(port, &tio));
240 old_timeout = tio.c_cc[VTIME];
242 SYSCALL(tcsetattr(port, TCSANOW, &tio));
245 SYSCALL(tcflush(port, TCIFLUSH));
246 while(read(port, &c, 1) > 0);
249 tio.c_cc[VTIME] = old_timeout;
250 SYSCALL(tcsetattr(port, TCSANOW, &tio));
261 const char delim,
size_t destination_length)
265 for(i = 0; source[i] != delim && source[i] !=
'\0'
266 && i < destination_length - 1; i++)
268 destination[i] = source[i];
271 destination[i] =
'\0';
283 if (strlen(reply) < 18)
285 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: shorter than expected. "
286 "It is likely that only a partial reply was read.\n"
287 "Reply value: %s", reply);
311 destination->
axis_number = (int) strtol(buffer, NULL, 10);
320 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: reply flags too "
321 "long. Maximum length: %zu. Your length: %zu. Reply flags "
322 "value: %s\n.",
sizeof(destination->
reply_flags), offset,
336 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: device status too "
337 "long. Expected length: %zu. Your length: %zu. Device status "
353 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: warning flags too "
354 "long. Expected length: %zu. Your length: %zu. Warning flags "
366 length = strlen(reply);
369 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: response data too "
370 "long. Maximum length: %zu. Your length: %zu. Data: %s.\n",
386 if (strlen(reply) < 13)
388 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: shorter than expected. "
389 "It is likely that only a partial reply was read.\n"
390 "Reply value: %s", reply);
414 destination->
axis_number = (int) strtol(buffer, NULL, 10);
426 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: device status too "
427 "long. Expected length: %zu. Your length: %zu. Device status "
443 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: warning flags too "
444 "long. Expected length: %zu. Your length: %zu. Warning flags "
463 if (strlen(reply) < 7)
465 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: shorter than expected. "
466 "It is likely that only a partial reply was read.\n"
467 "Reply value: %s", reply);
491 destination->
axis_number = (int) strtol(buffer, NULL, 10);
502 length = strlen(reply);
505 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: response data too "
506 "long. Maximum length: %zu. Your length: %zu. Data: %s.\n",
531 if (destination == NULL || reply == NULL)
533 PRINT_ERROR(
"[ERROR] decoding requires both a non-NULL destination "
534 "and reply to decode.");
538 if (strlen(reply) == 0)
540 PRINT_ERROR(
"[ERROR] Reply could not be decoded: no data.");
543 message_type = reply[0];
555 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: unexpected "
556 "message type. Valid types are '@' (reply), '!' (alert), "
557 "and '#' (info). Your type: '%c'. \n", message_type);
GeneratorWrapper< T > value(T &&value)
@ Z_ERROR_COULD_NOT_DECODE
@ Z_ERROR_INVALID_BAUDRATE
@ Z_ERROR_BUFFER_TOO_SMALL
int za_decode(struct za_reply *destination, const char *reply)
static size_t copy_until_delim(char *destination, const char *source, const char delim, size_t destination_length)
static int decode_reply(struct za_reply *destination, const char *reply)
static int decode_alert(struct za_reply *destination, const char *reply)
int za_connect(z_port *port, const char *port_name)
int za_setbaud(z_port port, int baud)
void za_set_verbose(int value)
static int decode_info(struct za_reply *destination, const char *reply)
int za_receive(z_port port, char *destination, int length)
int za_send(z_port port, const char *command)
int za_drain(z_port port)
#define PRINTF_ERROR(M,...)
int za_disconnect(z_port port)
Provides a set of functions for interacting with Zaber devices in the ASCII protocol.