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));
127 if (command[0] !=
'/')
129 SYSCALL(nlast = write(port,
"/", 1));
132 length = strnlen(command, sMaxSz);
133 SYSCALL(nlast = write(port, command, length));
137 PRINTF_ERROR(
"[ERROR] write did not write entire message: "
138 "could only write %d bytes of %d.", nlast, length);
142 if (length == 0 || command[length-1] !=
'\n')
144 SYSCALL(nlast = write(port,
"\n", 1));
159 SYSCALL(nlast = (
int) read(port, &c, 1));
168 if (destination != NULL)
170 destination[nread] = c;
176 PRINTF_ERROR(
"[ERROR] Read destination buffer not large "
177 "enough. Recommended size: 256B. Your size: %dB.",
187 PRINT_ERROR(
"[ERROR] Reply too short. It is likely that "
188 "only a partial reply was read.");
191 if (destination != NULL)
193 destination[nread] =
'\0';
222 PRINTF_ERROR(
"[ERROR] Invalid baud rate. Valid rates are "
223 "9600, 19200, 38400, 57600, and 115200 (default).\n"
224 "Your rate: %d.", baud);
228 SYSCALL(tcgetattr(port, &tio));
229 SYSCALL(cfsetospeed(&tio, tbaud) & cfsetispeed(&tio, tbaud));
230 SYSCALL(tcsetattr(port, TCSAFLUSH, &tio));
242 SYSCALL(tcgetattr(port, &tio));
243 old_timeout = tio.c_cc[VTIME];
245 SYSCALL(tcsetattr(port, TCSANOW, &tio));
248 SYSCALL(tcflush(port, TCIFLUSH));
249 while(read(port, &c, 1) > 0);
252 tio.c_cc[VTIME] = old_timeout;
253 SYSCALL(tcsetattr(port, TCSANOW, &tio));
264 const char delim,
size_t destination_length)
268 for(i = 0; source[i] != delim && source[i] !=
'\0'
269 && i < destination_length - 1; i++)
271 destination[i] = source[i];
274 destination[i] =
'\0';
289 if (strnlen(reply, sMaxSz) < 18)
291 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: shorter than expected. "
292 "It is likely that only a partial reply was read.\n"
293 "Reply value: %s", reply);
317 destination->
axis_number = (int) strtol(buffer, NULL, 10);
326 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: reply flags too "
327 "long. Maximum length: %zu. Your length: %zu. Reply flags "
328 "value: %s\n.",
sizeof(destination->
reply_flags), offset,
342 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: device status too "
343 "long. Expected length: %zu. Your length: %zu. Device status "
359 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: warning flags too "
360 "long. Expected length: %zu. Your length: %zu. Warning flags "
372 length = strnlen(reply, sMaxSz);
375 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: response data too "
376 "long. Maximum length: %zu. Your length: %zu. Data: %s.\n",
395 if (strnlen(reply, sMaxSz) < 13)
397 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: shorter than expected. "
398 "It is likely that only a partial reply was read.\n"
399 "Reply value: %s", reply);
423 destination->
axis_number = (int) strtol(buffer, NULL, 10);
435 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: device status too "
436 "long. Expected length: %zu. Your length: %zu. Device status "
452 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: warning flags too "
453 "long. Expected length: %zu. Your length: %zu. Warning flags "
475 if (strnlen(reply, sMaxSz) < 7)
477 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: shorter than expected. "
478 "It is likely that only a partial reply was read.\n"
479 "Reply value: %s", reply);
503 destination->
axis_number = (int) strtol(buffer, NULL, 10);
514 length = strnlen(reply,sMaxSz);
517 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: response data too "
518 "long. Maximum length: %zu. Your length: %zu. Data: %s.\n",
546 if (destination == NULL || reply == NULL)
548 PRINT_ERROR(
"[ERROR] decoding requires both a non-NULL destination "
549 "and reply to decode.");
553 if (strnlen(reply, sMaxSz) == 0)
555 PRINT_ERROR(
"[ERROR] Reply could not be decoded: no data.");
558 message_type = reply[0];
570 PRINTF_ERROR(
"[ERROR] Reply could not be decoded: unexpected "
571 "message type. Valid types are '@' (reply), '!' (alert), "
572 "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
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, size_t sMaxSz)
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, size_t sMaxSz)
int za_receive(z_port port, char *destination, int length)
int za_decode(struct za_reply *destination, const char *reply, size_t sMaxSz)
static int decode_alert(struct za_reply *destination, const char *reply, size_t sMaxSz)
int za_send(z_port port, const char *command, size_t sMaxSz)
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.