comparison megawifi.c @ 1959:6d99bdbf1e3e

megawifi: refactor and update commands
author doragasu <doragasu@hotmail.com>
date Sun, 03 May 2020 12:38:28 -0700
parents 1a09422b87a5
children f79e16d8baa4
comparison
equal deleted inserted replaced
1958:9c01945b5d20 1959:6d99bdbf1e3e
23 TX_PAYLOAD, 23 TX_PAYLOAD,
24 TX_WAIT_ETX 24 TX_WAIT_ETX
25 }; 25 };
26 #define STX 0x7E 26 #define STX 0x7E
27 #define ETX 0x7E 27 #define ETX 0x7E
28 #define MAX_RECV_SIZE 1440 28 #define MAX_RECV_SIZE 1460
29 29
30 #define E(N) N 30 #define E(N) N
31 enum { 31 enum {
32 #include "mw_commands.c" 32 #include "mw_commands.c"
33 CMD_ERROR = 255 33 CMD_ERROR = 255
48 STATE_AP_JOIN, 48 STATE_AP_JOIN,
49 STATE_SCAN, 49 STATE_SCAN,
50 STATE_READY, 50 STATE_READY,
51 STATE_TRANSPARENT 51 STATE_TRANSPARENT
52 }; 52 };
53
54 enum {
55 SOCKST_NONE = 0,
56 SOCKST_TCP_LISTEN,
57 SOCKST_TCP_EST,
58 SOCKST_UDP_READY
59 };
60
53 61
54 #define FLAG_ONLINE 62 #define FLAG_ONLINE
55 63
56 typedef struct { 64 typedef struct {
57 uint32_t transmit_bytes; 65 uint32_t transmit_bytes;
110 } 118 }
111 memcpy(mw->receive_buffer + mw->receive_bytes, src, count); 119 memcpy(mw->receive_buffer + mw->receive_bytes, src, count);
112 mw->receive_bytes += count; 120 mw->receive_bytes += count;
113 } 121 }
114 122
115 static void mw_puts(megawifi *mw, char *s) 123 static void mw_putraw(megawifi *mw, const char *data, size_t len)
116 { 124 {
117 uint32_t len = strlen(s);
118 if ((mw->receive_bytes + len) > sizeof(mw->receive_buffer)) { 125 if ((mw->receive_bytes + len) > sizeof(mw->receive_buffer)) {
119 return; 126 return;
120 } 127 }
121 memcpy(mw->receive_buffer + mw->receive_bytes, s, len); 128 memcpy(mw->receive_buffer + mw->receive_bytes, data, len);
122 mw->receive_bytes += len; 129 mw->receive_bytes += len;
130 }
131
132 static void mw_puts(megawifi *mw, const char *s)
133 {
134 size_t len = strlen(s);
135 mw_putraw(mw, s, len);
123 } 136 }
124 137
125 static void poll_socket(megawifi *mw, uint8_t channel) 138 static void poll_socket(megawifi *mw, uint8_t channel)
126 { 139 {
127 if (mw->sock_fds[channel] < 0) { 140 if (mw->sock_fds[channel] < 0) {
128 return; 141 return;
129 } 142 }
130 if (mw->channel_state[channel] == 1) { 143 if (mw->channel_state[channel] == SOCKST_TCP_LISTEN) {
131 int res = accept(mw->sock_fds[channel], NULL, NULL); 144 int res = accept(mw->sock_fds[channel], NULL, NULL);
132 if (res >= 0) { 145 if (res >= 0) {
133 close(mw->sock_fds[channel]); 146 close(mw->sock_fds[channel]);
134 #ifndef _WIN32 147 #ifndef _WIN32
135 //FIXME: Set nonblocking on Windows too 148 //FIXME: Set nonblocking on Windows too
136 fcntl(res, F_SETFL, O_NONBLOCK); 149 fcntl(res, F_SETFL, O_NONBLOCK);
137 #endif 150 #endif
138 mw->sock_fds[channel] = res; 151 mw->sock_fds[channel] = res;
139 mw->channel_state[channel] = 2; 152 mw->channel_state[channel] = SOCKST_TCP_EST;
140 mw->channel_flags |= 1 << (channel + 1); 153 mw->channel_flags |= 1 << (channel + 1);
141 } else if (errno != EAGAIN && errno != EWOULDBLOCK) { 154 } else if (errno != EAGAIN && errno != EWOULDBLOCK) {
142 close(mw->sock_fds[channel]); 155 close(mw->sock_fds[channel]);
143 mw->channel_state[channel] = 0; 156 mw->channel_state[channel] = SOCKST_NONE;
144 mw->channel_flags |= 1 << (channel + 1); 157 mw->channel_flags |= 1 << (channel + 1);
145 } 158 }
146 } else if (mw->channel_state[channel] == 2 && mw->receive_bytes < sizeof(mw->receive_buffer) - 4) { 159 } else if (mw->channel_state[channel] == SOCKST_TCP_EST && mw->receive_bytes < sizeof(mw->receive_buffer) - 4) {
147 size_t max = sizeof(mw->receive_buffer) - 4 - mw->receive_bytes; 160 size_t max = sizeof(mw->receive_buffer) - 4 - mw->receive_bytes;
148 if (max > MAX_RECV_SIZE) { 161 if (max > MAX_RECV_SIZE) {
149 max = MAX_RECV_SIZE; 162 max = MAX_RECV_SIZE;
150 } 163 }
151 int bytes = recv(mw->sock_fds[channel], mw->receive_buffer + mw->receive_bytes + 3, max, 0); 164 int bytes = recv(mw->sock_fds[channel], mw->receive_buffer + mw->receive_bytes + 3, max, 0);
156 mw->receive_bytes += bytes; 169 mw->receive_bytes += bytes;
157 mw_putc(mw, ETX); 170 mw_putc(mw, ETX);
158 //should this set the channel flag? 171 //should this set the channel flag?
159 } else if (bytes < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { 172 } else if (bytes < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
160 close(mw->sock_fds[channel]); 173 close(mw->sock_fds[channel]);
161 mw->channel_state[channel] = 0; 174 mw->channel_state[channel] = SOCKST_NONE;
162 mw->channel_flags |= 1 << (channel + 1); 175 mw->channel_flags |= 1 << (channel + 1);
163 } 176 }
164 } 177 }
165 } 178 }
166 179
195 mw->receive_buffer[5] = len >> 8; 208 mw->receive_buffer[5] = len >> 8;
196 mw->receive_buffer[6] = len; 209 mw->receive_buffer[6] = len;
197 mw_putc(mw, ETX); 210 mw_putc(mw, ETX);
198 } 211 }
199 212
200 static void process_packet(megawifi *mw) 213 static void process_command(megawifi *mw)
201 { 214 {
202 if (mw->transmit_channel == 0) { 215 uint32_t command = mw->transmit_buffer[0] << 8 | mw->transmit_buffer[1];
203 uint32_t command = mw->transmit_buffer[0] << 8 | mw->transmit_buffer[1]; 216 uint32_t size = mw->transmit_buffer[2] << 8 | mw->transmit_buffer[3];
204 uint32_t size = mw->transmit_buffer[2] << 8 | mw->transmit_buffer[3]; 217 if (size > mw->transmit_bytes - 4) {
205 if (size > mw->transmit_bytes - 4) { 218 size = mw->transmit_bytes - 4;
206 size = mw->transmit_bytes - 4; 219 }
207 } 220 int orig_receive_bytes = mw->receive_bytes;
208 int orig_receive_bytes = mw->receive_bytes; 221 switch (command)
209 switch (command) 222 {
210 { 223 case CMD_VERSION:
211 case CMD_VERSION: 224 start_reply(mw, CMD_OK);
225 mw_putc(mw, 1);
226 mw_putc(mw, 3);
227 mw_putc(mw, 0);
228 mw_puts(mw, "blastem");
229 end_reply(mw);
230 break;
231 case CMD_ECHO:
232 mw->receive_bytes = mw->transmit_bytes;
233 memcpy(mw->receive_buffer, mw->transmit_buffer, mw->transmit_bytes);
234 break;
235 case CMD_IP_CURRENT: {
236 iface_info i;
237 if (get_host_address(&i)) {
212 start_reply(mw, CMD_OK); 238 start_reply(mw, CMD_OK);
213 mw_putc(mw, 1); 239 //config number and reserved bytes
214 mw_putc(mw, 0); 240 mw_set(mw, 0, 4);
215 mw_puts(mw, "blastem"); 241 //ip
242 mw_copy(mw, i.ip, sizeof(i.ip));
243 //net mask
244 mw_copy(mw, i.net_mask, sizeof(i.net_mask));
245 //gateway guess
246 mw_putc(mw, i.ip[0] & i.net_mask[0]);
247 mw_putc(mw, i.ip[1] & i.net_mask[1]);
248 mw_putc(mw, i.ip[2] & i.net_mask[2]);
249 mw_putc(mw, (i.ip[3] & i.net_mask[3]) + 1);
250 //dns
251 static const uint8_t localhost[] = {127,0,0,1};
252 mw_copy(mw, localhost, sizeof(localhost));
253 mw_copy(mw, localhost, sizeof(localhost));
254
255 } else {
256 start_reply(mw, CMD_ERROR);
257 }
258 end_reply(mw);
259 break;
260 }
261 case CMD_AP_JOIN:
262 mw->module_state = STATE_READY;
263 start_reply(mw, CMD_OK);
264 end_reply(mw);
265 break;
266 case CMD_TCP_BIND:{
267 if (size < 7){
268 start_reply(mw, CMD_ERROR);
216 end_reply(mw); 269 end_reply(mw);
217 break; 270 break;
218 case CMD_ECHO: 271 }
219 mw->receive_bytes = mw->transmit_bytes; 272 uint8_t channel = mw->transmit_buffer[10];
220 memcpy(mw->receive_buffer, mw->transmit_buffer, mw->transmit_bytes); 273 if (!channel || channel > 15) {
221 break; 274 start_reply(mw, CMD_ERROR);
222 case CMD_IP_CURRENT: {
223 iface_info i;
224 if (get_host_address(&i)) {
225 start_reply(mw, CMD_OK);
226 //config number and reserved bytes
227 mw_set(mw, 0, 4);
228 //ip
229 mw_copy(mw, i.ip, sizeof(i.ip));
230 //net mask
231 mw_copy(mw, i.net_mask, sizeof(i.net_mask));
232 //gateway guess
233 mw_putc(mw, i.ip[0] & i.net_mask[0]);
234 mw_putc(mw, i.ip[1] & i.net_mask[1]);
235 mw_putc(mw, i.ip[2] & i.net_mask[2]);
236 mw_putc(mw, (i.ip[3] & i.net_mask[3]) + 1);
237 //dns
238 static const uint8_t localhost[] = {127,0,0,1};
239 mw_copy(mw, localhost, sizeof(localhost));
240 mw_copy(mw, localhost, sizeof(localhost));
241
242 } else {
243 start_reply(mw, CMD_ERROR);
244 }
245 end_reply(mw); 275 end_reply(mw);
246 break; 276 break;
247 } 277 }
248 case CMD_AP_JOIN: 278 channel--;
249 mw->module_state = STATE_READY; 279 if (mw->sock_fds[channel] >= 0) {
250 start_reply(mw, CMD_OK); 280 close(mw->sock_fds[channel]);
281 }
282 mw->sock_fds[channel] = socket(AF_INET, SOCK_STREAM, 0);
283 if (mw->sock_fds[channel] < 0) {
284 start_reply(mw, CMD_ERROR);
251 end_reply(mw); 285 end_reply(mw);
252 break; 286 break;
253 case CMD_TCP_BIND:{ 287 }
254 if (size < 7){ 288 int value = 1;
255 start_reply(mw, CMD_ERROR); 289 setsockopt(mw->sock_fds[channel], SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
256 end_reply(mw); 290 struct sockaddr_in bind_addr;
257 break; 291 memset(&bind_addr, 0, sizeof(bind_addr));
258 } 292 bind_addr.sin_family = AF_INET;
259 uint8_t channel = mw->transmit_buffer[10]; 293 bind_addr.sin_port = htons(mw->transmit_buffer[8] << 8 | mw->transmit_buffer[9]);
260 if (!channel || channel > 15) { 294 if (bind(mw->sock_fds[channel], (struct sockaddr *)&bind_addr, sizeof(bind_addr)) != 0) {
261 start_reply(mw, CMD_ERROR); 295 close(mw->sock_fds[channel]);
262 end_reply(mw); 296 mw->sock_fds[channel] = -1;
263 break; 297 start_reply(mw, CMD_ERROR);
264 } 298 end_reply(mw);
265 channel--; 299 break;
266 if (mw->sock_fds[channel] >= 0) { 300 }
267 close(mw->sock_fds[channel]); 301 int res = listen(mw->sock_fds[channel], 2);
268 } 302 start_reply(mw, res ? CMD_ERROR : CMD_OK);
269 mw->sock_fds[channel] = socket(AF_INET, SOCK_STREAM, 0); 303 if (res) {
270 if (mw->sock_fds[channel] < 0) { 304 close(mw->sock_fds[channel]);
271 start_reply(mw, CMD_ERROR); 305 mw->sock_fds[channel] = -1;
272 end_reply(mw); 306 } else {
273 break; 307 mw->channel_flags |= 1 << (channel + 1);
274 } 308 mw->channel_state[channel] = SOCKST_TCP_LISTEN;
275 int value = 1;
276 setsockopt(mw->sock_fds[channel], SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
277 struct sockaddr_in bind_addr;
278 memset(&bind_addr, 0, sizeof(bind_addr));
279 bind_addr.sin_family = AF_INET;
280 bind_addr.sin_port = htons(mw->transmit_buffer[8] << 8 | mw->transmit_buffer[9]);
281 if (bind(mw->sock_fds[channel], (struct sockaddr *)&bind_addr, sizeof(bind_addr)) != 0) {
282 close(mw->sock_fds[channel]);
283 mw->sock_fds[channel] = -1;
284 start_reply(mw, CMD_ERROR);
285 end_reply(mw);
286 break;
287 }
288 int res = listen(mw->sock_fds[channel], 2);
289 start_reply(mw, res ? CMD_ERROR : CMD_OK);
290 if (res) {
291 close(mw->sock_fds[channel]);
292 mw->sock_fds[channel] = -1;
293 } else {
294 mw->channel_flags |= 1 << (channel + 1);
295 mw->channel_state[channel] = 1;
296 #ifndef _WIN32 309 #ifndef _WIN32
297 //FIXME: Set nonblocking on Windows too 310 //FIXME: Set nonblocking on Windows too
298 fcntl(mw->sock_fds[channel], F_SETFL, O_NONBLOCK); 311 fcntl(mw->sock_fds[channel], F_SETFL, O_NONBLOCK);
299 #endif 312 #endif
313 }
314 end_reply(mw);
315 break;
316 }
317 case CMD_SOCK_STAT: {
318 uint8_t channel = mw->transmit_buffer[4];
319 if (!channel || channel > 15) {
320 start_reply(mw, CMD_ERROR);
321 end_reply(mw);
322 break;
323 }
324 mw->channel_flags &= ~(1 << channel);
325 channel--;
326 poll_socket(mw, channel);
327 start_reply(mw, CMD_OK);
328 mw_putc(mw, mw->channel_state[channel]);
329 end_reply(mw);
330 break;
331 }
332 case CMD_SYS_STAT:
333 poll_all_sockets(mw);
334 start_reply(mw, CMD_OK);
335 mw_putc(mw, mw->module_state);
336 mw_putc(mw, mw->flags);
337 mw_putc(mw, mw->channel_flags >> 8);
338 mw_putc(mw, mw->channel_flags);
339 end_reply(mw);
340 break;
341 default:
342 printf("Unhandled MegaWiFi command %s(%d) with length %X\n", cmd_names[command], command, size);
343 break;
344 }
345 }
346
347 static void process_packet(megawifi *mw)
348 {
349 if (mw->transmit_channel == 0) {
350 process_command(mw);
351 } else {
352 uint8_t channel = mw->transmit_channel - 1;
353 int channel_state = mw->channel_state[channel];
354 int sock_fd = mw->sock_fds[channel];
355 // TODO Handle UDP type sockets
356 if (sock_fd >= 0 && channel_state == SOCKST_TCP_EST) {
357 int sent = send(sock_fd, mw->transmit_buffer, mw->transmit_bytes, MSG_NOSIGNAL);
358 if (sent < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
359 close(sock_fd);
360 mw->sock_fds[channel] = -1;
361 mw->channel_state[channel] = SOCKST_NONE;
362 mw->channel_flags |= 1 << mw->transmit_channel;
363 } else if (sent < mw->transmit_bytes) {
364 //TODO: save this data somewhere so it can be sent in poll_socket
365 printf("Sent %d bytes on channel %d, but %d were requested\n", sent, mw->transmit_channel, mw->transmit_bytes);
300 } 366 }
301 end_reply(mw); 367 } else {
302 break; 368 printf("Unhandled receive of MegaWiFi data on channel %d\n", mw->transmit_channel);
303 } 369 }
304 case CMD_SOCK_STAT: {
305 uint8_t channel = mw->transmit_buffer[4];
306 if (!channel || channel > 15) {
307 start_reply(mw, CMD_ERROR);
308 end_reply(mw);
309 break;
310 }
311 mw->channel_flags &= ~(1 << channel);
312 channel--;
313 poll_socket(mw, channel);
314 start_reply(mw, CMD_OK);
315 mw_putc(mw, mw->channel_state[channel]);
316 end_reply(mw);
317 break;
318 }
319 case CMD_SYS_STAT:
320 poll_all_sockets(mw);
321 start_reply(mw, CMD_OK);
322 mw_putc(mw, mw->module_state);
323 mw_putc(mw, mw->flags);
324 mw_putc(mw, mw->channel_flags >> 8);
325 mw_putc(mw, mw->channel_flags);
326 end_reply(mw);
327 break;
328 default:
329 printf("Unhandled MegaWiFi command %s(%d) with length %X\n", cmd_names[command], command, size);
330 break;
331 }
332 } else if (mw->sock_fds[mw->transmit_channel - 1] >= 0 && mw->channel_state[mw->transmit_channel - 1] == 2) {
333 uint8_t channel = mw->transmit_channel - 1;
334 int sent = send(mw->sock_fds[channel], mw->transmit_buffer, mw->transmit_bytes, MSG_NOSIGNAL);
335 if (sent < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
336 close(mw->sock_fds[channel]);
337 mw->sock_fds[channel] = -1;
338 mw->channel_state[channel] = 0;
339 mw->channel_flags |= 1 << mw->transmit_channel;
340 } else if (sent < mw->transmit_bytes) {
341 //TODO: save this data somewhere so it can be sent in poll_socket
342 printf("Sent %d bytes on channel %d, but %d were requested\n", sent, mw->transmit_channel, mw->transmit_bytes);
343 }
344 } else {
345 printf("Unhandled receive of MegaWiFi data on channel %d\n", mw->transmit_channel);
346 } 370 }
347 mw->transmit_bytes = mw->expected_bytes = 0; 371 mw->transmit_bytes = mw->expected_bytes = 0;
348 } 372 }
349 373
350 void *megawifi_write_b(uint32_t address, void *context, uint8_t value) 374 void *megawifi_write_b(uint32_t address, void *context, uint8_t value)