Bringing WiFi to the Cidco Mailstation
at main 222 lines 4.5 kB view raw
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 "wifistation.h" 19 20struct eeprom_data *settings; 21 22bool serial_alive = true; 23bool mailstation_alive = false; 24 25WiFiUDP syslogUDPClient; 26Syslog syslog(syslogUDPClient, SYSLOG_PROTO_BSD); 27 28#define BOOKMARK_0 "klud.ge" 29 30void 31setup(void) 32{ 33 static_assert(sizeof(struct eeprom_data) < EEPROM_SIZE, 34 "EEPROM_SIZE is not large enough to hold struct eeprom_data"); 35 36 EEPROM.begin(EEPROM_SIZE); 37 settings = (struct eeprom_data *)EEPROM.getDataPtr(); 38 if (memcmp(settings->magic, EEPROM_MAGIC_BYTES, 39 sizeof(settings->magic)) == 0) { 40 /* do migrations if needed based on current revision */ 41 switch (settings->revision) { 42 case 1: 43 settings->http_server = 0; 44 /* FALLTHROUGH */ 45 case 2: 46 memset(settings->bookmarks, 0, 47 BOOKMARK_SIZE * NUM_BOOKMARKS); 48 strcpy(settings->bookmarks[0], BOOKMARK_0); 49 /* FALLTHROUGH */ 50 case 3: 51 settings->echo = 1; 52 settings->quiet = 0; 53 settings->verbal = 1; 54 } 55 56 if (settings->revision != EEPROM_REVISION) { 57 settings->revision = EEPROM_REVISION; 58 EEPROM.commit(); 59 } 60 } else { 61 /* start over */ 62 memset(settings, 0, sizeof(struct eeprom_data)); 63 memcpy(settings->magic, EEPROM_MAGIC_BYTES, 64 sizeof(settings->magic)); 65 settings->revision = EEPROM_REVISION; 66 67 settings->baud = 9600; 68 69 settings->telnet = 1; 70 strlcpy(settings->telnet_tterm, "ansi", 71 sizeof(settings->telnet_tterm)); 72 /* msTERM defaults */ 73 settings->telnet_tts_w = 64; 74 settings->telnet_tts_h = 15; 75 76 settings->http_server = 0; 77 78 settings->echo = 1; 79 settings->quiet = 0; 80 settings->verbal = 1; 81 82 memset(settings->bookmarks, 0, 83 BOOKMARK_SIZE * NUM_BOOKMARKS); 84 strcpy(settings->bookmarks[0], BOOKMARK_0); 85 86 EEPROM.commit(); 87 } 88 89 syslog_setup(); 90 91 Serial.begin(settings->baud); 92 delay(1000); 93 94 led_setup(); 95 ms_setup(); 96 led_reset(); 97 98 WiFi.persistent(false); 99 WiFi.mode(WIFI_STA); 100 101 /* don't require wifi_pass in case it's an open network */ 102 if (settings->wifi_ssid[0] == 0) 103 WiFi.disconnect(); 104 else 105 WiFi.begin(settings->wifi_ssid, settings->wifi_pass); 106 107 http_setup(); 108} 109 110void 111syslog_setup(void) 112{ 113 if (settings->syslog_server[0]) 114 syslog.server(settings->syslog_server, 514); 115 else 116 syslog.server(NULL, 514); 117} 118 119void 120led_setup(void) 121{ 122 /* setup LEDs */ 123 pinMode(pRedLED, OUTPUT); 124 pinMode(pBlueLED, OUTPUT); 125 led_reset(); 126} 127 128void 129error_flash(void) 130{ 131 digitalWrite(pRedLED, LOW); 132 digitalWrite(pBlueLED, HIGH); 133 delay(100); 134 digitalWrite(pRedLED, HIGH); 135 digitalWrite(pBlueLED, LOW); 136 delay(100); 137 digitalWrite(pBlueLED, HIGH); 138} 139 140void 141led_reset(void) 142{ 143 digitalWrite(pRedLED, HIGH); 144 digitalWrite(pBlueLED, HIGH); 145} 146 147size_t 148outputf(const char *format, ...) 149{ 150 va_list arg; 151 char temp[64]; 152 char* buf; 153 154 va_start(arg, format); 155 size_t len = vsnprintf(temp, sizeof(temp), format, arg); 156 va_end(arg); 157 158 if (len > sizeof(temp) - 1) { 159 /* too big for stack buffer, malloc something bigger */ 160 buf = (char *)malloc(len + 1); 161 if (!buf) 162 return 0; 163 164 va_start(arg, format); 165 vsnprintf(buf, len + 1, format, arg); 166 va_end(arg); 167 } else 168 buf = temp; 169 170 output(buf); 171 172 if (buf != temp) 173 free(buf); 174 175 return len; 176} 177 178int 179output(char c) 180{ 181 if (serial_alive) { 182 Serial.write(c); 183 if (c == '\n') 184 Serial.flush(); 185 } 186 if (mailstation_alive) 187 ms_write(c); 188 189 return 0; 190} 191 192int 193output(const char *str) 194{ 195 size_t len = strlen(str); 196 197#ifdef OUTPUT_TRACE 198 syslog.logf(LOG_DEBUG, "output: \"%s\"", str); 199#endif 200 201 for (size_t i = 0; i < len; i++) 202 output(str[i]); 203 204 return 0; 205} 206 207int 208output(String str) 209{ 210 size_t len = str.length(); 211 char *buf = (char *)malloc(len + 1); 212 int ret; 213 214 if (buf == NULL) 215 return -1; 216 217 str.toCharArray(buf, len); 218 ret = output(buf); 219 free(buf); 220 221 return ret; 222}