Tools for working with Cidco Mailstations

sendload: support sending through serial port

+82 -16
+82 -16
util/sendload.c
··· 6 6 * assumes Loader has been loaded on the Mailstation and is running 7 7 */ 8 8 9 + #include <err.h> 10 + #include <errno.h> 11 + #include <fcntl.h> 9 12 #include <stdio.h> 10 13 #include <stdlib.h> 11 14 #include <string.h> 12 15 #include <signal.h> 13 - #include <err.h> 14 - #include <errno.h> 16 + #include <termios.h> 15 17 #include <unistd.h> 18 + #include <sys/stat.h> 16 19 #include <sys/types.h> 17 - #include <sys/stat.h> 18 20 19 21 #include "tribble.h" 20 22 23 + static int serial_fd = -1; 24 + static int serial_speed = B115200; 25 + 21 26 void 22 27 usage(void) 23 28 { 24 - printf("usage: %s [-dr] [-p port address] <file to send>\n", 25 - getprogname()); 26 - exit(1); 29 + errx(1, "usage: %s [-dr] [-p lpt address | serial device] " 30 + "[-s serial speed] <file to send>", getprogname()); 31 + } 32 + 33 + int 34 + sendbyte_shim(char b) 35 + { 36 + if (serial_fd >= 0) 37 + return (write(serial_fd, &b, 1) != 1); 38 + else 39 + return sendbyte(b); 40 + } 41 + 42 + void 43 + setupserial(speed_t speed) 44 + { 45 + struct termios tty; 46 + 47 + if (tcgetattr(serial_fd, &tty) < 0) 48 + err(1, "tcgetattr"); 49 + 50 + cfsetospeed(&tty, speed); 51 + cfsetispeed(&tty, speed); 52 + 53 + tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */ 54 + tty.c_cflag &= ~CSIZE; 55 + tty.c_cflag |= CS8; /* 8-bit characters */ 56 + tty.c_cflag &= ~PARENB; /* no parity bit */ 57 + tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */ 58 + 59 + /* setup for non-canonical mode */ 60 + tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); 61 + tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 62 + tty.c_oflag &= ~OPOST; 63 + 64 + /* fetch bytes as they become available */ 65 + tty.c_cc[VMIN] = 1; 66 + tty.c_cc[VTIME] = 1; 67 + 68 + if (tcsetattr(serial_fd, TCSANOW, &tty) != 0) 69 + err(1, "tcsetattr"); 27 70 } 28 71 29 72 int ··· 33 76 struct stat sb; 34 77 unsigned int sent = 0, size = 0, raw = 0; 35 78 int ch; 36 - char *fn; 79 + char *fn, *serial_dev = NULL; 37 80 38 - while ((ch = getopt(argc, argv, "dp:r")) != -1) { 81 + while ((ch = getopt(argc, argv, "dp:rs:")) != -1) { 39 82 switch (ch) { 40 83 case 'd': 41 84 tribble_debug = 1; 42 85 break; 43 86 case 'p': 44 - tribble_port = (unsigned)strtol(optarg, NULL, 0); 45 - if (errno) 46 - err(1, "invalid port value"); 87 + if (optarg[0] == '/') { 88 + if ((serial_dev = strdup(optarg)) == NULL) 89 + err(1, "strdup"); 90 + serial_fd = open(serial_dev, 91 + O_RDWR | O_NOCTTY | O_SYNC); 92 + if (serial_fd < 0) 93 + err(1, "can't open %s", optarg); 94 + } else { 95 + tribble_port = (unsigned)strtol(optarg, NULL, 96 + 0); 97 + if (errno) 98 + err(1, "invalid port value"); 99 + } 47 100 break; 48 101 case 'r': 49 102 raw = 1; 103 + break; 104 + case 's': 105 + serial_speed = (unsigned)strtol(optarg, NULL, 0); 106 + if (errno) 107 + err(1, "invalid serial port speed value"); 50 108 break; 51 109 default: 52 110 usage(); ··· 58 116 if (argc != 1) 59 117 usage(); 60 118 61 - checkio(); 119 + if (serial_fd >= 0) 120 + setupserial(serial_speed); 121 + else 122 + checkio(); 62 123 63 124 fn = argv[0]; 64 125 pFile = fopen(fn, "rb"); ··· 71 132 /* we're never going to send huge files */ 72 133 size = (unsigned int)sb.st_size; 73 134 74 - printf("[port 0x%x] sending %s (%d bytes)...", tribble_port, fn, size); 135 + if (serial_fd >= 0) 136 + printf("[%s]", serial_dev); 137 + else 138 + printf("[lpt port 0x%x]", tribble_port); 139 + 140 + printf(" sending %s (%d bytes)...", fn, size); 75 141 fflush(stdout); 76 142 77 143 /* loader expects two bytes, the low and then high of the file size */ 78 144 if (!raw) { 79 - if (sendbyte(size & 0xff) != 0) 145 + if (sendbyte_shim(size & 0xff) != 0) 80 146 errx(1, "sendbyte failed"); 81 - if (sendbyte((size >> 8) & 0xff) != 0) 147 + if (sendbyte_shim((size >> 8) & 0xff) != 0) 82 148 errx(1, "sendbyte failed"); 83 149 } 84 150 85 151 while (sent < size) { 86 - if (sendbyte(fgetc(pFile)) != 0) 152 + if (sendbyte_shim(fgetc(pFile)) != 0) 87 153 errx(1, "sendbyte failed at %d/%d", sent, size); 88 154 89 155 if (sent++ == 0)