diff options
Diffstat (limited to 'minion/src/wifi_module.cpp')
-rw-r--r-- | minion/src/wifi_module.cpp | 162 |
1 files changed, 123 insertions, 39 deletions
diff --git a/minion/src/wifi_module.cpp b/minion/src/wifi_module.cpp index 8b04b70..065bcdf 100644 --- a/minion/src/wifi_module.cpp +++ b/minion/src/wifi_module.cpp @@ -146,7 +146,7 @@ void WiFiModule::create_tcp_server(size_t port) noexcept char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; - _read(TIMEOUT_LONG, response); + _read(TIMEOUT_MEDIUM, response); // Serial.println(response); } @@ -191,6 +191,8 @@ auto WiFiModule::get_local_ip(char *local_ip_out) noexcept -> const char * return local_ip_out; } + strcpy(buf, ""); + const auto response_status = _read(10000U, buf); if (response_status != ResponseStatus::OK) @@ -206,7 +208,7 @@ auto WiFiModule::get_local_ip(char *local_ip_out) noexcept -> const char * return local_ip_out; } - const auto *local_ip_end = strstr(buf, "\r\n+CIFSR:STAMAC"); + const auto local_ip_end = strstr(buf, "\r\n+CIFSR:STAMAC"); if (local_ip_end == nullptr) { @@ -224,15 +226,15 @@ auto WiFiModule::get_local_ip(char *local_ip_out) noexcept -> const char * return local_ip_out; } -auto WiFiModule::has_incoming_request() noexcept -> bool +auto WiFiModule::read_incoming_request() noexcept -> HTTPRequest * { char request_prefix[] = "+IPD,"; - return get_available() != 0 && _serial.find(request_prefix); -} + if (get_available() == 0 || !_serial.find(request_prefix)) + { + return nullptr; + } -auto WiFiModule::read_incoming_request(char *raw_request_out) noexcept -> size_t -{ const auto min_available_bytes = 5; // Wait for the data buffer a bit @@ -240,41 +242,50 @@ auto WiFiModule::read_incoming_request(char *raw_request_out) noexcept -> size_t { } - const auto connection_id = _serial.read() - ASCII_TO_CHAR; + const auto connection_id = _read_connection_id(); - // Skip the comma - _serial.read(); + auto request_data_length = _read_request_data_length(); - char data_length_buf[16] = { '\0' }; + const auto request_method = _read_request_method(request_data_length); - _read_buffer(&data_length_buf[0], sizeof(data_length_buf) - 1, ':'); + // Read request path + char request_path[REQUEST_PATH_MAX_LENGTH] = ""; + _read_to(&request_path[0], sizeof(request_path) - 1U, ' ', TIMEOUT_MEDIUM); - auto data_length = atoi(data_length_buf); + request_data_length -= strlen(request_path) + 1U; - Serial.print("Data length: "); - Serial.println(data_length); + // Read request HTTP version + char http_version[REQUEST_HTTP_VERSION_MAX_LENGTH] = ""; + _read_to(&http_version[0], sizeof(http_version) - 1U, '\r', TIMEOUT_MEDIUM); - auto read_bytes = 0; - const auto start_time = millis(); + request_data_length -= strlen(http_version) + 1U; - while (read_bytes != data_length && (start_time + 10000) > millis()) + // Skip the newline + while (get_available() == 0) { - if (get_available() == 0) - { - continue; - } - - char character = _read_byte(); + } + _serial.read(); + request_data_length -= 1U; - strncat(raw_request_out, &character, 1U); + auto request_data = util::malloc<char>(request_data_length + 1U); - read_bytes++; + if (request_data == nullptr) + { + return nullptr; } - // Skip the comma at the beginning - raw_request_out++; + strcpy(request_data, ""); - return connection_id; + _read_bytes(request_data, request_data_length, TIMEOUT_LONG); + + return new HTTPRequest( + connection_id, + request_method, + http_version, + request_path, + request_data_length, + request_data + ); } auto WiFiModule::close_connection(size_t connection_id) noexcept -> bool @@ -340,13 +351,13 @@ auto WiFiModule::send(size_t connection_id, const char *data) noexcept -> bool char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; - _read(TIMEOUT_LONG, response); + _read(TIMEOUT_MEDIUM, response); _serial.print(data); strcpy(response, ""); - _read(TIMEOUT_LONG, response); + _read(TIMEOUT_MEDIUM, response); return true; } @@ -374,6 +385,43 @@ auto WiFiModule::_send_serial(const char *command) noexcept -> bool return true; } +size_t WiFiModule::_read_connection_id() noexcept +{ + const auto connection_id = _serial.read() - ASCII_TO_CHAR; + + // Skip the comma + _serial.read(); + + return connection_id; +} + +size_t WiFiModule::_read_request_data_length() noexcept +{ + char data_length_buf[REQUEST_DATA_LENGTH_BUF_SIZE] = ""; + + _read_to(&data_length_buf[0], sizeof(data_length_buf) - 1U, ':', TIMEOUT_SHORT); + + return static_cast<size_t>(strtoul(data_length_buf, nullptr, 10)); +} + +HTTPRequestMethod WiFiModule::_read_request_method(size_t &request_data_length) noexcept +{ + char request_method_buf[REQUEST_METHOD_STR_MAX_LENGTH] = ""; + + _read_to( + &request_method_buf[0], + sizeof(request_method_buf) - 1U, + ' ', + TIMEOUT_MEDIUM + ); + + const auto request_method = str_to_http_request_method(request_method_buf); + + request_data_length -= strlen(request_method_buf) + 1U; + + return request_method; +} + auto WiFiModule::_read(uint64_t timeout, char *response_out) noexcept -> ResponseStatus { const auto start_time = millis(); @@ -381,8 +429,6 @@ auto WiFiModule::_read(uint64_t timeout, char *response_out) noexcept -> Respons bool has_end = false; auto status = ResponseStatus::TIMEOUT; - // auto *response_out_head = response_out; - while (!has_end && (start_time + timeout) > millis()) { while (_serial.available() != 0) @@ -391,9 +437,6 @@ auto WiFiModule::_read(uint64_t timeout, char *response_out) noexcept -> Respons strncat(response_out, &character, 1U); - // *response_out_head = character; - // response_out_head++; - if (util::str_ends_with(response_out, "OK")) { status = ResponseStatus::OK; @@ -417,16 +460,29 @@ auto WiFiModule::_read(uint64_t timeout, char *response_out) noexcept -> Respons return status; } -void WiFiModule::_read_buffer(char *buffer_out, size_t length, char stop_char) noexcept +void WiFiModule::_read_to( + char *buffer_out, + size_t length, // NOLINT(bugprone-easily-swappable-parameters) + char stop_char, + uint64_t timeout +) noexcept { - byte position = 0; + auto position = 0U; + const auto start_time = millis(); - while (get_available() != 0 && position < length) + while (position < length && (start_time + timeout) > millis()) { + if (get_available() == 0) + { + continue; + } + auto character = _read_byte(); if (character == stop_char) + { break; + } buffer_out[position++] = character; } @@ -434,6 +490,34 @@ void WiFiModule::_read_buffer(char *buffer_out, size_t length, char stop_char) n buffer_out[position] = '\0'; } +// NOLINTNEXTLINE(bugprone-easily-swappable-parameters) +void WiFiModule::_read_bytes(char *buffer_out, size_t length, uint64_t timeout) noexcept +{ + const auto original_length = length; + + auto position = 0U; + const auto start_time = millis(); + + while (position != length && (start_time + timeout) > millis()) + { + if (get_available() == 0) + { + continue; + } + + char character = _read_byte(); + + buffer_out[position++] = character; + + if (character == '\n' && position != original_length) + { + length -= 2U; + } + } + + buffer_out[position] = '\0'; +} + auto WiFiModule::_read_byte() noexcept -> char { return static_cast<char>(_serial.read()); |