From 2809f92eeb8b727e20167fe82e4cb9c3627d4870 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 8 May 2022 18:55:42 +0200 Subject: chore: move most files to minion folder --- .clang-format | 19 --- .clang-tidy | 47 ------- .gitignore | 7 +- Makefile | 20 --- minion/.clang-format | 19 +++ minion/.clang-tidy | 47 +++++++ minion/Makefile | 20 +++ minion/platformio.ini | 16 +++ minion/src/gymnasiearbete.cpp | 69 ++++++++++ minion/src/util.cpp | 35 +++++ minion/src/util.hpp | 27 ++++ minion/src/wifi_module.cpp | 312 ++++++++++++++++++++++++++++++++++++++++++ minion/src/wifi_module.hpp | 93 +++++++++++++ platformio.ini | 16 --- src/gymnasiearbete.cpp | 69 ---------- src/util.cpp | 35 ----- src/util.hpp | 27 ---- src/wifi_module.cpp | 312 ------------------------------------------ src/wifi_module.hpp | 93 ------------- 19 files changed, 642 insertions(+), 641 deletions(-) delete mode 100644 .clang-format delete mode 100644 .clang-tidy delete mode 100644 Makefile create mode 100644 minion/.clang-format create mode 100644 minion/.clang-tidy create mode 100644 minion/Makefile create mode 100644 minion/platformio.ini create mode 100644 minion/src/gymnasiearbete.cpp create mode 100644 minion/src/util.cpp create mode 100644 minion/src/util.hpp create mode 100644 minion/src/wifi_module.cpp create mode 100644 minion/src/wifi_module.hpp delete mode 100644 platformio.ini delete mode 100644 src/gymnasiearbete.cpp delete mode 100644 src/util.cpp delete mode 100644 src/util.hpp delete mode 100644 src/wifi_module.cpp delete mode 100644 src/wifi_module.hpp diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 782b0a9..0000000 --- a/.clang-format +++ /dev/null @@ -1,19 +0,0 @@ -BasedOnStyle: LLVM -UseTab: Always -IndentWidth: 4 -TabWidth: 4 -BreakBeforeBraces: Allman -AllowShortIfStatementsOnASingleLine: false -AllowShortFunctionsOnASingleLine: Empty -AllowShortLambdasOnASingleLine: None -IndentCaseLabels: false -ColumnLimit: 90 -AccessModifierOffset: -4 -AlwaysBreakTemplateDeclarations: Yes -ConstructorInitializerAllOnOneLineOrOnePerLine: true -AllowAllArgumentsOnNextLine: false -AllowAllParametersOfDeclarationOnNextLine: false -BinPackArguments: false -BinPackParameters: false -AlignAfterOpenBracket: BlockIndent -Cpp11BracedListStyle: false diff --git a/.clang-tidy b/.clang-tidy deleted file mode 100644 index 8a92317..0000000 --- a/.clang-tidy +++ /dev/null @@ -1,47 +0,0 @@ ---- -Checks: ' - clang-analyzer-*, - cppcoreguidelines-*, - google-*, - misc-*, - modernize-*, - bugprone-*, - performance-*, - readability-*, - -modernize-avoid-c-arrays, - -cppcoreguidelines-avoid-c-arrays, - -cppcoreguidelines-no-malloc, - -cppcoreguidelines-owning-memory' -WarningsAsErrors: '*' -HeaderFilterRegex: '\/src\/' -AnalyzeTemporaryDtors: false -CheckOptions: - - key: readability-function-cognitive-complexity.Threshold - value: 100 - - key: readability-identifier-naming.ClassCase - value: CamelCase - - key: readability-identifier-naming.PrivateMemberPrefix - value: _ - - key: readability-identifier-naming.StructCase - value: CamelCase - - key: google-readability-braces-around-statements.ShortStatementLines - value: '1' - - key: google-readability-function-size.StatementThreshold - value: '800' - - key: google-readability-namespace-comments.ShortNamespaceLines - value: '10' - - key: google-readability-namespace-comments.SpacesBeforeComments - value: '2' - - key: modernize-loop-convert.MaxCopySize - value: '16' - - key: modernize-loop-convert.MinConfidence - value: reasonable - - key: modernize-loop-convert.NamingStyle - value: CamelCase - - key: modernize-pass-by-value.IncludeStyle - value: llvm - - key: modernize-replace-auto-ptr.IncludeStyle - value: llvm - - key: modernize-use-nullptr.NullMacros - value: 'NULL' -... diff --git a/.gitignore b/.gitignore index c108c04..3050cb6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -build .vscode -.pio -src/secrets.hpp + +minion/build +minion/.pio +minion/src/secrets.hpp diff --git a/Makefile b/Makefile deleted file mode 100644 index 986833f..0000000 --- a/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -TARGET = gymnasiearbete - -PIO = platformio - -all: $(TARGET) - -.PHONY: $(TARGET) upload clean monitor - -$(TARGET): - $(PIO) run -v - $(PIO) run --target compiledb - -upload: - $(PIO) run --target upload - -clean: - $(PIO) run --target clean - -monitor: - $(PIO) run --target monitor diff --git a/minion/.clang-format b/minion/.clang-format new file mode 100644 index 0000000..782b0a9 --- /dev/null +++ b/minion/.clang-format @@ -0,0 +1,19 @@ +BasedOnStyle: LLVM +UseTab: Always +IndentWidth: 4 +TabWidth: 4 +BreakBeforeBraces: Allman +AllowShortIfStatementsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortLambdasOnASingleLine: None +IndentCaseLabels: false +ColumnLimit: 90 +AccessModifierOffset: -4 +AlwaysBreakTemplateDeclarations: Yes +ConstructorInitializerAllOnOneLineOrOnePerLine: true +AllowAllArgumentsOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +BinPackArguments: false +BinPackParameters: false +AlignAfterOpenBracket: BlockIndent +Cpp11BracedListStyle: false diff --git a/minion/.clang-tidy b/minion/.clang-tidy new file mode 100644 index 0000000..8a92317 --- /dev/null +++ b/minion/.clang-tidy @@ -0,0 +1,47 @@ +--- +Checks: ' + clang-analyzer-*, + cppcoreguidelines-*, + google-*, + misc-*, + modernize-*, + bugprone-*, + performance-*, + readability-*, + -modernize-avoid-c-arrays, + -cppcoreguidelines-avoid-c-arrays, + -cppcoreguidelines-no-malloc, + -cppcoreguidelines-owning-memory' +WarningsAsErrors: '*' +HeaderFilterRegex: '\/src\/' +AnalyzeTemporaryDtors: false +CheckOptions: + - key: readability-function-cognitive-complexity.Threshold + value: 100 + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.PrivateMemberPrefix + value: _ + - key: readability-identifier-naming.StructCase + value: CamelCase + - key: google-readability-braces-around-statements.ShortStatementLines + value: '1' + - key: google-readability-function-size.StatementThreshold + value: '800' + - key: google-readability-namespace-comments.ShortNamespaceLines + value: '10' + - key: google-readability-namespace-comments.SpacesBeforeComments + value: '2' + - key: modernize-loop-convert.MaxCopySize + value: '16' + - key: modernize-loop-convert.MinConfidence + value: reasonable + - key: modernize-loop-convert.NamingStyle + value: CamelCase + - key: modernize-pass-by-value.IncludeStyle + value: llvm + - key: modernize-replace-auto-ptr.IncludeStyle + value: llvm + - key: modernize-use-nullptr.NullMacros + value: 'NULL' +... diff --git a/minion/Makefile b/minion/Makefile new file mode 100644 index 0000000..986833f --- /dev/null +++ b/minion/Makefile @@ -0,0 +1,20 @@ +TARGET = gymnasiearbete + +PIO = platformio + +all: $(TARGET) + +.PHONY: $(TARGET) upload clean monitor + +$(TARGET): + $(PIO) run -v + $(PIO) run --target compiledb + +upload: + $(PIO) run --target upload + +clean: + $(PIO) run --target clean + +monitor: + $(PIO) run --target monitor diff --git a/minion/platformio.ini b/minion/platformio.ini new file mode 100644 index 0000000..4bac56e --- /dev/null +++ b/minion/platformio.ini @@ -0,0 +1,16 @@ +[platformio] +build_dir = build + +[env:uno] +platform = atmelavr +board = uno +framework = arduino +src_build_flags = + -Wextra + -Wpedantic + -Wshadow + -Wcast-align + -Wunused + -Wold-style-cast + -Wconversion + -pedantic diff --git a/minion/src/gymnasiearbete.cpp b/minion/src/gymnasiearbete.cpp new file mode 100644 index 0000000..0e1adb5 --- /dev/null +++ b/minion/src/gymnasiearbete.cpp @@ -0,0 +1,69 @@ +#include "secrets.hpp" +#include "wifi_module.hpp" + +#include +#include +#include + +constexpr auto BAUDRATE = 9600U; + +constexpr auto NETWORK_MODULE_RX_PIN = 3; +constexpr auto NETWORK_MODULE_TX_PIN = 2; + +auto wifi_module = WiFiModule(NETWORK_MODULE_RX_PIN, NETWORK_MODULE_TX_PIN); + +void setup() +{ + Serial.begin(BAUDRATE); + + pinMode(NETWORK_MODULE_RX_PIN, INPUT); + pinMode(NETWORK_MODULE_TX_PIN, OUTPUT); + + wifi_module.begin(BAUDRATE); + + wifi_module.reset(); + + delay(1000); + + auto wifi_module_connected = wifi_module.test(); + + Serial.print("Wifi module connected: "); + Serial.println(wifi_module_connected ? "Yes" : "No"); + + if (!wifi_module_connected) + { + while (true) + { + } + } + + wifi_module.set_echo_enabled(false); + + delay(1000); + + const auto wifi_connect_success = wifi_module.connect(WIFI_SSID, WIFI_PASSWORD); + + if (wifi_connect_success) + { + Serial.print("Connected to wifi network '"); + Serial.print(WIFI_SSID); + Serial.println("' successfully"); + } + else + { + Serial.print("Failed to connect to wifi network '"); + Serial.print(WIFI_SSID); + Serial.println("'"); + } + + wifi_module.set_wifi_mode(WifiMode::Station); + + delay(3000); + + char local_ip[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; + + Serial.print("IP address: "); + Serial.println(wifi_module.get_local_ip(local_ip)); +} + +void loop() {} diff --git a/minion/src/util.cpp b/minion/src/util.cpp new file mode 100644 index 0000000..f587781 --- /dev/null +++ b/minion/src/util.cpp @@ -0,0 +1,35 @@ +#include "util.hpp" + +namespace util +{ + +bool str_ends_with(const char *str, const char *other_str) noexcept +{ + if (str == nullptr || other_str == nullptr) + { + return false; + } + + auto str_length = strlen(str); + auto other_str_length = strlen(other_str); + + if (other_str_length > str_length) + { + return false; + } + + return strncmp(str + str_length - other_str_length, other_str, other_str_length) == 0; +} + +void substr(const char *str, const char *end, char *dest) noexcept +{ + auto *dest_head = dest; + + for (const char *char_ptr = str; char_ptr + 1 != end; ++char_ptr) + { + *dest_head = *char_ptr; + dest_head++; + } +} + +} // namespace util diff --git a/minion/src/util.hpp b/minion/src/util.hpp new file mode 100644 index 0000000..d6f7f1c --- /dev/null +++ b/minion/src/util.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +namespace util +{ + +template +Type *malloc(size_t size) noexcept +{ + return static_cast(::malloc(size)); +} + +bool str_ends_with(const char *str, const char *other_str) noexcept; + +/** + * Extracts a portion of a string. + * + * @param str The target string. + * @param end A pointer to a place inside the target string. + * @param dest Output buffer. + */ +void substr(const char *str, const char *end, char *dest) noexcept; + +} // namespace util diff --git a/minion/src/wifi_module.cpp b/minion/src/wifi_module.cpp new file mode 100644 index 0000000..2e25dc9 --- /dev/null +++ b/minion/src/wifi_module.cpp @@ -0,0 +1,312 @@ +#include "wifi_module.hpp" + +#include "util.hpp" + +#include +#include + +WiFiModule::WiFiModule(uint8_t receive_pin, uint8_t transmit_pin) noexcept + : _serial(receive_pin, transmit_pin) +{ +} + +void WiFiModule::begin(size_t baudrate) noexcept +{ + _serial.begin(baudrate); +} + +int WiFiModule::get_available() noexcept +{ + return _serial.available(); +} + +void WiFiModule::reset() noexcept +{ + _send_serial("AT+RST"); + + char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; + + const auto response_status = _read(2000U, response); + + Serial.println( + response_status == ResponseStatus::OK ? "Reset wifi module" + : "Failed to reset wifi module" + ); +} + +bool WiFiModule::connect(const char *ssid, const char *password) noexcept +{ + const char cmd[] = "AT+CWJAP"; + + auto command_length = strlen(cmd) + strlen(ssid) + strlen(password) + 6U + 1U; + + auto *command = util::malloc(command_length); + + if (command == nullptr) + { + Serial.println("Memory allocation failed for creating full connection command"); + return false; + } + + snprintf(command, command_length, "%s=\"%s\",\"%s\"", cmd, ssid, password); + + const auto send_success = _send_serial(command); + + if (!send_success) + { + Serial.println("Failed to send connection command"); + return false; + } + + free(command); + + char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; + + const auto response_status = _read(20000U, response); + + if (response_status != ResponseStatus::OK) + { + Serial.print("Connection command responded with status "); + Serial.println(response_status); + return false; + } + + return true; +} + +void WiFiModule::set_wifi_mode(WifiMode wifi_mode) noexcept +{ + const char cmd[] = "AT+CWMODE_CUR"; + + auto command_length = strlen(cmd) + 2U + 1U; + + auto *command = util::malloc(command_length); + + snprintf(command, command_length, "%s=%u", cmd, static_cast(wifi_mode)); + + _send_serial(command); + + free(command); + + char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; + + _read(1500U, response); +} + +void WiFiModule::set_multiple_connections_enabled(bool is_enabled) noexcept +{ + const char cmd[] = "AT+CIPMUX"; + + auto command_length = strlen(cmd) + 2U + 1U; + + auto *command = util::malloc(command_length); + + snprintf(command, command_length, "%s=%u", cmd, is_enabled ? 1U : 0U); + + _send_serial(command); + + free(command); + + char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; + + _read(1500U, response); + + // Serial.println(response); +} + +void WiFiModule::set_echo_enabled(bool is_enabled) noexcept +{ + const char cmd[] = "ATE"; + + auto command_length = strlen(cmd) + 1U + 1U; + + auto *command = util::malloc(command_length); + + snprintf(command, command_length, "%s%u", cmd, is_enabled ? 1U : 0U); + + _send_serial(command); + + free(command); + + char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; + + const auto response_status = _read(1500U, response); + + if (response_status == ResponseStatus::OK) + { + Serial.print("Turned "); + Serial.print(is_enabled ? "on" : "off"); + Serial.println(" AT commands echo"); + } + else + { + Serial.print("Failed to turn "); + Serial.print(is_enabled ? "on" : "off"); + Serial.println(" AT commands echo"); + } +} + +void WiFiModule::create_tcp_server(size_t port) noexcept +{ + const auto cmd = "AT+CIPSERVER"; + + auto command_length = strlen(cmd) + 7U + 1U; + + auto *command = util::malloc(command_length); + + snprintf(command, command_length, "%s=1,%u", cmd, port); + + _send_serial(command); + + free(command); + + char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; + + _read(1500U, response); + + // Serial.println(response); +} + +bool WiFiModule::test() noexcept +{ + const auto send_success = _send_serial("AT"); + + if (!send_success) + { + return false; + } + + char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; + + const auto response_status = _read(5000U, response); + + if (response_status == ResponseStatus::TIMEOUT) + { + return false; + } + + return strcmp(response, "") != 0; +} + +const char *WiFiModule::get_local_ip(char *local_ip_out) noexcept +{ + const auto command = "AT+CIFSR"; + + const auto send_success = _send_serial(command); + + if (!send_success) + { + return local_ip_out; + } + + auto *buf = util::malloc(strlen(local_ip_out)); + + if (buf == nullptr) + { + strcpy(local_ip_out, "Memory allocation failure"); + return local_ip_out; + } + + const auto response_status = _read(10000U, buf); + + if (response_status != ResponseStatus::OK) + { + free(buf); + + sprintf( + local_ip_out, + "Response status was not OK. Was %d", + static_cast(response_status) + ); + + return local_ip_out; + } + + const auto *local_ip_end = strstr(buf, "\r\n+CIFSR:STAMAC"); + + if (local_ip_end == nullptr) + { + free(buf); + strcpy(local_ip_out, "Response parsing error"); + return local_ip_out; + } + + const auto staip_title_length = 16U; // The length of '+CIFSR:STAIP,"' + + util::substr(buf + staip_title_length, local_ip_end, local_ip_out); + + free(buf); + + return local_ip_out; +} + +bool WiFiModule::_send_serial(const char *command) noexcept +{ + auto full_command_length = strlen(command) + 2U + 1U; + + auto *full_command = util::malloc(full_command_length); + + if (full_command == nullptr) + { + return false; + } + + snprintf(full_command, full_command_length, "%s\r\n", command); + + _serial.print(full_command); + + // Serial.print("Sent command: "); + // Serial.println(full_command); + + free(full_command); + + return true; +} + +ResponseStatus WiFiModule::_read(uint64_t timeout, char *response_out) noexcept +{ + const auto start_time = millis(); + + 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) + { + char character = _read_byte(); + + strncat(response_out, &character, 1U); + + // *response_out_head = character; + // response_out_head++; + + if (util::str_ends_with(response_out, "OK")) + { + status = ResponseStatus::OK; + has_end = true; + } + + if (util::str_ends_with(response_out, "ERROR")) + { + status = ResponseStatus::ERROR; + has_end = true; + } + + if (util::str_ends_with(response_out, "FAIL")) + { + status = ResponseStatus::FAIL; + has_end = true; + } + } + } + + return status; +} + +char WiFiModule::_read_byte() noexcept +{ + return static_cast(_serial.read()); +} diff --git a/minion/src/wifi_module.hpp b/minion/src/wifi_module.hpp new file mode 100644 index 0000000..5a4148c --- /dev/null +++ b/minion/src/wifi_module.hpp @@ -0,0 +1,93 @@ +#pragma once + +#include +#include +#include + +constexpr auto MAX_NETWORK_MODULE_RESPONSE_LENGTH = 128U; + +enum WifiMode +{ + Station = 1, + SoftAP = 2, + SoftAPAndStation = 3 +}; + +enum ResponseStatus +{ + OK, + FAIL, + ERROR, + TIMEOUT +}; + +class WiFiModule +{ +public: + WiFiModule(uint8_t receive_pin, uint8_t transmit_pin) noexcept; + + void begin(size_t baudrate) noexcept; + + int get_available() noexcept; + + void reset() noexcept; + + /** + * Connects to a wifi network. + * + * @param ssid The service set identifier of a wifi network. + * @param password The wifi network password. + * + * @returns Whether or not it succeeded. + */ + bool connect(const char *ssid, const char *password) noexcept; + + void set_wifi_mode(WifiMode wifi_mode) noexcept; + + void set_multiple_connections_enabled(bool is_enabled) noexcept; + + void set_echo_enabled(bool is_enabled) noexcept; + + void create_tcp_server(size_t port) noexcept; + + /** + * Tests the connection to the wifi module. + * + * @returns Whether or not the test succeeded. + */ + bool test() noexcept; + + /** + * Gets local IP address of the wifi module. + * + * @param local_ip_out Local IP output buffer. + * + * @returns A pointer to the local IP output buffer. + */ + const char *get_local_ip(char *local_ip_out) noexcept; + +private: + SoftwareSerial _serial; + + /** + * Sends a command to the wifi module. + * + * @param command A command without the "AT+" in the beginning. + * + * @returns Whether or not it succeeded. + */ + bool _send_serial(const char *command) noexcept; + + /** + * Reads from the wifi module until it responds with a status. + * + * @param timeout Timeout in milliseconds. + * @param response_out Response output buffer. + * + * @returns The response status. + * + */ + ResponseStatus _read(uint64_t timeout, char *response_out) noexcept; + + char _read_byte() noexcept; +}; diff --git a/platformio.ini b/platformio.ini deleted file mode 100644 index 4bac56e..0000000 --- a/platformio.ini +++ /dev/null @@ -1,16 +0,0 @@ -[platformio] -build_dir = build - -[env:uno] -platform = atmelavr -board = uno -framework = arduino -src_build_flags = - -Wextra - -Wpedantic - -Wshadow - -Wcast-align - -Wunused - -Wold-style-cast - -Wconversion - -pedantic diff --git a/src/gymnasiearbete.cpp b/src/gymnasiearbete.cpp deleted file mode 100644 index 0e1adb5..0000000 --- a/src/gymnasiearbete.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "secrets.hpp" -#include "wifi_module.hpp" - -#include -#include -#include - -constexpr auto BAUDRATE = 9600U; - -constexpr auto NETWORK_MODULE_RX_PIN = 3; -constexpr auto NETWORK_MODULE_TX_PIN = 2; - -auto wifi_module = WiFiModule(NETWORK_MODULE_RX_PIN, NETWORK_MODULE_TX_PIN); - -void setup() -{ - Serial.begin(BAUDRATE); - - pinMode(NETWORK_MODULE_RX_PIN, INPUT); - pinMode(NETWORK_MODULE_TX_PIN, OUTPUT); - - wifi_module.begin(BAUDRATE); - - wifi_module.reset(); - - delay(1000); - - auto wifi_module_connected = wifi_module.test(); - - Serial.print("Wifi module connected: "); - Serial.println(wifi_module_connected ? "Yes" : "No"); - - if (!wifi_module_connected) - { - while (true) - { - } - } - - wifi_module.set_echo_enabled(false); - - delay(1000); - - const auto wifi_connect_success = wifi_module.connect(WIFI_SSID, WIFI_PASSWORD); - - if (wifi_connect_success) - { - Serial.print("Connected to wifi network '"); - Serial.print(WIFI_SSID); - Serial.println("' successfully"); - } - else - { - Serial.print("Failed to connect to wifi network '"); - Serial.print(WIFI_SSID); - Serial.println("'"); - } - - wifi_module.set_wifi_mode(WifiMode::Station); - - delay(3000); - - char local_ip[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; - - Serial.print("IP address: "); - Serial.println(wifi_module.get_local_ip(local_ip)); -} - -void loop() {} diff --git a/src/util.cpp b/src/util.cpp deleted file mode 100644 index f587781..0000000 --- a/src/util.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "util.hpp" - -namespace util -{ - -bool str_ends_with(const char *str, const char *other_str) noexcept -{ - if (str == nullptr || other_str == nullptr) - { - return false; - } - - auto str_length = strlen(str); - auto other_str_length = strlen(other_str); - - if (other_str_length > str_length) - { - return false; - } - - return strncmp(str + str_length - other_str_length, other_str, other_str_length) == 0; -} - -void substr(const char *str, const char *end, char *dest) noexcept -{ - auto *dest_head = dest; - - for (const char *char_ptr = str; char_ptr + 1 != end; ++char_ptr) - { - *dest_head = *char_ptr; - dest_head++; - } -} - -} // namespace util diff --git a/src/util.hpp b/src/util.hpp deleted file mode 100644 index d6f7f1c..0000000 --- a/src/util.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace util -{ - -template -Type *malloc(size_t size) noexcept -{ - return static_cast(::malloc(size)); -} - -bool str_ends_with(const char *str, const char *other_str) noexcept; - -/** - * Extracts a portion of a string. - * - * @param str The target string. - * @param end A pointer to a place inside the target string. - * @param dest Output buffer. - */ -void substr(const char *str, const char *end, char *dest) noexcept; - -} // namespace util diff --git a/src/wifi_module.cpp b/src/wifi_module.cpp deleted file mode 100644 index 2e25dc9..0000000 --- a/src/wifi_module.cpp +++ /dev/null @@ -1,312 +0,0 @@ -#include "wifi_module.hpp" - -#include "util.hpp" - -#include -#include - -WiFiModule::WiFiModule(uint8_t receive_pin, uint8_t transmit_pin) noexcept - : _serial(receive_pin, transmit_pin) -{ -} - -void WiFiModule::begin(size_t baudrate) noexcept -{ - _serial.begin(baudrate); -} - -int WiFiModule::get_available() noexcept -{ - return _serial.available(); -} - -void WiFiModule::reset() noexcept -{ - _send_serial("AT+RST"); - - char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; - - const auto response_status = _read(2000U, response); - - Serial.println( - response_status == ResponseStatus::OK ? "Reset wifi module" - : "Failed to reset wifi module" - ); -} - -bool WiFiModule::connect(const char *ssid, const char *password) noexcept -{ - const char cmd[] = "AT+CWJAP"; - - auto command_length = strlen(cmd) + strlen(ssid) + strlen(password) + 6U + 1U; - - auto *command = util::malloc(command_length); - - if (command == nullptr) - { - Serial.println("Memory allocation failed for creating full connection command"); - return false; - } - - snprintf(command, command_length, "%s=\"%s\",\"%s\"", cmd, ssid, password); - - const auto send_success = _send_serial(command); - - if (!send_success) - { - Serial.println("Failed to send connection command"); - return false; - } - - free(command); - - char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; - - const auto response_status = _read(20000U, response); - - if (response_status != ResponseStatus::OK) - { - Serial.print("Connection command responded with status "); - Serial.println(response_status); - return false; - } - - return true; -} - -void WiFiModule::set_wifi_mode(WifiMode wifi_mode) noexcept -{ - const char cmd[] = "AT+CWMODE_CUR"; - - auto command_length = strlen(cmd) + 2U + 1U; - - auto *command = util::malloc(command_length); - - snprintf(command, command_length, "%s=%u", cmd, static_cast(wifi_mode)); - - _send_serial(command); - - free(command); - - char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; - - _read(1500U, response); -} - -void WiFiModule::set_multiple_connections_enabled(bool is_enabled) noexcept -{ - const char cmd[] = "AT+CIPMUX"; - - auto command_length = strlen(cmd) + 2U + 1U; - - auto *command = util::malloc(command_length); - - snprintf(command, command_length, "%s=%u", cmd, is_enabled ? 1U : 0U); - - _send_serial(command); - - free(command); - - char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; - - _read(1500U, response); - - // Serial.println(response); -} - -void WiFiModule::set_echo_enabled(bool is_enabled) noexcept -{ - const char cmd[] = "ATE"; - - auto command_length = strlen(cmd) + 1U + 1U; - - auto *command = util::malloc(command_length); - - snprintf(command, command_length, "%s%u", cmd, is_enabled ? 1U : 0U); - - _send_serial(command); - - free(command); - - char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; - - const auto response_status = _read(1500U, response); - - if (response_status == ResponseStatus::OK) - { - Serial.print("Turned "); - Serial.print(is_enabled ? "on" : "off"); - Serial.println(" AT commands echo"); - } - else - { - Serial.print("Failed to turn "); - Serial.print(is_enabled ? "on" : "off"); - Serial.println(" AT commands echo"); - } -} - -void WiFiModule::create_tcp_server(size_t port) noexcept -{ - const auto cmd = "AT+CIPSERVER"; - - auto command_length = strlen(cmd) + 7U + 1U; - - auto *command = util::malloc(command_length); - - snprintf(command, command_length, "%s=1,%u", cmd, port); - - _send_serial(command); - - free(command); - - char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; - - _read(1500U, response); - - // Serial.println(response); -} - -bool WiFiModule::test() noexcept -{ - const auto send_success = _send_serial("AT"); - - if (!send_success) - { - return false; - } - - char response[MAX_NETWORK_MODULE_RESPONSE_LENGTH] = ""; - - const auto response_status = _read(5000U, response); - - if (response_status == ResponseStatus::TIMEOUT) - { - return false; - } - - return strcmp(response, "") != 0; -} - -const char *WiFiModule::get_local_ip(char *local_ip_out) noexcept -{ - const auto command = "AT+CIFSR"; - - const auto send_success = _send_serial(command); - - if (!send_success) - { - return local_ip_out; - } - - auto *buf = util::malloc(strlen(local_ip_out)); - - if (buf == nullptr) - { - strcpy(local_ip_out, "Memory allocation failure"); - return local_ip_out; - } - - const auto response_status = _read(10000U, buf); - - if (response_status != ResponseStatus::OK) - { - free(buf); - - sprintf( - local_ip_out, - "Response status was not OK. Was %d", - static_cast(response_status) - ); - - return local_ip_out; - } - - const auto *local_ip_end = strstr(buf, "\r\n+CIFSR:STAMAC"); - - if (local_ip_end == nullptr) - { - free(buf); - strcpy(local_ip_out, "Response parsing error"); - return local_ip_out; - } - - const auto staip_title_length = 16U; // The length of '+CIFSR:STAIP,"' - - util::substr(buf + staip_title_length, local_ip_end, local_ip_out); - - free(buf); - - return local_ip_out; -} - -bool WiFiModule::_send_serial(const char *command) noexcept -{ - auto full_command_length = strlen(command) + 2U + 1U; - - auto *full_command = util::malloc(full_command_length); - - if (full_command == nullptr) - { - return false; - } - - snprintf(full_command, full_command_length, "%s\r\n", command); - - _serial.print(full_command); - - // Serial.print("Sent command: "); - // Serial.println(full_command); - - free(full_command); - - return true; -} - -ResponseStatus WiFiModule::_read(uint64_t timeout, char *response_out) noexcept -{ - const auto start_time = millis(); - - 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) - { - char character = _read_byte(); - - strncat(response_out, &character, 1U); - - // *response_out_head = character; - // response_out_head++; - - if (util::str_ends_with(response_out, "OK")) - { - status = ResponseStatus::OK; - has_end = true; - } - - if (util::str_ends_with(response_out, "ERROR")) - { - status = ResponseStatus::ERROR; - has_end = true; - } - - if (util::str_ends_with(response_out, "FAIL")) - { - status = ResponseStatus::FAIL; - has_end = true; - } - } - } - - return status; -} - -char WiFiModule::_read_byte() noexcept -{ - return static_cast(_serial.read()); -} diff --git a/src/wifi_module.hpp b/src/wifi_module.hpp deleted file mode 100644 index 5a4148c..0000000 --- a/src/wifi_module.hpp +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once - -#include -#include -#include - -constexpr auto MAX_NETWORK_MODULE_RESPONSE_LENGTH = 128U; - -enum WifiMode -{ - Station = 1, - SoftAP = 2, - SoftAPAndStation = 3 -}; - -enum ResponseStatus -{ - OK, - FAIL, - ERROR, - TIMEOUT -}; - -class WiFiModule -{ -public: - WiFiModule(uint8_t receive_pin, uint8_t transmit_pin) noexcept; - - void begin(size_t baudrate) noexcept; - - int get_available() noexcept; - - void reset() noexcept; - - /** - * Connects to a wifi network. - * - * @param ssid The service set identifier of a wifi network. - * @param password The wifi network password. - * - * @returns Whether or not it succeeded. - */ - bool connect(const char *ssid, const char *password) noexcept; - - void set_wifi_mode(WifiMode wifi_mode) noexcept; - - void set_multiple_connections_enabled(bool is_enabled) noexcept; - - void set_echo_enabled(bool is_enabled) noexcept; - - void create_tcp_server(size_t port) noexcept; - - /** - * Tests the connection to the wifi module. - * - * @returns Whether or not the test succeeded. - */ - bool test() noexcept; - - /** - * Gets local IP address of the wifi module. - * - * @param local_ip_out Local IP output buffer. - * - * @returns A pointer to the local IP output buffer. - */ - const char *get_local_ip(char *local_ip_out) noexcept; - -private: - SoftwareSerial _serial; - - /** - * Sends a command to the wifi module. - * - * @param command A command without the "AT+" in the beginning. - * - * @returns Whether or not it succeeded. - */ - bool _send_serial(const char *command) noexcept; - - /** - * Reads from the wifi module until it responds with a status. - * - * @param timeout Timeout in milliseconds. - * @param response_out Response output buffer. - * - * @returns The response status. - * - */ - ResponseStatus _read(uint64_t timeout, char *response_out) noexcept; - - char _read_byte() noexcept; -}; -- cgit v1.2.3-18-g5258