comparison megawifi.c @ 1968:c16dabdb0aad

megawifi: use util module socket functions for WIN32 compatibility
author doragasu <doragasu@hotmail.com>
date Fri, 08 May 2020 00:24:25 -0700
parents b3c2dcae7dfc
children 852393cdec7c
comparison
equal deleted inserted replaced
1967:bd70f1e15684 1968:c16dabdb0aad
15 #include <errno.h> 15 #include <errno.h>
16 #include <fcntl.h> 16 #include <fcntl.h>
17 #include <time.h> 17 #include <time.h>
18 #include "genesis.h" 18 #include "genesis.h"
19 #include "net.h" 19 #include "net.h"
20 #include "util.h"
20 21
21 enum { 22 enum {
22 TX_IDLE, 23 TX_IDLE,
23 TX_LEN1, 24 TX_LEN1,
24 TX_LEN2, 25 TX_LEN2,
83 static megawifi *get_megawifi(void *context) 84 static megawifi *get_megawifi(void *context)
84 { 85 {
85 m68k_context *m68k = context; 86 m68k_context *m68k = context;
86 genesis_context *gen = m68k->system; 87 genesis_context *gen = m68k->system;
87 if (!gen->extra) { 88 if (!gen->extra) {
89 socket_init();
88 gen->extra = calloc(1, sizeof(megawifi)); 90 gen->extra = calloc(1, sizeof(megawifi));
89 megawifi *mw = gen->extra; 91 megawifi *mw = gen->extra;
90 mw->module_state = STATE_IDLE; 92 mw->module_state = STATE_IDLE;
91 for (int i = 0; i < 15; i++) 93 for (int i = 0; i < 15; i++) {
92 {
93 mw->sock_fds[i] = -1; 94 mw->sock_fds[i] = -1;
94 } 95 }
95 } 96 }
96 return gen->extra; 97 return gen->extra;
97 } 98 }
143 return; 144 return;
144 } 145 }
145 if (mw->channel_state[channel] == SOCKST_TCP_LISTEN) { 146 if (mw->channel_state[channel] == SOCKST_TCP_LISTEN) {
146 int res = accept(mw->sock_fds[channel], NULL, NULL); 147 int res = accept(mw->sock_fds[channel], NULL, NULL);
147 if (res >= 0) { 148 if (res >= 0) {
148 close(mw->sock_fds[channel]); 149 socket_close(mw->sock_fds[channel]);
149 #ifndef _WIN32 150 socket_blocking(res, 0);
150 //FIXME: Set nonblocking on Windows too
151 fcntl(res, F_SETFL, O_NONBLOCK);
152 #endif
153 mw->sock_fds[channel] = res; 151 mw->sock_fds[channel] = res;
154 mw->channel_state[channel] = SOCKST_TCP_EST; 152 mw->channel_state[channel] = SOCKST_TCP_EST;
155 mw->channel_flags |= 1 << (channel + 1); 153 mw->channel_flags |= 1 << (channel + 1);
156 } else if (errno != EAGAIN && errno != EWOULDBLOCK) { 154 } else if (errno != EAGAIN && errno != EWOULDBLOCK) {
157 close(mw->sock_fds[channel]); 155 socket_close(mw->sock_fds[channel]);
158 mw->channel_state[channel] = SOCKST_NONE; 156 mw->channel_state[channel] = SOCKST_NONE;
159 mw->channel_flags |= 1 << (channel + 1); 157 mw->channel_flags |= 1 << (channel + 1);
160 } 158 }
161 } else if (mw->channel_state[channel] == SOCKST_TCP_EST && 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) {
162 size_t max = sizeof(mw->receive_buffer) - 4 - mw->receive_bytes; 160 size_t max = sizeof(mw->receive_buffer) - 4 - mw->receive_bytes;
163 if (max > MAX_RECV_SIZE) { 161 if (max > MAX_RECV_SIZE) {
164 max = MAX_RECV_SIZE; 162 max = MAX_RECV_SIZE;
165 } 163 }
166 int bytes = recv(mw->sock_fds[channel], mw->receive_buffer + mw->receive_bytes + 3, max, 0); 164 int bytes = recv(mw->sock_fds[channel], (char*)(mw->receive_buffer + mw->receive_bytes + 3), max, 0);
167 if (bytes > 0) { 165 if (bytes > 0) {
168 mw_putc(mw, STX); 166 mw_putc(mw, STX);
169 mw_putc(mw, bytes >> 8 | (channel+1) << 4); 167 mw_putc(mw, bytes >> 8 | (channel+1) << 4);
170 mw_putc(mw, bytes); 168 mw_putc(mw, bytes);
171 mw->receive_bytes += bytes; 169 mw->receive_bytes += bytes;
172 mw_putc(mw, ETX); 170 mw_putc(mw, ETX);
173 //should this set the channel flag? 171 //should this set the channel flag?
174 } else if (bytes < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { 172 } else if (bytes < 0 && !socket_error_is_wouldblock()) {
175 close(mw->sock_fds[channel]); 173 socket_close(mw->sock_fds[channel]);
176 mw->channel_state[channel] = SOCKST_NONE; 174 mw->channel_state[channel] = SOCKST_NONE;
177 mw->channel_flags |= 1 << (channel + 1); 175 mw->channel_flags |= 1 << (channel + 1);
178 } 176 }
179 } 177 }
180 } 178 }
291 // Should this be handled in a separate thread to avoid blocking emulation? 289 // Should this be handled in a separate thread to avoid blocking emulation?
292 if (connect(s, res->ai_addr, res->ai_addrlen) != 0) { 290 if (connect(s, res->ai_addr, res->ai_addrlen) != 0) {
293 goto err; 291 goto err;
294 } 292 }
295 293
296 #ifndef _WIN32 294 socket_blocking(s, 0);
297 //FIXME: Set nonblocking on Windows too
298 fcntl(s, F_SETFL, O_NONBLOCK);
299 #endif
300 mw->sock_fds[channel] = s; 295 mw->sock_fds[channel] = s;
301 mw->channel_state[channel] = SOCKST_TCP_EST; 296 mw->channel_state[channel] = SOCKST_TCP_EST;
302 mw->channel_flags |= 1 << (channel + 1); 297 mw->channel_flags |= 1 << (channel + 1);
303 printf("Connection established on ch %d with %s:%s\n", channel + 1, host, dst_port); 298 printf("Connection established on ch %d with %s:%s\n", channel + 1, host, dst_port);
304 299
434 end_reply(mw); 429 end_reply(mw);
435 break; 430 break;
436 } 431 }
437 channel--; 432 channel--;
438 if (mw->sock_fds[channel] >= 0) { 433 if (mw->sock_fds[channel] >= 0) {
439 close(mw->sock_fds[channel]); 434 socket_close(mw->sock_fds[channel]);
440 } 435 }
441 mw->sock_fds[channel] = socket(AF_INET, SOCK_STREAM, 0); 436 mw->sock_fds[channel] = socket(AF_INET, SOCK_STREAM, 0);
442 if (mw->sock_fds[channel] < 0) { 437 if (mw->sock_fds[channel] < 0) {
443 start_reply(mw, CMD_ERROR); 438 start_reply(mw, CMD_ERROR);
444 end_reply(mw); 439 end_reply(mw);
449 struct sockaddr_in bind_addr; 444 struct sockaddr_in bind_addr;
450 memset(&bind_addr, 0, sizeof(bind_addr)); 445 memset(&bind_addr, 0, sizeof(bind_addr));
451 bind_addr.sin_family = AF_INET; 446 bind_addr.sin_family = AF_INET;
452 bind_addr.sin_port = htons(mw->transmit_buffer[8] << 8 | mw->transmit_buffer[9]); 447 bind_addr.sin_port = htons(mw->transmit_buffer[8] << 8 | mw->transmit_buffer[9]);
453 if (bind(mw->sock_fds[channel], (struct sockaddr *)&bind_addr, sizeof(bind_addr)) != 0) { 448 if (bind(mw->sock_fds[channel], (struct sockaddr *)&bind_addr, sizeof(bind_addr)) != 0) {
454 close(mw->sock_fds[channel]); 449 socket_close(mw->sock_fds[channel]);
455 mw->sock_fds[channel] = -1; 450 mw->sock_fds[channel] = -1;
456 start_reply(mw, CMD_ERROR); 451 start_reply(mw, CMD_ERROR);
457 end_reply(mw); 452 end_reply(mw);
458 break; 453 break;
459 } 454 }
460 int res = listen(mw->sock_fds[channel], 2); 455 int res = listen(mw->sock_fds[channel], 2);
461 start_reply(mw, res ? CMD_ERROR : CMD_OK); 456 start_reply(mw, res ? CMD_ERROR : CMD_OK);
462 if (res) { 457 if (res) {
463 close(mw->sock_fds[channel]); 458 socket_close(mw->sock_fds[channel]);
464 mw->sock_fds[channel] = -1; 459 mw->sock_fds[channel] = -1;
465 } else { 460 } else {
466 mw->channel_flags |= 1 << (channel + 1); 461 mw->channel_flags |= 1 << (channel + 1);
467 mw->channel_state[channel] = SOCKST_TCP_LISTEN; 462 mw->channel_state[channel] = SOCKST_TCP_LISTEN;
468 #ifndef _WIN32 463 socket_blocking(mw->sock_fds[channel], 0);
469 //FIXME: Set nonblocking on Windows too
470 fcntl(mw->sock_fds[channel], F_SETFL, O_NONBLOCK);
471 #endif
472 } 464 }
473 end_reply(mw); 465 end_reply(mw);
474 break; 466 break;
475 } 467 }
476 case CMD_SOCK_STAT: { 468 case CMD_SOCK_STAT: {
509 cmd_hrng_get(mw); 501 cmd_hrng_get(mw);
510 break; 502 break;
511 case CMD_SERVER_URL_GET: 503 case CMD_SERVER_URL_GET:
512 start_reply(mw, CMD_OK); 504 start_reply(mw, CMD_OK);
513 // FIXME: This should be get from config file 505 // FIXME: This should be get from config file
514 mw_puts(mw, "192.168.1.32"); 506 mw_puts(mw, "doragasu.com");
515 end_reply(mw); 507 end_reply(mw);
516 break; 508 break;
517 default: 509 default:
518 printf("Unhandled MegaWiFi command %s(%d) with length %X\n", cmd_names[command], command, size); 510 printf("Unhandled MegaWiFi command %s(%d) with length %X\n", cmd_names[command], command, size);
519 break; 511 break;
528 uint8_t channel = mw->transmit_channel - 1; 520 uint8_t channel = mw->transmit_channel - 1;
529 int channel_state = mw->channel_state[channel]; 521 int channel_state = mw->channel_state[channel];
530 int sock_fd = mw->sock_fds[channel]; 522 int sock_fd = mw->sock_fds[channel];
531 // TODO Handle UDP type sockets 523 // TODO Handle UDP type sockets
532 if (sock_fd >= 0 && channel_state == SOCKST_TCP_EST) { 524 if (sock_fd >= 0 && channel_state == SOCKST_TCP_EST) {
533 int sent = send(sock_fd, mw->transmit_buffer, mw->transmit_bytes, MSG_NOSIGNAL); 525 int sent = send(sock_fd, (char*)mw->transmit_buffer, mw->transmit_bytes, 0);
534 if (sent < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { 526 if (sent < 0 && !socket_error_is_wouldblock()) {
535 close(sock_fd); 527 socket_close(sock_fd);
536 mw->sock_fds[channel] = -1; 528 mw->sock_fds[channel] = -1;
537 mw->channel_state[channel] = SOCKST_NONE; 529 mw->channel_state[channel] = SOCKST_NONE;
538 mw->channel_flags |= 1 << mw->transmit_channel; 530 mw->channel_flags |= 1 << mw->transmit_channel;
539 } else if (sent < mw->transmit_bytes) { 531 } else if (sent < mw->transmit_bytes) {
540 //TODO: save this data somewhere so it can be sent in poll_socket 532 //TODO: save this data somewhere so it can be sent in poll_socket