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