diff options
author | HampusM <hampus@hampusmat.com> | 2022-05-08 23:04:16 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2022-05-08 23:05:36 +0200 |
commit | eddaed4e597ce2bc7fa179ce6a15b90951579c6e (patch) | |
tree | 0e696aaab4cb24f58582efce1982cce47832cb4f /minion | |
parent | 2809f92eeb8b727e20167fe82e4cb9c3627d4870 (diff) |
feat(minion): implement respond to HTTP requests
Diffstat (limited to 'minion')
-rw-r--r-- | minion/src/gymnasiearbete.cpp | 28 | ||||
-rw-r--r-- | minion/src/wifi_module.cpp | 118 | ||||
-rw-r--r-- | minion/src/wifi_module.hpp | 17 |
3 files changed, 161 insertions, 2 deletions
diff --git a/minion/src/gymnasiearbete.cpp b/minion/src/gymnasiearbete.cpp index 0e1adb5..b3c543a 100644 --- a/minion/src/gymnasiearbete.cpp +++ b/minion/src/gymnasiearbete.cpp @@ -64,6 +64,32 @@ void setup() Serial.print("IP address: "); Serial.println(wifi_module.get_local_ip(local_ip)); + + wifi_module.set_multiple_connections_enabled(true); + + delay(1000); + + wifi_module.create_tcp_server(80U); } -void loop() {} +void loop() +{ + if (wifi_module.has_incoming_request()) + { + char raw_request[200] = ""; + + const auto connection_id = wifi_module.read_incoming_request(raw_request); + + Serial.print("Connection ID: "); + Serial.println(connection_id); + + Serial.print("\nRaw request: "); + Serial.println(raw_request); + + wifi_module.send(connection_id, "lmao!"); + + wifi_module.close_connection(connection_id); + + delay(1000); + } +} diff --git a/minion/src/wifi_module.cpp b/minion/src/wifi_module.cpp index 2e25dc9..718065d 100644 --- a/minion/src/wifi_module.cpp +++ b/minion/src/wifi_module.cpp @@ -162,7 +162,7 @@ void WiFiModule::create_tcp_server(size_t port) noexcept char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; - _read(1500U, response); + _read(4000U, response); // Serial.println(response); } @@ -240,6 +240,122 @@ const char *WiFiModule::get_local_ip(char *local_ip_out) noexcept return local_ip_out; } +bool WiFiModule::has_incoming_request() noexcept +{ + return get_available() != 0 && _serial.find("+IPD,"); +} + +size_t WiFiModule::read_incoming_request(char *raw_request_out) noexcept +{ + // Wait for the data buffer a bit + while (get_available() < 5) + { + } + + const auto connection_id = _serial.read() - ASCII_TO_CHAR; + + const auto data_length = _serial.read(); + + Serial.print("Data length: "); + Serial.print(data_length); + + auto read_bytes = 0U; + const auto start_time = millis(); + + while (read_bytes != data_length && (start_time + 10000) > millis()) + { + if (get_available() == 0) + { + continue; + } + + char character = _read_byte(); + + strncat(raw_request_out, &character, 1U); + + read_bytes++; + } + + // Skip the comma at the beginning + raw_request_out++; + + return connection_id; +} + +bool WiFiModule::close_connection(size_t connection_id) noexcept +{ + const auto cmd = "AT+CIPCLOSE"; + + auto command_length = strlen(cmd) + 50U + 1U; + + auto *command = util::malloc<char>(command_length); + + if (command == nullptr) + { + Serial.println("Memory allocation failed for creating close connection command"); + return false; + } + + snprintf(command, command_length, "%s=%u", cmd, connection_id); + + _send_serial(command); + + free(command); + + char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; + + const auto response_status = _read(4000U, response); + + if (response_status == ResponseStatus::OK) + { + Serial.print("Closed connection to "); + Serial.println(connection_id); + } + else + { + Serial.print("Failed to close connection to "); + Serial.println(connection_id); + return false; + } + + return true; +} + +bool WiFiModule::send(size_t connection_id, const char *data) +{ + const auto cmd = "AT+CIPSEND"; + + const auto data_length = strlen(data); + + auto command_length = strlen(cmd) + 50U + data_length + 1U; + + auto *command = util::malloc<char>(command_length); + + if (command == nullptr) + { + Serial.println("Memory allocation failed for creating close connection command"); + return false; + } + + snprintf(command, command_length, "%s=%u,%u", cmd, connection_id, data_length); + + _send_serial(command); + + free(command); + + char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; + + _read(4000U, response); + + _serial.print(data); + + strcpy(response, ""); + + _read(4000U, response); + + return true; +} + bool WiFiModule::_send_serial(const char *command) noexcept { auto full_command_length = strlen(command) + 2U + 1U; diff --git a/minion/src/wifi_module.hpp b/minion/src/wifi_module.hpp index 5a4148c..3621229 100644 --- a/minion/src/wifi_module.hpp +++ b/minion/src/wifi_module.hpp @@ -6,6 +6,8 @@ constexpr auto MAX_NETWORK_MODULE_RESPONSE_LENGTH = 128U; +constexpr auto ASCII_TO_CHAR = 48U; + enum WifiMode { Station = 1, @@ -66,6 +68,21 @@ public: */ const char *get_local_ip(char *local_ip_out) noexcept; + bool has_incoming_request() noexcept; + + /** + * Reads a incoming HTTP request. + * + * @param raw_request_out Raw request output buffer. + * + * @returns The connection ID. + */ + size_t read_incoming_request(char *raw_request_out) noexcept; + + bool close_connection(size_t connection_id) noexcept; + + bool send(size_t connection_id, const char *data); + private: SoftwareSerial _serial; |