AmendHub

Download:

jcs

/

subtext

/

amendments

/

89

serial: Bugfixes, hook up to session and now we're taking calls!


jcs made amendment 89 over 2 years ago
--- serial.c Thu Mar 17 15:29:37 2022 +++ serial.c Tue Mar 29 16:32:16 2022 @@ -38,23 +38,23 @@ static bool serial_initialized = false; static short serial_out_refnum = 0, serial_in_refnum = 0; -static char serial_input_buf[512]; -static char serial_input_line_buf[128]; -static size_t serial_input_line_buf_len = 0; +static char serial_input_internal_buf[1024]; +static char serial_input_buf[128]; +static size_t serial_input_buf_len = 0; struct serial_node { - short id; - short state; + bool connected; unsigned short obuflen; unsigned char obuf[512]; unsigned char ibuf[64]; unsigned short ibuflen; struct session *session; -}; +} the_serial_node; void serial_reset(void); +void serial_flush(void); void serial_printf(const char *format, ...); -char * serial_get_line(void); +char * serial_get_line(bool wait); short serial_input(struct session *session); short serial_output(struct session *session); void serial_close(struct session *session); @@ -96,8 +96,8 @@ serial_init(void) baud19200 + data8 + noParity + stop10)) != 0) panic("SerReset(in) failed: %d", error); - SerSetBuf(serial_in_refnum, (Ptr)&serial_input_buf, - sizeof(serial_input_buf)); + SerSetBuf(serial_in_refnum, (Ptr)&serial_input_internal_buf, + sizeof(serial_input_internal_buf)); flags.fXOn = true; flags.fInX = true; @@ -119,31 +119,62 @@ serial_reset(void) /* reset */ serial_hangup(); - serial_printf("ATZ\r\n"); - Delay(60L, &m); - while (serial_get_line() != NULL) - ; - + serial_printf("ATZ\r"); + Delay(TICKS_PER_SEC * 2, &m); + serial_flush(); + /* disable echo */ - serial_printf("ATE0\r\n"); - while (serial_get_line() != NULL) - ; + serial_printf("ATE0\r"); + resp = serial_get_line(true); + if (resp[0] == 'A' && resp[1] == 'T' && resp[2] == 'E') + /* eat echo */ + resp = serial_get_line(true); + if (resp[0] != 'O' || resp[1] != 'K') + warn("bad response to ATE0: \"%s\"", resp); /* initialize */ - serial_printf("%s\r\n", db->config.modem_init); - resp = serial_get_line(); - if (resp[0] != 'O' || resp[1] != 'K') - warn("bad response to modem init: \"%s\"", resp); + serial_printf("%s\r", db->config.modem_init); + Delay(TICKS_PER_SEC, &m); + serial_flush(); + + the_serial_node.connected = false; + the_serial_node.obuflen = 0; + the_serial_node.ibuflen = 0; + + serial_input_buf_len = 0; } void serial_hangup(void) { + long m; + /* de-assert DTR */ Control(serial_out_refnum, 18, NULL); + Delay(TICKS_PER_SEC * 1, &m); + /* assert DTR */ + Control(serial_out_refnum, 17, NULL); } void +serial_flush(void) +{ + long len; + + for (;;) { + SerGetBuf(serial_in_refnum, &len); + if (!len) + break; + if (len > sizeof(serial_input_buf)) + len = sizeof(serial_input_buf); + FSRead(serial_in_refnum, &len, &serial_input_buf); + } + + memset(serial_input_buf, 0, sizeof(serial_input_buf)); + serial_input_buf_len = 0; +} + +void serial_printf(const char *format, ...) { static char serial_printf_tbuf[256]; @@ -170,64 +201,72 @@ serial_printf(const char *format, ...) } char * -serial_get_line(void) +serial_get_line(bool wait) { - static char serial_input_cur_line_buf[sizeof(serial_input_line_buf)]; + static char serial_cur_line[sizeof(serial_input_buf)]; size_t n; long len, rem; - + +maybe_read: /* append as much new data as we can fit */ - if (serial_input_line_buf_len < sizeof(serial_input_line_buf)) { + if (serial_input_buf_len < sizeof(serial_input_buf)) { SerGetBuf(serial_in_refnum, &len); if (len) { - n = sizeof(serial_input_line_buf) - serial_input_line_buf_len; - if (len > n) - len = n; + len = MIN(len, + sizeof(serial_input_buf) - serial_input_buf_len); FSRead(serial_in_refnum, &len, - &serial_input_line_buf + serial_input_line_buf_len); - serial_input_line_buf_len += len; + serial_input_buf + serial_input_buf_len); + serial_input_buf[serial_input_buf_len + len] = '\0'; + progress("%s", serial_input_buf + serial_input_buf_len); + serial_input_buf_len += len; } } find_line: - for (n = 0; n < serial_input_line_buf_len; n++) { - if (serial_input_line_buf[n] == '\r' || - serial_input_line_buf[n] == '\n') { + for (n = 0; n < serial_input_buf_len; n++) { + if (serial_input_buf[n] == '\r' || + serial_input_buf[n] == '\n') { if (n > 0) - memcpy(serial_input_cur_line_buf, - serial_input_line_buf, n); - serial_input_cur_line_buf[n] = '\0'; + memcpy(serial_cur_line, serial_input_buf, n); + serial_cur_line[n] = '\0'; /* eat any trailing newlines */ - while (n + 1 < serial_input_line_buf_len && - (serial_input_line_buf[n + 1] == '\r' || - serial_input_line_buf[n + 1] == '\n')) + while (n + 1 < serial_input_buf_len && + (serial_input_buf[n + 1] == '\r' || + serial_input_buf[n + 1] == '\n')) n++; /* shift remaining data down */ - rem = serial_input_line_buf_len - n - 1; + rem = serial_input_buf_len - n - 1; if (rem > 0) - memmove(serial_input_line_buf, - serial_input_line_buf + n + 1, rem); + memmove(serial_input_buf, serial_input_buf + n + 1, rem); else if (rem < 0) panic("bogus serial input remaining %ld", rem); - serial_input_line_buf_len = rem; + serial_input_buf_len = rem; /* skip blank lines */ - if (serial_input_cur_line_buf[0] == '\0') + if (serial_cur_line[0] == '\0') goto find_line; - return (char *)&serial_input_cur_line_buf; + return (char *)&serial_cur_line; } } + if (wait) { + if (serial_input_buf_len >= sizeof(serial_input_buf)) + panic("serial_get_line with wait but input buffer full"); + goto maybe_read; + } + return NULL; } void serial_atexit(void) { - SerSetBuf(serial_in_refnum, (Ptr)&serial_input_buf, 0); + serial_hangup(); + + SerSetBuf(serial_in_refnum, (Ptr)&serial_input_internal_buf, 0); if (serial_in_refnum) CloseDriver(serial_in_refnum); if (serial_out_refnum) @@ -239,7 +278,7 @@ serial_idle(void) { SerStaRec status; long count, i; - char inbuf[64]; + char *line; SerStatus(serial_in_refnum, &status); if (status.ctsHold != 0) @@ -247,35 +286,89 @@ serial_idle(void) if (status.xOffHold != 0) warn("xoff set"); if (status.cumErrs != 0) - warn("break!"); + ;//warn("break!"); + + if (the_serial_node.connected) + return; + + if ((line = serial_get_line(false)) == NULL) + return; + + if (strstr(line, "CONNECT ") != NULL) { + char tty[7]; + long baud; /* optimistic :) */ + short count, ret; - SerGetBuf(serial_in_refnum, &count); - if (count > 0) { - if (count > sizeof(inbuf)) - count = sizeof(inbuf); - FSRead(serial_in_refnum, &count, &inbuf); - for (i = 0; i < count; i++) { - if (inbuf[i] == '\0' || inbuf[i] == '\r') - inbuf[i] = ' '; + sprintf(tty, "ttym%d", (db->config.modem_port == 2 ? 1 : 0)); + the_serial_node.connected = true; + the_serial_node.session = session_create(tty, "modem", + &serial_node_funcs); + the_serial_node.session->cookie = (void *)&the_serial_node; + /* TODO: pass caller id */ + + if (sscanf(line, "CONNECT %ld/%n", baud, &count) == 1 && + count > 0) { + console->session->vt100 = 1; + console->session->tspeed = baud; } - inbuf[count] = '\0'; - warn("read from serial: %s", inbuf); } } short serial_input(struct session *session) { - return 0; + struct serial_node *node = (struct serial_node *)session->cookie; + unsigned short rlen; + long len; + short error, n; + unsigned char c; + + if (session->ending) + return 0; + + if (serial_input_buf_len) { + /* drain input buf first */ + n = MIN(serial_input_buf_len, + sizeof(session->ibuf) - session->ibuflen); + memcpy(session->ibuf + session->ibuflen, serial_input_buf, n); + session->ibuflen += n; + if (serial_input_buf_len - n > 0) + memmove(serial_input_buf, serial_input_buf + n, + serial_input_buf_len - n); + serial_input_buf_len -= n; + return n; + } + + SerGetBuf(serial_in_refnum, &len); + if (!len) + return 0; + + n = MAX(len, sizeof(session->ibuf) - session->ibuflen); + FSRead(serial_in_refnum, &len, + &session->ibuf + session->ibuflen); + session->ibuflen += len; + + return len; } short serial_output(struct session *session) { - return 0; + ParamBlockRec pbr = { 0 }; + + if (session->obuflen == 0 || session->ending) + return 0; + + pbr.ioParam.ioRefNum = serial_out_refnum; + pbr.ioParam.ioBuffer = (Ptr)&session->obuf; + pbr.ioParam.ioReqCount = session->obuflen; + PBWrite(&pbr, false); + + session->obuflen = 0; } void serial_close(struct session *session) { + serial_reset(); } --- util.h Mon Feb 7 21:18:17 2022 +++ util.h Tue Mar 29 13:17:24 2022 @@ -46,6 +46,8 @@ /* GetMBarHeight() is not very useful */ #define MENUBAR_HEIGHT 20 +#define TICKS_PER_SEC 60L + #define MAX_TEXTEDIT_SIZE 32767L #ifndef bool