ESP8266-based WiFi serial modem emulator ROM
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Serial: Setup other pins for RS232

A Pololu 23201a board based on the MAX3238 is doing RS232 to TTL
serial for us.

Start on supporting hardware flow control by only sending when RTS
is asserted.

Assert DSR and CTS after init.

Assert DCD when we're connected to telnet or PPP.

+188 -20
+3
GNUmakefile
··· 1 1 # pkg_add makeesparduino 2 2 3 + # targeting the adafruit feather huzzah esp8266 4 + BOARD = huzzah 5 + 3 6 # default of -w supresses all warnings 4 7 COMP_WARNINGS = -Wall -Wextra 5 8
+2
ppp.cpp
··· 49 49 ppp_set_ipcp_hisaddr(_ppp, &c_addr); /* or hers! */ 50 50 51 51 outputf("CONNECT %d %s:PPP\r\n", settings->baud, ipaddr_ntoa(&s_addr)); 52 + serial_dcd(true); 52 53 53 54 ppp_listen(_ppp); 54 55 ··· 157 158 ppp_free(_ppp); 158 159 _ppp = NULL; 159 160 state = STATE_AT; 161 + serial_dcd(false); 160 162 outputf("\r\nNO CARRIER\r\n"); 161 163 return; 162 164 }
+127
serial.cpp
··· 1 + /* 2 + * WiFiStation 3 + * Copyright (c) 2021 joshua stein <jcs@jcs.org> 4 + * 5 + * Permission to use, copy, modify, and distribute this software for any 6 + * purpose with or without fee is hereby granted, provided that the above 7 + * copyright notice and this permission notice appear in all copies. 8 + * 9 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 + */ 17 + 18 + #include "wifippp.h" 19 + 20 + bool serial_alive = true; 21 + 22 + void 23 + serial_setup(void) 24 + { 25 + /* DCE mode, acting as a modem */ 26 + 27 + serial_begin(settings->baud); 28 + 29 + pinMode(pRI, OUTPUT); 30 + serial_ri(false); 31 + 32 + pinMode(pDSR, OUTPUT); 33 + serial_dsr(false); 34 + 35 + pinMode(pRTS, INPUT); 36 + 37 + pinMode(pCTS, OUTPUT); 38 + serial_cts(false); 39 + 40 + pinMode(pDCD, OUTPUT); 41 + serial_dcd(false); 42 + 43 + pinMode(pDTR, INPUT); 44 + } 45 + 46 + void 47 + serial_begin(int baud) 48 + { 49 + Serial.begin(baud); 50 + } 51 + 52 + void 53 + serial_write(char b) 54 + { 55 + if (settings->reg_r == REG_R_RTS_ON) { 56 + while (!serial_rts()) 57 + yield(); 58 + } 59 + Serial.write(b); 60 + } 61 + 62 + void 63 + serial_flush(void) 64 + { 65 + Serial.flush(); 66 + } 67 + 68 + bool 69 + serial_available(void) 70 + { 71 + return Serial.available(); 72 + } 73 + 74 + uint8_t 75 + serial_read(void) 76 + { 77 + return Serial.read(); 78 + } 79 + 80 + int16_t 81 + serial_peek(void) 82 + { 83 + return Serial.peek(); 84 + } 85 + 86 + /* Clear to Send */ 87 + void 88 + serial_cts(bool clear) 89 + { 90 + digitalWrite(pCTS, clear ? LOW : HIGH); /* inverted */ 91 + } 92 + 93 + /* Data Carrier Detect */ 94 + void 95 + serial_dcd(bool carrier) 96 + { 97 + digitalWrite(pBlueLED, carrier ? LOW : HIGH); 98 + digitalWrite(pDCD, carrier ? LOW : HIGH); /* inverted */ 99 + } 100 + 101 + /* Data Set Ready */ 102 + void 103 + serial_dsr(bool ready) 104 + { 105 + digitalWrite(pDSR, ready ? LOW : HIGH); /* inverted */ 106 + } 107 + 108 + /* Data Terminal Ready */ 109 + bool 110 + serial_dtr(void) 111 + { 112 + return (digitalRead(pDTR) == LOW); /* inverted */ 113 + } 114 + 115 + /* Ring Indicator */ 116 + void 117 + serial_ri(bool ringing) 118 + { 119 + digitalWrite(pRI, ringing ? LOW : HIGH); /* inverted */ 120 + } 121 + 122 + /* Ready to Send */ 123 + bool 124 + serial_rts(void) 125 + { 126 + return (digitalRead(pRTS) == LOW); /* inverted */ 127 + }
+4 -2
telnet.cpp
··· 100 100 101 101 telnet_state = TELNET_STATE_CONNECTED; 102 102 telnet_echoing = true; 103 + serial_dcd(true); 103 104 return 0; 104 105 } 105 106 ··· 110 111 return false; 111 112 112 113 if (!telnet.connected()) { 113 - telnet.stop(); 114 - telnet_state = TELNET_STATE_DISCONNECTED; 114 + if (telnet_state != TELNET_STATE_DISCONNECTED) 115 + telnet_disconnect(); 115 116 return false; 116 117 } 117 118 ··· 123 124 { 124 125 telnet.stop(); 125 126 telnet_state = TELNET_STATE_DISCONNECTED; 127 + serial_dcd(false); 126 128 } 127 129 128 130 void
+1 -1
update.cpp
··· 173 173 outputf("Updating to version %s (%d bytes) from %s\r\n", 174 174 version.c_str(), bytesize, (char *)url.c_str()); 175 175 176 - Update.begin(bytesize, U_FLASH, pBlueLED); 176 + Update.begin(bytesize, U_FLASH, pRedLED); 177 177 178 178 Update.setMD5(md5.c_str()); 179 179
+14 -8
util.cpp
··· 19 19 20 20 struct eeprom_data *settings; 21 21 22 - bool serial_alive = true; 23 - 24 22 WiFiUDP syslogUDPClient; 25 23 Syslog syslog(syslogUDPClient, SYSLOG_PROTO_BSD); 26 24 ··· 47 45 settings->revision = EEPROM_REVISION; 48 46 49 47 settings->baud = 115200; 48 + 49 + /* enable hardware flow control, disable software */ 50 + settings->reg_r = REG_R_RTS_ON; 51 + settings->reg_i = REG_I_XONXOFF_OFF; 50 52 51 53 settings->telnet = 1; 52 54 strlcpy(settings->telnet_tterm, "ansi", ··· 67 69 68 70 syslog_setup(); 69 71 70 - Serial.begin(settings->baud); 71 - delay(1000); 72 + serial_setup(); 72 73 73 74 led_setup(); 74 75 led_reset(); ··· 82 83 WiFi.begin(settings->wifi_ssid, settings->wifi_pass); 83 84 84 85 socks_setup(); 86 + 87 + serial_dsr(true); 88 + serial_cts(true); 85 89 } 86 90 87 91 void ··· 99 103 led_setup(void) 100 104 { 101 105 /* setup LEDs */ 106 + pinMode(pRedLED, OUTPUT); 102 107 pinMode(pBlueLED, OUTPUT); 103 108 led_reset(); 104 109 } ··· 106 111 void 107 112 error_flash(void) 108 113 { 109 - digitalWrite(pBlueLED, LOW); 114 + digitalWrite(pRedLED, LOW); 110 115 delay(100); 111 - digitalWrite(pBlueLED, HIGH); 116 + digitalWrite(pRedLED, HIGH); 112 117 } 113 118 114 119 void 115 120 led_reset(void) 116 121 { 122 + digitalWrite(pRedLED, HIGH); 117 123 digitalWrite(pBlueLED, HIGH); 118 124 } 119 125 ··· 152 158 output(char c) 153 159 { 154 160 if (serial_alive) { 155 - Serial.write(c); 161 + serial_write(c); 156 162 if (c == '\n') 157 - Serial.flush(); 163 + serial_flush(); 158 164 } 159 165 160 166 return 0;
+30 -2
wifippp.h
··· 45 45 char syslog_server[64]; 46 46 ip4_addr_t ppp_server_ip; 47 47 ip4_addr_t ppp_client_ip; 48 + uint8_t reg_r; 49 + #define REG_R_RTS_OFF 1 50 + #define REG_R_RTS_ON 2 51 + uint8_t reg_i; 52 + #define REG_I_XONXOFF_OFF 0 53 + #define REG_I_XONXOFF_ON 1 48 54 }; 49 55 50 56 enum { ··· 59 65 60 66 #define MAX_UPLOAD_SIZE (16 * 1024) 61 67 62 - /* ESP8266 pins */ 63 - const int pBlueLED = 16; 68 + /* ESP8266 pins for Adafruit Huzzah */ 69 + const int pRedLED = 0; 70 + const int pBlueLED = 2; 71 + const int pRI = 0; 72 + const int pDCD = 4; 73 + const int pDTR = 5; 74 + const int pDSR = 12; 75 + const int pRTS = 13; 76 + const int pCTS = 14; 64 77 65 78 /* ppp.cpp */ 66 79 bool ppp_start(void); 67 80 void ppp_process(void); 81 + 82 + /* serial.cpp */ 83 + void serial_setup(void); 84 + void serial_begin(int baud); 85 + uint8_t serial_read(void); 86 + bool serial_available(void); 87 + int16_t serial_peek(void); 88 + void serial_write(char b); 89 + void serial_flush(void); 90 + void serial_cts(bool clear); 91 + void serial_dcd(bool carrier); 92 + void serial_dsr(bool ready); 93 + bool serial_dtr(void); 94 + void serial_ri(bool ringing); 95 + bool serial_rts(void); 68 96 69 97 /* socks.cpp */ 70 98 void socks_setup(void);
+7 -7
wifippp.ino
··· 36 36 37 37 switch (state) { 38 38 case STATE_AT: 39 - if (Serial.available() && (b = Serial.read())) 39 + if (serial_available() && (b = serial_read())) 40 40 serial_alive = true; 41 41 else 42 42 return; ··· 63 63 /* if sender is using \r\n, ignore the \n */ 64 64 now = millis(); 65 65 while (millis() - now < 10) { 66 - int b2 = Serial.peek(); 66 + int b2 = serial_peek(); 67 67 if (b2 == -1) 68 68 continue; 69 69 else if (b2 == '\n') { 70 70 /* this is a \r\n, ignore \n */ 71 - Serial.read(); 71 + serial_read(); 72 72 break; 73 73 } else { 74 74 /* some other data */ ··· 97 97 case STATE_TELNET: 98 98 b = -1; 99 99 100 - if (Serial.available() && (b = Serial.read())) 100 + if (serial_available() && (b = serial_read())) 101 101 serial_alive = true; 102 102 103 103 if (b == -1 && plus_wait > 0 && (millis() - plus_wait) >= 500) { ··· 131 131 132 132 if ((b = telnet_read()) != -1) { 133 133 if (serial_alive) 134 - Serial.write(b); 134 + serial_write(b); 135 135 return; 136 136 } else if (!telnet_connected()) { 137 137 output("\r\nNO CARRIER\r\n"); ··· 470 470 settings->baud = baud; 471 471 outputf("OK switching to %d\r\n", 472 472 settings->baud); 473 - Serial.flush(); 474 - Serial.begin(settings->baud); 473 + serial_flush(); 474 + serial_begin(settings->baud); 475 475 break; 476 476 default: 477 477 output("ERROR unsupported baud rate\r\n");