Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
ser_posix.c File Reference
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include "avrdude.h"
#include "libavrdude.h"
#include "ac_cfg.h"
+ Include dependency graph for ser_posix.c:

Go to the source code of this file.

Classes

struct  baud_mapping
 

Macros

#define MAX_ZERO_READS   512
 

Functions

static speed_t serial_baud_lookup (long baud)
 
static int ser_setspeed (union filedescriptor *fd, long baud)
 
ssize_t read_timeout (int fd, void *buf, size_t count, long timeout)
 
ssize_t write_timeout (int fd, const void *buf, size_t count, long timeout)
 
static int net_open (const char *port, union filedescriptor *fdp)
 
static int ser_set_dtr_rts (union filedescriptor *fdp, int is_on)
 
static int ser_open (char *port, union pinfo pinfo, union filedescriptor *fdp)
 
static void ser_close (union filedescriptor *fd)
 
static int ser_send (union filedescriptor *fd, const unsigned char *buf, size_t buflen)
 
static int ser_recv (union filedescriptor *fd, unsigned char *buf, size_t buflen)
 
static int ser_drain (union filedescriptor *fd, int display)
 

Variables

long serial_recv_timeout = 4000
 
static struct baud_mapping baud_lookup_table []
 
static struct termios original_termios
 
static int saved_original_termios
 
struct serial_device serial_serdev
 
struct serial_deviceserdev = &serial_serdev
 

Class Documentation

◆ baud_mapping

struct baud_mapping
Class Members
long baud
speed_t speed

Macro Definition Documentation

◆ MAX_ZERO_READS

#define MAX_ZERO_READS   512

Function Documentation

◆ net_open()

static int net_open ( const char *  port,
union filedescriptor fdp 
)
static
224{
225#ifdef HAVE_GETADDRINFO
226 char *hp, *hstr, *pstr;
227 int s, fd, ret = -1;
228 struct addrinfo hints;
229 struct addrinfo *result, *rp;
230
231 if ((hstr = hp = strdup(port)) == NULL) {
232 avrdude_message(MSG_INFO, "%s: net_open(): Out of memory!\n",
233 progname);
234 return -1;
235 }
236
237 /*
238 * As numeric IPv6 addresses use colons as separators, we need to
239 * look for the last colon here, which separates the port number or
240 * service name from the host or IP address.
241 */
242 if (((pstr = strrchr(hstr, ':')) == NULL) || (pstr == hstr)) {
243 avrdude_message(MSG_INFO, "%s: net_open(): Mangled host:port string \"%s\"\n",
244 progname, hstr);
245 goto error;
246 }
247
248 /*
249 * Remove brackets from the host part, if present.
250 */
251 if (*hstr == '[' && *(pstr-1) == ']') {
252 hstr++;
253 *(pstr-1) = '\0';
254 }
255
256 /*
257 * Terminate the host section of the description.
258 */
259 *pstr++ = '\0';
260
261 memset(&hints, 0, sizeof(hints));
262 hints.ai_family = AF_UNSPEC;
263 hints.ai_socktype = SOCK_STREAM;
264 s = getaddrinfo(hstr, pstr, &hints, &result);
265
266 if (s != 0) {
268 "%s: net_open(): Cannot resolve "
269 "host=\"%s\", port=\"%s\": %s\n",
270 progname, hstr, pstr, gai_strerror(s));
271 goto error;
272 }
273 for (rp = result; rp != NULL; rp = rp->ai_next) {
274 fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
275 if (fd == -1) {
276 /* This one failed, loop over */
277 continue;
278 }
279 if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1) {
280 /* Success, we are connected */
281 break;
282 }
283 close(fd);
284 }
285 if (rp == NULL) {
286 avrdude_message(MSG_INFO, "%s: net_open(): Cannot connect: %s\n",
287 progname, strerror(errno));
288 }
289 else {
290 fdp->ifd = fd;
291 ret = 0;
292 }
293 freeaddrinfo(result);
294
295error:
296 free(hp);
297 return ret;
298#else
300 "%s: Networking is not supported on your platform.\n"
301 "If you need it, please open a bug report.\n", progname);
302 return -1;
303#endif /* HAVE_GETADDRINFO */
304}
#define MSG_INFO
Definition avrdude.h:51
char * progname
Definition main.c:61
int avrdude_message(const int msglvl, const char *format,...)
Definition main.c:93
void free(void *)
int ifd
Definition libavrdude.h:522
static char error[256]
Definition tga.cpp:50

References avrdude_message(), error, free(), filedescriptor::ifd, MSG_INFO, and progname.

Referenced by ser_open().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ read_timeout()

ssize_t read_timeout ( int  fd,
void buf,
size_t  count,
long  timeout 
)
158{
159 struct timeval tm, tm2;
160 fd_set rfds;
161 int nfds;
162
163 tm.tv_sec = timeout / 1000L;
164 tm.tv_usec = (timeout % 1000L) * 1000;
165
166 while (1) {
167 FD_ZERO(&rfds);
168 FD_SET(fd, &rfds);
169 tm2 = tm;
170 nfds = select(fd + 1, &rfds, NULL, NULL, &tm2);
171
172 if (nfds == 0) {
173 return -2;
174 } else if (nfds == -1) {
175 if (errno == EINTR || errno == EAGAIN) {
176 continue;
177 } else {
178 return -1;
179 }
180 } else {
181 return read(fd, buf, count);
182 }
183 }
184}

Referenced by ser_drain(), and ser_recv().

+ Here is the caller graph for this function:

◆ ser_close()

static void ser_close ( union filedescriptor fd)
static
376{
377 /*
378 * restore original termios settings from ser_open
379 */
381 int rc = tcsetattr(fd->ifd, TCSANOW | TCSADRAIN, &original_termios);
382 if (rc) {
383 avrdude_message(MSG_INFO, "%s: ser_close(): can't reset attributes for device: %s\n",
384 progname, strerror(errno));
385 }
387 }
388
389 close(fd->ifd);
390}
static struct termios original_termios
Definition ser_posix.c:76
static int saved_original_termios
Definition ser_posix.c:77

References avrdude_message(), filedescriptor::ifd, MSG_INFO, original_termios, progname, and saved_original_termios.

+ Here is the call graph for this function:

◆ ser_drain()

static int ser_drain ( union filedescriptor fd,
int  display 
)
static
510{
511 int rc;
512 unsigned char buf;
513 unsigned zero_reads = 0;
514
515 if (display) {
516 avrdude_message(MSG_INFO, "drain>");
517 }
518
519 while (1) {
521
522 rc = read_timeout(fd->ifd, &buf, 1, 250); // Note: timeout needs to be kept low to not timeout in programmers
523 if (rc == -2) {
524 if (display) {
525 avrdude_message(MSG_INFO, "<drain\n");
526 }
527
528 break;
529 } else if (rc == -1) {
530 avrdude_message(MSG_INFO, "%s: ser_drain(): read error: %s\n", progname, strerror(errno));
531 return -1;
532 } else if (rc == 0) {
533 zero_reads++;
534 if (zero_reads > MAX_ZERO_READS) {
535 avrdude_message(MSG_NOTICE2, "%s: ser_drain(): programmer is not responding (too many zero reads)\n",
536 progname);
537 return -1;
538 }
539 } else {
540 zero_reads = 0;
541 }
542 if (display) {
543 avrdude_message(MSG_INFO, "%02x ", buf);
544 }
545 }
546
547 return 0;
548}
#define MSG_NOTICE2
Definition avrdude.h:53
#define RETURN_IF_CANCEL()
Definition libavrdude.h:733
#define MAX_ZERO_READS
Definition ser_posix.c:48
ssize_t read_timeout(int fd, void *buf, size_t count, long timeout)
Definition ser_posix.c:157

References avrdude_message(), filedescriptor::ifd, MAX_ZERO_READS, MSG_INFO, MSG_NOTICE2, progname, read_timeout(), and RETURN_IF_CANCEL.

+ Here is the call graph for this function:

◆ ser_open()

static int ser_open ( char *  port,
union pinfo  pinfo,
union filedescriptor fdp 
)
static
337{
338 int rc;
339 int fd;
340
341 /*
342 * If the port is of the form "net:<host>:<port>", then
343 * handle it as a TCP connection to a terminal server.
344 */
345 if (strncmp(port, "net:", strlen("net:")) == 0) {
346 return net_open(port + strlen("net:"), fdp);
347 }
348
349 /*
350 * open the serial port
351 */
352 fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
353 if (fd < 0) {
354 avrdude_message(MSG_INFO, "%s: ser_open(): can't open device \"%s\": %s\n",
355 progname, port, strerror(errno));
356 return -1;
357 }
358
359 fdp->ifd = fd;
360
361 /*
362 * set serial line attributes
363 */
364 rc = ser_setspeed(fdp, pinfo.baud);
365 if (rc) {
366 avrdude_message(MSG_INFO, "%s: ser_open(): can't set attributes for device \"%s\": %s\n",
367 progname, port, strerror(-rc));
368 close(fd);
369 return -1;
370 }
371 return 0;
372}
long baud
Definition libavrdude.h:537
Definition libavrdude.h:536
static int ser_setspeed(union filedescriptor *fd, long baud)
Definition ser_posix.c:99
static int net_open(const char *port, union filedescriptor *fdp)
Definition ser_posix.c:223

References avrdude_message(), pinfo::baud, filedescriptor::ifd, MSG_INFO, net_open(), progname, and ser_setspeed().

+ Here is the call graph for this function:

◆ ser_recv()

static int ser_recv ( union filedescriptor fd,
unsigned char *  buf,
size_t  buflen 
)
static
452{
453 int rc;
454 unsigned char * p = buf;
455 size_t len = 0;
456 unsigned zero_reads = 0;
457
458 while (len < buflen) {
460
461 rc = read_timeout(fd->ifd, p, (buflen - len > 1024) ? 1024 : buflen - len, serial_recv_timeout);
462
463 if (rc == -2) {
464 avrdude_message(MSG_NOTICE2, "%s: ser_recv(): programmer is not responding\n", progname);
465 return -1;
466 } else if (rc == -1) {
467 avrdude_message(MSG_INFO, "%s: ser_recv(): read error: %s\n", progname, strerror(errno));
468 return -1;
469 } else if (rc == 0) {
470 zero_reads++;
471 if (zero_reads > MAX_ZERO_READS) {
472 avrdude_message(MSG_NOTICE2, "%s: ser_recv(): programmer is not responding (too many zero reads)\n",
473 progname);
474 return -1;
475 }
476 } else {
477 zero_reads = 0;
478 p += rc;
479 len += rc;
480 }
481 }
482
483 p = buf;
484
485 if (verbose > 3)
486 {
487 avrdude_message(MSG_TRACE, "%s: Recv: ", progname);
488
489 while (len) {
490 unsigned char c = *p;
491 if (isprint(c)) {
492 avrdude_message(MSG_TRACE, "%c ", c);
493 }
494 else {
496 }
497 avrdude_message(MSG_TRACE, "[%02x] ", c);
498
499 p++;
500 len--;
501 }
503 }
504
505 return 0;
506}
int verbose
Definition main.c:198
#define MSG_TRACE
Definition avrdude.h:55
long serial_recv_timeout
Definition ser_posix.c:47

References avrdude_message(), filedescriptor::ifd, MAX_ZERO_READS, MSG_INFO, MSG_NOTICE2, MSG_TRACE, progname, read_timeout(), RETURN_IF_CANCEL, serial_recv_timeout, and verbose.

+ Here is the call graph for this function:

◆ ser_send()

static int ser_send ( union filedescriptor fd,
const unsigned char *  buf,
size_t  buflen 
)
static
394{
395 int rc;
396 const unsigned char * p = buf;
397 size_t len = buflen;
398 unsigned zero_writes = 0;
399
400 if (!len)
401 return 0;
402
403 if (verbose > 3)
404 {
405 avrdude_message(MSG_TRACE, "%s: Send: ", progname);
406
407 while (buflen) {
408 unsigned char c = *buf;
409 if (isprint(c)) {
410 avrdude_message(MSG_TRACE, "%c ", c);
411 }
412 else {
414 }
415 avrdude_message(MSG_TRACE, "[%02x] ", c);
416
417 buf++;
418 buflen--;
419 }
420
422 }
423
424 while (len) {
426 rc = write_timeout(fd->ifd, p, (len > 1024) ? 1024 : len, serial_recv_timeout);
427 if (rc == -2) {
428 avrdude_message(MSG_NOTICE2, "%s: ser_send(): programmer is not responding\n", progname);
429 return -1;
430 } else if (rc == -1) {
431 avrdude_message(MSG_INFO, "%s: ser_send(): write error: %s\n", progname, strerror(errno));
432 return -1;
433 } else if (rc == 0) {
434 zero_writes++;
435 if (zero_writes > MAX_ZERO_READS) {
436 avrdude_message(MSG_NOTICE2, "%s: ser_send(): programmer is not responding (too many zero writes)\n",
437 progname);
438 return -1;
439 }
440 } else {
441 zero_writes = 0;
442 p += rc;
443 len -= rc;
444 }
445 }
446
447 return 0;
448}
ssize_t write_timeout(int fd, const void *buf, size_t count, long timeout)
Definition ser_posix.c:186

References avrdude_message(), filedescriptor::ifd, MAX_ZERO_READS, MSG_INFO, MSG_NOTICE2, MSG_TRACE, progname, RETURN_IF_CANCEL, serial_recv_timeout, verbose, and write_timeout().

+ Here is the call graph for this function:

◆ ser_set_dtr_rts()

static int ser_set_dtr_rts ( union filedescriptor fdp,
int  is_on 
)
static
308{
309 unsigned int ctl;
310 int r;
311
312 r = ioctl(fdp->ifd, TIOCMGET, &ctl);
313 if (r < 0) {
314 perror("ioctl(\"TIOCMGET\")");
315 return -1;
316 }
317
318 if (is_on) {
319 /* Set DTR and RTS */
320 ctl |= (TIOCM_DTR | TIOCM_RTS);
321 }
322 else {
323 /* Clear DTR and RTS */
324 ctl &= ~(TIOCM_DTR | TIOCM_RTS);
325 }
326
327 r = ioctl(fdp->ifd, TIOCMSET, &ctl);
328 if (r < 0) {
329 perror("ioctl(\"TIOCMSET\")");
330 return -1;
331 }
332
333 return 0;
334}

References filedescriptor::ifd.

◆ ser_setspeed()

static int ser_setspeed ( union filedescriptor fd,
long  baud 
)
static
100{
101 int rc;
102 struct termios termios;
103 speed_t speed = serial_baud_lookup (baud);
104
105 if (!isatty(fd->ifd))
106 return -ENOTTY;
107
108 /*
109 * initialize terminal modes
110 */
111 rc = tcgetattr(fd->ifd, &termios);
112 if (rc < 0) {
113 avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcgetattr() failed\n",
114 progname);
115 return -errno;
116 }
117
118 /*
119 * copy termios for ser_close if we haven't already
120 */
121 if (! saved_original_termios++) {
122 original_termios = termios;
123 }
124
125 termios.c_iflag = IGNBRK;
126 termios.c_oflag = 0;
127 termios.c_lflag = 0;
128 termios.c_cflag = (CS8 | CREAD | CLOCAL);
129 termios.c_cc[VMIN] = 1;
130 termios.c_cc[VTIME] = 0;
131
132 cfsetospeed(&termios, speed);
133 cfsetispeed(&termios, speed);
134
135 rc = tcsetattr(fd->ifd, TCSANOW, &termios);
136 if (rc < 0) {
137 avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcsetattr() failed\n",
138 progname);
139 return -errno;
140 }
141
142 /*
143 * Everything is now set up for a local line without modem control
144 * or flow control, so clear O_NONBLOCK again.
145 */
146 rc = fcntl(fd->ifd, F_GETFL, 0);
147 if (rc != -1)
148 fcntl(fd->ifd, F_SETFL, rc & ~O_NONBLOCK);
149
150 return 0;
151}
static speed_t serial_baud_lookup(long baud)
Definition ser_posix.c:79
#define isatty
Definition unistd.h:46

References avrdude_message(), filedescriptor::ifd, isatty, MSG_INFO, original_termios, progname, saved_original_termios, and serial_baud_lookup().

Referenced by ser_open().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ serial_baud_lookup()

static speed_t serial_baud_lookup ( long  baud)
static
80{
81 struct baud_mapping *map = baud_lookup_table;
82
83 while (map->baud) {
84 if (map->baud == baud)
85 return map->speed;
86 map++;
87 }
88
89 /*
90 * If a non-standard BAUD rate is used, issue
91 * a warning (if we are verbose) and return the raw rate
92 */
93 avrdude_message(MSG_NOTICE, "%s: serial_baud_lookup(): Using non-standard baud rate: %ld\n",
94 progname, baud);
95
96 return baud;
97}
#define MSG_NOTICE
Definition avrdude.h:52
speed_t speed
Definition ser_posix.c:52
static struct baud_mapping baud_lookup_table[]
Definition ser_posix.c:57
long baud
Definition ser_posix.c:51
Definition ser_posix.c:50

References avrdude_message(), baud_mapping::baud, baud_lookup_table, MSG_NOTICE, progname, and baud_mapping::speed.

Referenced by ser_setspeed().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ write_timeout()

ssize_t write_timeout ( int  fd,
const void buf,
size_t  count,
long  timeout 
)
187{
188 struct timeval tm, tm2;
189 fd_set wfds;
190 int nfds;
191
192 tm.tv_sec = timeout / 1000L;
193 tm.tv_usec = (timeout % 1000L) * 1000;
194
195 while (1) {
196 FD_ZERO(&wfds);
197 FD_SET(fd, &wfds);
198 tm2 = tm;
199 nfds = select(fd + 1, NULL, &wfds, NULL, &tm2);
200
201 if (nfds == 0) {
202 return -2;
203 } else if (nfds == -1) {
204 if (errno == EINTR || errno == EAGAIN) {
205 continue;
206 } else {
207 return -1;
208 }
209 } else {
210 return write(fd, buf, count);
211 }
212 }
213}

Referenced by ser_send().

+ Here is the caller graph for this function:

Variable Documentation

◆ baud_lookup_table

struct baud_mapping baud_lookup_table[]
static
Initial value:
= {
{ 1200, B1200 },
{ 2400, B2400 },
{ 4800, B4800 },
{ 9600, B9600 },
{ 19200, B19200 },
{ 38400, B38400 },
{ 0, 0 }
}

Referenced by serial_baud_lookup().

◆ original_termios

struct termios original_termios
static

Referenced by ser_close(), and ser_setspeed().

◆ saved_original_termios

int saved_original_termios
static

Referenced by ser_close(), and ser_setspeed().

◆ serdev

◆ serial_recv_timeout

◆ serial_serdev

struct serial_device serial_serdev
Initial value:
=
{
.open = ser_open,
.setspeed = ser_setspeed,
.close = ser_close,
.send = ser_send,
.recv = ser_recv,
.drain = ser_drain,
.set_dtr_rts = ser_set_dtr_rts,
}
#define SERDEV_FL_CANSETSPEED
Definition libavrdude.h:564
static int ser_open(char *port, union pinfo pinfo, union filedescriptor *fdp)
Definition ser_posix.c:336
static int ser_set_dtr_rts(union filedescriptor *fdp, int is_on)
Definition ser_posix.c:307
static int ser_drain(union filedescriptor *fd, int display)
Definition ser_posix.c:509
static void ser_close(union filedescriptor *fd)
Definition ser_posix.c:375
static int ser_send(union filedescriptor *fd, const unsigned char *buf, size_t buflen)
Definition ser_posix.c:393
static int ser_recv(union filedescriptor *fd, unsigned char *buf, size_t buflen)
Definition ser_posix.c:451