ESP8266-based WiFi serial modem emulator ROM
1/*
2 * WiFiPPP
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
20struct eeprom_data *settings;
21
22WiFiUDP syslogUDPClient;
23Syslog syslog(syslogUDPClient, SYSLOG_PROTO_BSD);
24
25void
26setup(void)
27{
28 static_assert(sizeof(struct eeprom_data) < EEPROM_SIZE,
29 "EEPROM_SIZE < sizeof(struct eeprom_data)");
30
31 EEPROM.begin(EEPROM_SIZE);
32 settings = (struct eeprom_data *)EEPROM.getDataPtr();
33 if (memcmp(settings->magic, EEPROM_MAGIC_BYTES,
34 sizeof(settings->magic)) == 0) {
35 /* do migrations if needed based on current revision */
36 if (settings->revision != EEPROM_REVISION) {
37 settings->revision = EEPROM_REVISION;
38 EEPROM.commit();
39 }
40 } else {
41 /* start over */
42 memset(settings, 0, sizeof(struct eeprom_data));
43 memcpy(settings->magic, EEPROM_MAGIC_BYTES,
44 sizeof(settings->magic));
45 settings->revision = EEPROM_REVISION;
46
47 settings->echo = 1;
48 settings->quiet = 0;
49 settings->verbal = 1;
50
51 settings->baud = 9600;
52 settings->autobaud = 1;
53
54 /* enable hardware flow control, disable software */
55 settings->reg_r = REG_R_RTS_ON;
56 settings->reg_i = REG_I_XONXOFF_OFF;
57
58 settings->telnet = 1;
59 strlcpy(settings->telnet_tterm, "ansi",
60 sizeof(settings->telnet_tterm));
61 settings->telnet_tts_w = 80;
62 settings->telnet_tts_h = 24;
63
64 memset(settings->bookmarks, 0, BOOKMARK_SIZE * NUM_BOOKMARKS);
65 strlcpy(settings->bookmarks[0], "klud.ge",
66 sizeof(settings->bookmarks[0]));
67
68 IP4_ADDR(&settings->ppp_server_ip, 10, 10, 10, 10);
69 IP4_ADDR(&settings->ppp_client_ip, 10, 10, 10, 20);
70
71 settings->pixel_brightness = 5;
72
73 EEPROM.commit();
74 }
75
76 syslog_setup();
77 serial_setup();
78 pixel_setup();
79 screen_setup();
80
81 WiFi.mode(WIFI_STA);
82
83 /* don't require wifi_pass in case it's an open network */
84 if (settings->wifi_ssid[0] == 0)
85 WiFi.disconnect();
86 else
87 WiFi.begin(settings->wifi_ssid, settings->wifi_pass);
88
89 socks_setup();
90
91 serial_dsr(true);
92 serial_cts(true);
93}
94
95void
96syslog_setup(void)
97{
98 if (settings->syslog_server[0])
99 syslog.server(settings->syslog_server, 514);
100 else
101 syslog.server(NULL, 514);
102
103 syslog.appName("WiFiPPP");
104}
105
106size_t
107outputf(const char *format, ...)
108{
109 va_list arg;
110 char temp[64];
111 char* buf;
112
113 va_start(arg, format);
114 size_t len = vsnprintf(temp, sizeof(temp), format, arg);
115 va_end(arg);
116
117 if (len > sizeof(temp) - 1) {
118 /* too big for stack buffer, malloc something bigger */
119 buf = (char *)malloc(len + 1);
120 if (!buf)
121 return 0;
122
123 va_start(arg, format);
124 vsnprintf(buf, len + 1, format, arg);
125 va_end(arg);
126 } else
127 buf = temp;
128
129 output(buf);
130
131 if (buf != temp)
132 free(buf);
133
134 return len;
135}
136
137int
138output(char c)
139{
140 serial_write(c);
141 if (c == '\n')
142 serial_flush();
143
144 return 0;
145}
146
147int
148output(const char *str)
149{
150 size_t len = strlen(str);
151
152#ifdef OUTPUT_TRACE
153 syslog.logf(LOG_DEBUG, "output: \"%s\"", str);
154#endif
155
156 for (size_t i = 0; i < len; i++)
157 output(str[i]);
158
159 return 0;
160}
161
162int
163output(String str)
164{
165 size_t len = str.length();
166 char *buf = (char *)malloc(len + 1);
167 int ret;
168
169 if (buf == NULL)
170 return -1;
171
172 str.toCharArray(buf, len);
173 ret = output(buf);
174 free(buf);
175
176 return ret;
177}
178
179void
180syslog_buf(const char *buf, size_t len)
181{
182 static char tbuf[(64 * 4) + 1];
183 size_t tbufl = 0;
184
185 if (len > 64)
186 len = 64;
187
188 for (size_t i = 0; i < len; i++) {
189 if (buf[i] == '\n') {
190 tbuf[tbufl++] = '\\';
191 tbuf[tbufl++] = 'n';
192 } else if (buf[i] == '\r') {
193 tbuf[tbufl++] = '\\';
194 tbuf[tbufl++] = 'r';
195 } else if (buf[i] == ' ') {
196 tbuf[tbufl++] = ' ';
197 } else if (buf[i] < '!' || buf[i] > '~') {
198 sprintf(tbuf + tbufl, "[%02x]", buf[i]);
199 tbufl += 4;
200 } else {
201 tbuf[tbufl++] = buf[i];
202 }
203 }
204 tbuf[tbufl] = '\0';
205
206 syslog.log(LOG_DEBUG, tbuf);
207}