From d85bd0c9435bbcab8b63b07652a01e4e5a4a6eaf Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Mon, 15 Jan 2018 09:04:43 -0800 Subject: Initial work on MegaWiFi support --- megawifi.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 megawifi.c (limited to 'megawifi.c') diff --git a/megawifi.c b/megawifi.c new file mode 100644 index 0000000..17270c2 --- /dev/null +++ b/megawifi.c @@ -0,0 +1,238 @@ +#include +#include +#include +#include "genesis.h" + +enum { + TX_IDLE, + TX_LEN1, + TX_LEN2, + TX_PAYLOAD, + TX_WAIT_ETX +}; +#define STX 0x7E +#define ETX 0x7E + +#define E(N) N +enum { +#include "mw_commands.c" + CMD_ERROR = 255 +}; +#undef E +#define E(N) #N +static const char *cmd_names[] = { +#include "mw_commands.c" + [255] = "CMD_ERROR" +}; + +enum { + STATE_IDLE=1, + STATE_AP_JOIN, + STATE_SCAN, + STATE_READY, + STATE_TRANSPARENT +}; + +#define FLAG_ONLINE + +typedef struct { + uint32_t transmit_bytes; + uint32_t expected_bytes; + uint32_t receive_bytes; + uint32_t receive_read; + uint16_t channel_flags; + uint8_t scratchpad; + uint8_t transmit_channel; + uint8_t transmit_state; + uint8_t module_state; + uint8_t flags; + uint8_t transmit_buffer[4096]; + uint8_t receive_buffer[4096]; +} megawifi; + +static megawifi *get_megawifi(void *context) +{ + m68k_context *m68k = context; + genesis_context *gen = m68k->system; + if (!gen->extra) { + gen->extra = calloc(1, sizeof(megawifi)); + ((megawifi *)gen->extra)->module_state = STATE_IDLE; + } + return gen->extra; +} + +static void mw_putc(megawifi *mw, uint8_t v) +{ + if (mw->receive_bytes == sizeof(mw->receive_buffer)) { + return; + } + mw->receive_buffer[mw->receive_bytes++] = v; +} + +static void mw_puts(megawifi *mw, char *s) +{ + uint32_t len = strlen(s); + if ((mw->receive_bytes + len) > sizeof(mw->receive_buffer)) { + return; + } + memcpy(mw->receive_buffer + mw->receive_bytes, s, len); + mw->receive_bytes += len; +} + +static void process_packet(megawifi *mw) +{ + if (mw->transmit_channel == 0) { + uint32_t command = mw->transmit_buffer[0] << 8 | mw->transmit_buffer[1]; + uint32_t size = mw->transmit_buffer[2] << 8 | mw->transmit_buffer[3]; + if (size > mw->transmit_bytes - 4) { + size = mw->transmit_bytes - 4; + } + mw->receive_read = mw->receive_bytes = 0; + switch (command) + { + case CMD_VERSION: + //LSD header + mw_putc(mw, 0x7E); + mw_putc(mw, 0); + mw->receive_bytes += 1; //reserve space for LSB of len + //cmd + mw_putc(mw, 0); + mw_putc(mw, CMD_OK); + //length + mw_putc(mw, 0); + mw->receive_bytes += 1; //reserve space for LSB of len + mw_putc(mw, 1); + mw_putc(mw, 0); + mw_puts(mw, "blastem"); + mw->receive_buffer[2] = mw->receive_bytes - 3; + mw->receive_buffer[6] = mw->receive_bytes - 7; + mw_putc(mw, 0x7E); + break; + case CMD_ECHO: + mw->receive_bytes = mw->transmit_bytes; + memcpy(mw->receive_buffer, mw->transmit_buffer, mw->transmit_bytes); + break; + case CMD_AP_JOIN: + mw->module_state = STATE_READY; + mw_putc(mw, 0x7E); + mw_putc(mw, 0); + mw_putc(mw, 4); + //cmd + mw_putc(mw, 0); + mw_putc(mw, CMD_OK); + //length + mw_putc(mw, 0); + mw_putc(mw, 0); + mw_putc(mw, 0x7E); + break; + case CMD_SYS_STAT: + //LSD header + mw_putc(mw, 0x7E); + mw_putc(mw, 0); + mw_putc(mw, 8); + //cmd + mw_putc(mw, 0); + mw_putc(mw, CMD_OK); + //length + mw_putc(mw, 0); + mw_putc(mw, 4); + mw_putc(mw, mw->module_state); + mw_putc(mw, mw->flags); + mw_putc(mw, mw->channel_flags >> 8); + mw_putc(mw, mw->channel_flags); + mw_putc(mw, 0x7E); + break; + default: + printf("Unhandled MegaWiFi command %s(%d) with length %X\n", cmd_names[command], command, size); + break; + } + } else { + printf("Unhandled receive of MegaWiFi data on channel %d\n", mw->transmit_channel); + } + mw->transmit_bytes = mw->expected_bytes = 0; +} + +void *megawifi_write_b(uint32_t address, void *context, uint8_t value) +{ + if (!(address & 1)) { + return context; + } + megawifi *mw = get_megawifi(context); + address = address >> 1 & 7; + switch (address) + { + case 0: + switch (mw->transmit_state) + { + case TX_IDLE: + if (value == STX) { + mw->transmit_state = TX_LEN1; + } + break; + case TX_LEN1: + mw->transmit_channel = value >> 4; + mw->expected_bytes = value << 8 & 0xF00; + mw->transmit_state = TX_LEN2; + break; + case TX_LEN2: + mw->expected_bytes |= value; + mw->transmit_state = TX_PAYLOAD; + break; + case TX_PAYLOAD: + mw->transmit_buffer[mw->transmit_bytes++] = value; + if (mw->transmit_bytes == mw->expected_bytes) { + mw->transmit_state = TX_WAIT_ETX; + } + break; + case TX_WAIT_ETX: + if (value == ETX) { + mw->transmit_state = TX_IDLE; + process_packet(mw); + } + break; + } + break; + case 7: + mw->scratchpad = value; + break; + default: + printf("Unhandled write to MegaWiFi UART register %X: %X\n", address, value); + } + return context; +} + +void *megawifi_write_w(uint32_t address, void *context, uint16_t value) +{ + return megawifi_write_b(address | 1, context, value); +} + +uint8_t megawifi_read_b(uint32_t address, void *context) +{ + + if (!(address & 1)) { + return 0xFF; + } + megawifi *mw = get_megawifi(context); + address = address >> 1 & 7; + switch (address) + { + case 0: + if (mw->receive_read < mw->receive_bytes) { + return mw->receive_buffer[mw->receive_read++]; + } + return 0xFF; + case 5: + //line status + return 0x60 | (mw->receive_read < mw->receive_bytes); + case 7: + return mw->scratchpad; + default: + printf("Unhandled read from MegaWiFi UART register %X\n", address); + return 0xFF; + } +} + +uint16_t megawifi_read_w(uint32_t address, void *context) +{ + return 0xFF00 | megawifi_read_b(address | 1, context); +} -- cgit v1.2.3 From ea2646501e91437345afd1cfc85704dd1f983d66 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Tue, 16 Jan 2018 09:31:00 -0800 Subject: Added support for MegaWiFi command IP_CURRENT --- megawifi.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'megawifi.c') diff --git a/megawifi.c b/megawifi.c index 17270c2..898bc8a 100644 --- a/megawifi.c +++ b/megawifi.c @@ -2,6 +2,7 @@ #include #include #include "genesis.h" +#include "net.h" enum { TX_IDLE, @@ -88,6 +89,7 @@ static void process_packet(megawifi *mw) size = mw->transmit_bytes - 4; } mw->receive_read = mw->receive_bytes = 0; + printf("Received MegaWiFi command %s(%d) with length %X\n", cmd_names[command], command, size); switch (command) { case CMD_VERSION: @@ -142,6 +144,52 @@ static void process_packet(megawifi *mw) mw_putc(mw, mw->channel_flags); mw_putc(mw, 0x7E); break; + case CMD_IP_CURRENT: { + //LSD header + mw_putc(mw, 0x7E); + mw_putc(mw, 0); + mw_putc(mw, 28); + //cmd + mw_putc(mw, 0); + mw_putc(mw, CMD_OK); + //length + mw_putc(mw, 0); + mw_putc(mw, 24); + + iface_info i; + get_host_address(&i); + //config number and reserved bytes + mw_putc(mw, 0); + mw_putc(mw, 0); + mw_putc(mw, 0); + mw_putc(mw, 0); + //ip + mw_putc(mw, i.ip[0]); + mw_putc(mw, i.ip[1]); + mw_putc(mw, i.ip[2]); + mw_putc(mw, i.ip[3]); + //net mask + mw_putc(mw, i.net_mask[0]); + mw_putc(mw, i.net_mask[1]); + mw_putc(mw, i.net_mask[2]); + mw_putc(mw, i.net_mask[3]); + //gateway guess + mw_putc(mw, i.ip[0] & i.net_mask[0]); + mw_putc(mw, i.ip[1] & i.net_mask[1]); + mw_putc(mw, i.ip[2] & i.net_mask[2]); + mw_putc(mw, (i.ip[3] & i.net_mask[3]) + 1); + //dns + mw_putc(mw, 127); + mw_putc(mw, 0); + mw_putc(mw, 0); + mw_putc(mw, 1); + mw_putc(mw, 127); + mw_putc(mw, 0); + mw_putc(mw, 0); + mw_putc(mw, 1); + mw_putc(mw, 0x7E); + break; + } default: printf("Unhandled MegaWiFi command %s(%d) with length %X\n", cmd_names[command], command, size); break; -- cgit v1.2.3 From 37f06c25a346b455d0cb131ab6643785d603537d Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Tue, 16 Jan 2018 19:21:37 -0800 Subject: Cleanup MegaWiFi command implementation --- megawifi.c | 148 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 71 insertions(+), 77 deletions(-) (limited to 'megawifi.c') diff --git a/megawifi.c b/megawifi.c index 898bc8a..d9fa6e2 100644 --- a/megawifi.c +++ b/megawifi.c @@ -70,6 +70,24 @@ static void mw_putc(megawifi *mw, uint8_t v) mw->receive_buffer[mw->receive_bytes++] = v; } +static void mw_set(megawifi *mw, uint8_t val, uint32_t count) +{ + if (count + mw->receive_bytes > sizeof(mw->receive_buffer)) { + count = sizeof(mw->receive_buffer) - mw->receive_bytes; + } + memset(mw->receive_buffer + mw->receive_bytes, val, count); + mw->receive_bytes += count; +} + +static void mw_copy(megawifi *mw, const uint8_t *src, uint32_t count) +{ + if (count + mw->receive_bytes > sizeof(mw->receive_buffer)) { + count = sizeof(mw->receive_buffer) - mw->receive_bytes; + } + memcpy(mw->receive_buffer + mw->receive_bytes, src, count); + mw->receive_bytes += count; +} + static void mw_puts(megawifi *mw, char *s) { uint32_t len = strlen(s); @@ -80,6 +98,31 @@ static void mw_puts(megawifi *mw, char *s) mw->receive_bytes += len; } +static void start_reply(megawifi *mw, uint8_t cmd) +{ + mw_putc(mw, STX); + //reserve space for length + mw->receive_bytes += 2; + //cmd + mw_putc(mw, 0); + mw_putc(mw, cmd); + //reserve space for length + mw->receive_bytes += 2; +} + +static void end_reply(megawifi *mw) +{ + uint32_t len = mw->receive_bytes - 3; + //LSD packet length + mw->receive_buffer[1] = len >> 8; + mw->receive_buffer[2] = len; + //command length + len -= 4; + mw->receive_buffer[5] = len >> 8; + mw->receive_buffer[6] = len; + mw_putc(mw, ETX); +} + static void process_packet(megawifi *mw) { if (mw->transmit_channel == 0) { @@ -89,26 +132,14 @@ static void process_packet(megawifi *mw) size = mw->transmit_bytes - 4; } mw->receive_read = mw->receive_bytes = 0; - printf("Received MegaWiFi command %s(%d) with length %X\n", cmd_names[command], command, size); switch (command) { case CMD_VERSION: - //LSD header - mw_putc(mw, 0x7E); - mw_putc(mw, 0); - mw->receive_bytes += 1; //reserve space for LSB of len - //cmd - mw_putc(mw, 0); - mw_putc(mw, CMD_OK); - //length - mw_putc(mw, 0); - mw->receive_bytes += 1; //reserve space for LSB of len + start_reply(mw, CMD_OK); mw_putc(mw, 1); mw_putc(mw, 0); mw_puts(mw, "blastem"); - mw->receive_buffer[2] = mw->receive_bytes - 3; - mw->receive_buffer[6] = mw->receive_bytes - 7; - mw_putc(mw, 0x7E); + end_reply(mw); break; case CMD_ECHO: mw->receive_bytes = mw->transmit_bytes; @@ -116,78 +147,41 @@ static void process_packet(megawifi *mw) break; case CMD_AP_JOIN: mw->module_state = STATE_READY; - mw_putc(mw, 0x7E); - mw_putc(mw, 0); - mw_putc(mw, 4); - //cmd - mw_putc(mw, 0); - mw_putc(mw, CMD_OK); - //length - mw_putc(mw, 0); - mw_putc(mw, 0); - mw_putc(mw, 0x7E); + start_reply(mw, CMD_OK); + end_reply(mw); break; case CMD_SYS_STAT: - //LSD header - mw_putc(mw, 0x7E); - mw_putc(mw, 0); - mw_putc(mw, 8); - //cmd - mw_putc(mw, 0); - mw_putc(mw, CMD_OK); - //length - mw_putc(mw, 0); - mw_putc(mw, 4); + start_reply(mw, CMD_OK); mw_putc(mw, mw->module_state); mw_putc(mw, mw->flags); mw_putc(mw, mw->channel_flags >> 8); mw_putc(mw, mw->channel_flags); - mw_putc(mw, 0x7E); + end_reply(mw); break; case CMD_IP_CURRENT: { - //LSD header - mw_putc(mw, 0x7E); - mw_putc(mw, 0); - mw_putc(mw, 28); - //cmd - mw_putc(mw, 0); - mw_putc(mw, CMD_OK); - //length - mw_putc(mw, 0); - mw_putc(mw, 24); - iface_info i; - get_host_address(&i); - //config number and reserved bytes - mw_putc(mw, 0); - mw_putc(mw, 0); - mw_putc(mw, 0); - mw_putc(mw, 0); - //ip - mw_putc(mw, i.ip[0]); - mw_putc(mw, i.ip[1]); - mw_putc(mw, i.ip[2]); - mw_putc(mw, i.ip[3]); - //net mask - mw_putc(mw, i.net_mask[0]); - mw_putc(mw, i.net_mask[1]); - mw_putc(mw, i.net_mask[2]); - mw_putc(mw, i.net_mask[3]); - //gateway guess - mw_putc(mw, i.ip[0] & i.net_mask[0]); - mw_putc(mw, i.ip[1] & i.net_mask[1]); - mw_putc(mw, i.ip[2] & i.net_mask[2]); - mw_putc(mw, (i.ip[3] & i.net_mask[3]) + 1); - //dns - mw_putc(mw, 127); - mw_putc(mw, 0); - mw_putc(mw, 0); - mw_putc(mw, 1); - mw_putc(mw, 127); - mw_putc(mw, 0); - mw_putc(mw, 0); - mw_putc(mw, 1); - mw_putc(mw, 0x7E); + if (get_host_address(&i)) { + start_reply(mw, CMD_OK); + //config number and reserved bytes + mw_set(mw, 0, 4); + //ip + mw_copy(mw, i.ip, sizeof(i.ip)); + //net mask + mw_copy(mw, i.net_mask, sizeof(i.net_mask)); + //gateway guess + mw_putc(mw, i.ip[0] & i.net_mask[0]); + mw_putc(mw, i.ip[1] & i.net_mask[1]); + mw_putc(mw, i.ip[2] & i.net_mask[2]); + mw_putc(mw, (i.ip[3] & i.net_mask[3]) + 1); + //dns + static const uint8_t localhost[] = {127,0,0,1}; + mw_copy(mw, localhost, sizeof(localhost)); + mw_copy(mw, localhost, sizeof(localhost)); + + } else { + start_reply(mw, CMD_ERROR); + } + end_reply(mw); break; } default: -- cgit v1.2.3 From 05fcf797a7f77537f18c760dfb0bec783dbd9981 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Mon, 22 Jan 2018 22:02:29 -0800 Subject: Get enough of MegaWifi implemented so that basic commands from wflash CLI command work --- megawifi.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 159 insertions(+), 16 deletions(-) (limited to 'megawifi.c') diff --git a/megawifi.c b/megawifi.c index d9fa6e2..23b2530 100644 --- a/megawifi.c +++ b/megawifi.c @@ -1,6 +1,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include "genesis.h" #include "net.h" @@ -41,7 +47,9 @@ typedef struct { uint32_t expected_bytes; uint32_t receive_bytes; uint32_t receive_read; + int sock_fds[15]; uint16_t channel_flags; + uint8_t channel_state[15]; uint8_t scratchpad; uint8_t transmit_channel; uint8_t transmit_state; @@ -57,7 +65,12 @@ static megawifi *get_megawifi(void *context) genesis_context *gen = m68k->system; if (!gen->extra) { gen->extra = calloc(1, sizeof(megawifi)); - ((megawifi *)gen->extra)->module_state = STATE_IDLE; + megawifi *mw = gen->extra; + mw->module_state = STATE_IDLE; + for (int i = 0; i < 15; i++) + { + mw->sock_fds[i] = -1; + } } return gen->extra; } @@ -98,6 +111,54 @@ static void mw_puts(megawifi *mw, char *s) mw->receive_bytes += len; } +static void poll_socket(megawifi *mw, uint8_t channel) +{ + if (mw->sock_fds[channel] < 0) { + return; + } + if (mw->channel_state[channel] == 1) { + int res = accept(mw->sock_fds[channel], NULL, NULL); + if (res >= 0) { + close(mw->sock_fds[channel]); + fcntl(res, F_SETFL, O_NONBLOCK); + mw->sock_fds[channel] = res; + mw->channel_state[channel] = 2; + mw->channel_flags |= 1 << (channel + 1); + } else if (errno != EAGAIN && errno != EWOULDBLOCK) { + close(mw->sock_fds[channel]); + mw->channel_state[channel] = 0; + mw->channel_flags |= 1 << (channel + 1); + } + } else if (mw->channel_state[channel] == 2 && mw->receive_bytes < sizeof(mw->receive_buffer) - 4) { + int bytes = recv( + mw->sock_fds[channel], + mw->receive_buffer + mw->receive_bytes + 3, + sizeof(mw->receive_buffer) - 4 - mw->receive_bytes, + 0 + ); + if (bytes > 0) { + mw_putc(mw, STX); + mw_putc(mw, bytes >> 8 | (channel+1) << 4); + mw_putc(mw, bytes); + mw->receive_bytes += bytes; + mw_putc(mw, ETX); + //should this set the channel flag? + } else if (bytes < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + close(mw->sock_fds[channel]); + mw->channel_state[channel] = 0; + mw->channel_flags |= 1 << (channel + 1); + } + } +} + +static void poll_all_sockets(megawifi *mw) +{ + for (int i = 0; i < 15; i++) + { + poll_socket(mw, i); + } +} + static void start_reply(megawifi *mw, uint8_t cmd) { mw_putc(mw, STX); @@ -131,7 +192,7 @@ static void process_packet(megawifi *mw) if (size > mw->transmit_bytes - 4) { size = mw->transmit_bytes - 4; } - mw->receive_read = mw->receive_bytes = 0; + int orig_receive_bytes = mw->receive_bytes; switch (command) { case CMD_VERSION: @@ -145,19 +206,6 @@ static void process_packet(megawifi *mw) mw->receive_bytes = mw->transmit_bytes; memcpy(mw->receive_buffer, mw->transmit_buffer, mw->transmit_bytes); break; - case CMD_AP_JOIN: - mw->module_state = STATE_READY; - start_reply(mw, CMD_OK); - end_reply(mw); - break; - case CMD_SYS_STAT: - start_reply(mw, CMD_OK); - mw_putc(mw, mw->module_state); - mw_putc(mw, mw->flags); - mw_putc(mw, mw->channel_flags >> 8); - mw_putc(mw, mw->channel_flags); - end_reply(mw); - break; case CMD_IP_CURRENT: { iface_info i; if (get_host_address(&i)) { @@ -184,10 +232,99 @@ static void process_packet(megawifi *mw) end_reply(mw); break; } + case CMD_AP_JOIN: + mw->module_state = STATE_READY; + start_reply(mw, CMD_OK); + end_reply(mw); + break; + case CMD_TCP_BIND:{ + if (size < 7){ + start_reply(mw, CMD_ERROR); + end_reply(mw); + break; + } + uint8_t channel = mw->transmit_buffer[10]; + if (!channel || channel > 15) { + start_reply(mw, CMD_ERROR); + end_reply(mw); + break; + } + channel--; + if (mw->sock_fds[channel] >= 0) { + close(mw->sock_fds[channel]); + } + mw->sock_fds[channel] = socket(AF_INET, SOCK_STREAM, 0); + if (mw->sock_fds[channel] < 0) { + start_reply(mw, CMD_ERROR); + end_reply(mw); + break; + } + int value = 1; + setsockopt(mw->sock_fds[channel], SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)); + struct sockaddr_in bind_addr; + memset(&bind_addr, 0, sizeof(bind_addr)); + bind_addr.sin_family = AF_INET; + bind_addr.sin_port = htons(mw->transmit_buffer[8] << 8 | mw->transmit_buffer[9]); + if (bind(mw->sock_fds[channel], (struct sockaddr *)&bind_addr, sizeof(bind_addr)) != 0) { + close(mw->sock_fds[channel]); + mw->sock_fds[channel] = -1; + start_reply(mw, CMD_ERROR); + end_reply(mw); + break; + } + int res = listen(mw->sock_fds[channel], 2); + start_reply(mw, res ? CMD_ERROR : CMD_OK); + if (res) { + close(mw->sock_fds[channel]); + mw->sock_fds[channel] = -1; + } else { + mw->channel_flags |= 1 << (channel + 1); + mw->channel_state[channel] = 1; + fcntl(mw->sock_fds[channel], F_SETFL, O_NONBLOCK); + } + end_reply(mw); + break; + } + case CMD_SOCK_STAT: { + uint8_t channel = mw->transmit_buffer[4]; + if (!channel || channel > 15) { + start_reply(mw, CMD_ERROR); + end_reply(mw); + break; + } + mw->channel_flags &= ~(1 << channel); + channel--; + poll_socket(mw, channel); + start_reply(mw, CMD_OK); + mw_putc(mw, mw->channel_state[channel]); + end_reply(mw); + break; + } + case CMD_SYS_STAT: + poll_all_sockets(mw); + start_reply(mw, CMD_OK); + mw_putc(mw, mw->module_state); + mw_putc(mw, mw->flags); + mw_putc(mw, mw->channel_flags >> 8); + mw_putc(mw, mw->channel_flags); + end_reply(mw); + break; default: printf("Unhandled MegaWiFi command %s(%d) with length %X\n", cmd_names[command], command, size); break; } + } else if (mw->sock_fds[mw->transmit_channel - 1] >= 0 && mw->channel_state[mw->transmit_channel - 1] == 2) { + uint8_t channel = mw->transmit_channel - 1; + int sent = send(mw->sock_fds[channel], mw->transmit_buffer, mw->transmit_bytes, 0); + if (sent < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + close(mw->sock_fds[channel]); + mw->sock_fds[channel] = -1; + mw->channel_state[channel] = 0; + mw->channel_flags |= 1 << mw->transmit_channel; + } else if (sent < mw->transmit_bytes) { + //TODO: save this data somewhere so it can be sent in poll_socket + printf("Sent %d bytes on channel %d, but %d were requested\n", sent, mw->transmit_channel, mw->transmit_bytes); + } } else { printf("Unhandled receive of MegaWiFi data on channel %d\n", mw->transmit_channel); } @@ -259,11 +396,17 @@ uint8_t megawifi_read_b(uint32_t address, void *context) switch (address) { case 0: + poll_all_sockets(mw); if (mw->receive_read < mw->receive_bytes) { - return mw->receive_buffer[mw->receive_read++]; + uint8_t ret = mw->receive_buffer[mw->receive_read++]; + if (mw->receive_read == mw->receive_bytes) { + mw->receive_read = mw->receive_bytes = 0; + } + return ret; } return 0xFF; case 5: + poll_all_sockets(mw); //line status return 0x60 | (mw->receive_read < mw->receive_bytes); case 7: -- cgit v1.2.3 From aeb32eebf529a82a624f2c88f51a7706aad0bcc5 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Wed, 31 Jan 2018 21:59:08 -0800 Subject: Limit received LSD packets to 1440 bytes to match expectations of wflash code. Use MSG_NOSIGNAL to avoid getting killed with SIGPIPE --- megawifi.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'megawifi.c') diff --git a/megawifi.c b/megawifi.c index 23b2530..a0adfba 100644 --- a/megawifi.c +++ b/megawifi.c @@ -19,6 +19,7 @@ enum { }; #define STX 0x7E #define ETX 0x7E +#define MAX_RECV_SIZE 1440 #define E(N) N enum { @@ -130,12 +131,11 @@ static void poll_socket(megawifi *mw, uint8_t channel) mw->channel_flags |= 1 << (channel + 1); } } else if (mw->channel_state[channel] == 2 && mw->receive_bytes < sizeof(mw->receive_buffer) - 4) { - int bytes = recv( - mw->sock_fds[channel], - mw->receive_buffer + mw->receive_bytes + 3, - sizeof(mw->receive_buffer) - 4 - mw->receive_bytes, - 0 - ); + size_t max = sizeof(mw->receive_buffer) - 4 - mw->receive_bytes; + if (max > MAX_RECV_SIZE) { + max = MAX_RECV_SIZE; + } + int bytes = recv(mw->sock_fds[channel], mw->receive_buffer + mw->receive_bytes + 3, max, 0); if (bytes > 0) { mw_putc(mw, STX); mw_putc(mw, bytes >> 8 | (channel+1) << 4); @@ -315,7 +315,7 @@ static void process_packet(megawifi *mw) } } else if (mw->sock_fds[mw->transmit_channel - 1] >= 0 && mw->channel_state[mw->transmit_channel - 1] == 2) { uint8_t channel = mw->transmit_channel - 1; - int sent = send(mw->sock_fds[channel], mw->transmit_buffer, mw->transmit_bytes, 0); + int sent = send(mw->sock_fds[channel], mw->transmit_buffer, mw->transmit_bytes, MSG_NOSIGNAL); if (sent < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { close(mw->sock_fds[channel]); mw->sock_fds[channel] = -1; -- cgit v1.2.3