serial_source open_serial_source(const char *device, int baud_rate, int non_blocking, void (*message)(serial_source_msg problem)) /* Effects: opens serial port device at specified baud_rate. If non_blocking is true, read_serial_packet calls will be non-blocking (writes are always blocking, for now at least) Returns: descriptor for serial forwarder at host:port, or NULL for failure (bad device or bad baud rate) */ { struct termios newtio; int fd; tcflag_t baudflag = parse_baudrate(baud_rate); if (!baudflag) return NULL; fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd < 0) return NULL; #ifdef __CYGWIN__ /* For some very mysterious reason, this incantation is necessary to make the serial port work under some windows machines */ HANDLE handle = (HANDLE)get_osfhandle(fd); DCB dcb; if (!(GetCommState(handle, &dcb) && SetCommState(handle, &dcb))) { close(fd); return NULL; } #endif /* Serial port setting */ memset(&newtio, 0, sizeof(newtio)); newtio.c_cflag = CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR | IGNBRK; cfsetispeed(&newtio, baudflag); cfsetospeed(&newtio, baudflag); /* Raw output_file */ newtio.c_oflag = 0; if (tcflush(fd, TCIFLUSH) >= 0 && tcsetattr(fd, TCSANOW, &newtio) >= 0) { serial_source src = malloc(sizeof *src); if (src) { memset(src, 0, sizeof src); src->fd = fd; src->non_blocking = non_blocking; src->message = message; src->send.seqno = 37; return src; } } close(fd); return NULL; }
int parse_parameters(int argc, char **argv) { int opt, idx; int flags = 0; while ((opt = getopt_long(argc, argv, "a:b:d:eghr:w:uU?", longopts, &idx)) != -1) { switch (opt) { case 'a': i2c_adapter = atoi(optarg); break; case 'b': baudrate = parse_baudrate(optarg); break; case 'd': serial_port = optarg; break; case 'e': flags |= FLAG_ERASE; break; case 'g': flags |= FLAG_GO; break; case 'h': case '?': display_usage(argv[0]); break; case 'r': input_filename = optarg; break; case 'w': output_filename = optarg; break; case 'u': flags |= FLAG_UNPROTECT; break; case 'U': flags |= FLAG_READ_UNPROTECT; break; } } return flags; }
int main(int argc, char **argv) { int i; uint8_t *packet; char *prog_name; int len; int c, bail; input_src_t input_src; struct termios newtio; tcflag_t baudflag; int cnt; uint8_t *buf; serial_src = NULL; sf_src = 0; input_src = INPUT_RAW; bail = 0; prog_name = basename(argv[0]); while ((c = getopt_long(argc, argv, "Dvr", longopts, NULL)) != EOF) { switch (c) { case 1: bail = 1; input_src = INPUT_SF; break; case 2: bail = 1; input_src = INPUT_SERIAL; break; case 'D': debug++; break; case 'v': verbose++; break; case 'r': raw++; input_src = INPUT_RAW; break; default: usage(prog_name); } if (bail) break; } argc -= optind; argv += optind; if (argc != 2) { usage(prog_name); exit(2); } if (verbose) { fprintf(stderr, VERSION); switch (input_src) { case INPUT_SERIAL: fprintf(stderr, "opening: serial@%s:%d\n", argv[0], platform_baud_rate(argv[1])); break; case INPUT_SF: fprintf(stderr, "opening: sf@%s:%d\n", argv[0], atoi(argv[1])); break; case INPUT_RAW: fprintf(stderr, "opening: raw@%s:%d\n", argv[0], platform_baud_rate(argv[1])); break; } } if (input_src == INPUT_RAW) { baudflag = parse_baudrate(platform_baud_rate(argv[1])); if (!baudflag) { fprintf(stderr, "couldn't figure out the baud rate\n"); exit(2); } raw_fd = open(argv[0], O_RDWR | O_NOCTTY); if (raw_fd < 0) { fprintf(stderr, "*** Couldn't open serial port at %s:%s\n", argv[0], argv[1]); perror("error: "); exit(2); } /* Serial port setting */ memset(&newtio, 0, sizeof(newtio)); newtio.c_cflag = CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR | IGNBRK; cfsetispeed(&newtio, baudflag); cfsetospeed(&newtio, baudflag); /* Raw output_file */ newtio.c_oflag = 0; if (tcflush(raw_fd, TCIFLUSH) >= 0 && tcsetattr(raw_fd, TCSANOW, &newtio) >= 0) { buf = malloc(256); while(1) { cnt = read(raw_fd, buf, 1); if (cnt == 0) continue; fprintf(stderr, "%02x ", buf[0]); } } else close(raw_fd); exit(0); } switch(input_src) { case INPUT_SERIAL: serial_src = open_serial_source(argv[0], platform_baud_rate(argv[1]), 0, stderr_msg); if (!serial_src) { fprintf(stderr, "*** Couldn't open serial port at %s:%s\n", argv[0], argv[1]); perror("error: "); exit(1); } break; case INPUT_SF: sf_src = open_sf_source(argv[0], atoi(argv[1])); if (sf_src < 0) { fprintf(stderr, "*** Couldn't open serial forwarder at %s:%s\n", argv[0], argv[1]); perror("error: "); exit(1); } break; default: fprintf(stderr, "shouldn't be here\n"); exit(1); } for(;;) { switch(input_src) { case INPUT_SERIAL: packet = read_serial_packet(serial_src, &len); break; case INPUT_SF: packet = read_sf_packet(sf_src, &len); break; default: fprintf(stderr, "shouldn't be here\n"); exit(1); } if (!packet) { if (verbose) fprintf(stderr, "*** end of stream, terminating\n"); exit(0); } for (i = 0; i < len; i++) fprintf(stderr, "%02x ", packet[i]); fprintf(stderr, "\n"); free((void *)packet); } }
serial_source open_serial_source(const char *device, int baud_rate, int non_blocking, void (*message)(serial_source_msg problem)) /* Effects: opens serial port device at specified baud_rate. If non_blocking is true, read_serial_packet calls will be non-blocking (writes are always blocking, for now at least) Returns: descriptor for serial forwarder at host:port, or NULL for failure (bad device or bad baud rate) */ { #ifndef LOSE32 struct termios newtio; int fd; tcflag_t baudflag = parse_baudrate(baud_rate); if (!baudflag) return NULL; fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd < 0) return NULL; /* Serial port setting */ memset(&newtio, 0, sizeof(newtio)); newtio.c_cflag = CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR | IGNBRK; cfsetispeed(&newtio, baudflag); cfsetospeed(&newtio, baudflag); /* Raw output_file */ newtio.c_oflag = 0; if (tcflush(fd, TCIFLUSH) >= 0 && tcsetattr(fd, TCSANOW, &newtio) >= 0) { serial_source src = malloc(sizeof *src); if (src) { memset(src, 0, sizeof *src); src->fd = fd; src->non_blocking = non_blocking; src->message = message; src->send.seqno = 37; return src; } } close(fd); return NULL; #else // LOSE32 LPCTSTR ComName = (LPCTSTR)device; HANDLE hComm; DCB dcb; serial_source src; int buflen = MultiByteToWideChar(CP_ACP,0,(PCSTR)device,-1,(LPWSTR)ComName,0); MultiByteToWideChar(CP_ACP,0,(PCSTR)device,-1,(LPWSTR)ComName,buflen); //syncronize hComm = CreateFile(ComName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hComm == INVALID_HANDLE_VALUE) { return NULL; } PurgeComm(hComm, PURGE_RXCLEAR); GetCommState(hComm, &dcb); dcb.BaudRate = baud_rate; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.fParity = FALSE; dcb.StopBits = ONESTOPBIT; if (SetCommState(hComm, &dcb) == 0) { return NULL; } src = malloc(sizeof *src); if (src) { memset(src, 0, sizeof *src); src->hComm = hComm; src->non_blocking = non_blocking; src->message = message; src->send.seqno = 37; } return src; #endif // LOSE32 }