diff options
Diffstat (limited to 'stm32f091/server.c')
-rw-r--r-- | stm32f091/server.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/stm32f091/server.c b/stm32f091/server.c index aa2ff8b..a06727c 100644 --- a/stm32f091/server.c +++ b/stm32f091/server.c @@ -3,17 +3,46 @@ #include <stdlib.h> #include <string.h> +#include "../shared/protocol.h" #include "esp8266.h" #include "server.h" #include "setup.h" #include "consts.h" static ws_s_server_parser g_ws_server_parser = { - .counter = 0, .last_response = WS_SERVER_RC_NONE, .mode = WS_SERVER_LM_IDLE, + + .current_channel = 0, + .channel_data_length = 0, + .channel_data_counter = 0, + .channel_listen_mode = WS_SERVER_CL_DATA_LENGTH, }; +static ws_s_protocol_req_parser_state* g_ws_protocol_parsers[WS_SERVER_MAX_CHANNELS] = {0}; + + +void ws_server_req_parse_byte(unsigned int channel, uint8_t byte, bool ignore) { + if (ignore) return; + if (channel >= WS_SERVER_MAX_CHANNELS) return; + + if (g_ws_protocol_parsers[channel] == NULL) { + g_ws_protocol_parsers[channel] = ws_protocol_req_parser_alloc(); + } + + ws_protocol_parse_req_byte(g_ws_protocol_parsers[channel], byte); +} + +void ws_server_req_finish(unsigned int channel, bool ignore) { + if (ignore) return; + if (channel >= WS_SERVER_MAX_CHANNELS) return; + + if (g_ws_protocol_parsers[channel] != NULL) { + ws_protocol_req_parser_free(g_ws_protocol_parsers[channel]); + g_ws_protocol_parsers[channel] = NULL; + } +} + // TODO: next_few_bytes_are assumes that the complete search string is in the // buffer, so won't work for buffer cutoffs #define next_few_bytes_are(code) (i + sizeof(code) - 1 < size && strncmp((char*)&data[i], code, sizeof(code) - 1) == 0) @@ -37,7 +66,7 @@ void ws_server_req_incoming(uint8_t* data, size_t size) { if (next_few_bytes_are("OK")) { code_got = true; g_ws_server_parser.last_response = WS_SERVER_RC_OK; - } else if (next_few_bytes_are("ERROR")) { + } else if (next_few_bytes_are("ERROR") || next_few_bytes_are("FAIL")) { code_got = true; g_ws_server_parser.last_response = WS_SERVER_RC_ERR; } else if (next_few_bytes_are("busy p...")) { @@ -55,14 +84,46 @@ void ws_server_req_incoming(uint8_t* data, size_t size) { break; } case WS_SERVER_LM_IPD_LISTENING: { - // +IPD,0,15:last-records 5\n + switch (g_ws_server_parser.channel_listen_mode) { + case WS_SERVER_CL_CHANNEL_ID: { + if (byte == ',') { + g_ws_server_parser.channel_listen_mode = WS_SERVER_CL_DATA_LENGTH; + break; + } + g_ws_server_parser.current_channel *= 10; + g_ws_server_parser.current_channel += byte - '0'; // ascii to int + break; + } + case WS_SERVER_CL_DATA_LENGTH: { + if (byte == ':') { + g_ws_server_parser.channel_listen_mode = WS_SERVER_CL_DATA_READ; + if (g_ws_server_parser.channel_data_length > WS_PROTOCOL_CMD_BUFFER_LEN) + g_ws_server_parser.channel_data_ignore = true; + break; + } + g_ws_server_parser.current_channel *= 10; + g_ws_server_parser.current_channel += byte - '0'; // ascii to int + break; + } + case WS_SERVER_CL_DATA_READ: { + ws_server_req_parse_byte(g_ws_server_parser.current_channel, byte, g_ws_server_parser.channel_data_ignore); + g_ws_server_parser.channel_data_counter++; + if (g_ws_server_parser.channel_data_counter == g_ws_server_parser.channel_data_length) { + g_ws_server_parser.current_channel = 0; + g_ws_server_parser.channel_data_counter = 0; + g_ws_server_parser.channel_data_length = 0; + g_ws_server_parser.channel_listen_mode = WS_SERVER_CL_CHANNEL_ID; + ws_server_req_finish(g_ws_server_parser.current_channel, g_ws_server_parser.channel_data_ignore); + } + break; + } + default: {} + } break; } default: {} } } - - return; } void ws_server_send(uint8_t* data, size_t size) { @@ -72,8 +133,8 @@ void ws_server_send(uint8_t* data, size_t size) { } void ws_server_req_respond(unsigned int channel, uint8_t* data, size_t size) { - uint8_t Tx_close[]="AT+CIPCLOSE=0\r\n"; uint8_t Tx_send[]="AT+CIPSEND=0,LEN:"; + uint8_t Tx_close[]="AT+CIPCLOSE=0\r\n"; return; } |