summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2022-05-08 23:04:16 +0200
committerHampusM <hampus@hampusmat.com>2022-05-08 23:05:36 +0200
commiteddaed4e597ce2bc7fa179ce6a15b90951579c6e (patch)
tree0e696aaab4cb24f58582efce1982cce47832cb4f
parent2809f92eeb8b727e20167fe82e4cb9c3627d4870 (diff)
feat(minion): implement respond to HTTP requests
-rw-r--r--minion/src/gymnasiearbete.cpp28
-rw-r--r--minion/src/wifi_module.cpp118
-rw-r--r--minion/src/wifi_module.hpp17
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;