Mercurial > repos > blastem
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 |