diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..69c74bc --- /dev/null +++ b/.clang-format @@ -0,0 +1,12 @@ +BasedOnStyle: Google +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +BreakBeforeBraces: Allman +ColumnLimit: 160 +IncludeBlocks: Preserve +IndentCaseLabels: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortBlocksOnASingleLine: Never diff --git a/bootloader_components/boot_hooks.c b/bootloader_components/boot_hooks.c index 8f00ddb..c5bb9df 100644 --- a/bootloader_components/boot_hooks.c +++ b/bootloader_components/boot_hooks.c @@ -1,4 +1,5 @@ -// source: https://github.com/espressif/esp-iot-solution/blob/4730d91db70df7e6e0a3191d725ab1c5f98ff9ce/examples/usb/device/usb_webcam/bootloader_components/boot_hooks/boot_hooks.c +// source: +// https://github.com/espressif/esp-iot-solution/blob/4730d91db70df7e6e0a3191d725ab1c5f98ff9ce/examples/usb/device/usb_webcam/bootloader_components/boot_hooks/boot_hooks.c #ifdef CONFIG_GENERAL_INCLUDE_UVC_MODE #include "esp_log.h" @@ -9,16 +10,13 @@ * with all its symbols. */ -void bootloader_hooks_include(void) -{ -} +void bootloader_hooks_include(void) {} void bootloader_before_init(void) { - - // Disable D+ pullup, to prevent the USB host from retrieving USB-Serial-JTAG's descriptor. - SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE); - CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP); - CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE); + // Disable D+ pullup, to prevent the USB host from retrieving USB-Serial-JTAG's descriptor. + SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE); + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP); + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE); } #endif \ No newline at end of file diff --git a/components/CameraManager/CameraManager/CameraManager.cpp b/components/CameraManager/CameraManager/CameraManager.cpp index 50bab34..835a97a 100644 --- a/components/CameraManager/CameraManager/CameraManager.cpp +++ b/components/CameraManager/CameraManager/CameraManager.cpp @@ -1,237 +1,229 @@ #include "CameraManager.hpp" -const char *CAMERA_MANAGER_TAG = "[CAMERA_MANAGER]"; +const char* CAMERA_MANAGER_TAG = "[CAMERA_MANAGER]"; -CameraManager::CameraManager(std::shared_ptr projectConfig, QueueHandle_t eventQueue) - : projectConfig(projectConfig), eventQueue(eventQueue) {} +CameraManager::CameraManager(std::shared_ptr projectConfig, QueueHandle_t eventQueue) : projectConfig(projectConfig), eventQueue(eventQueue) {} void CameraManager::setupCameraPinout() { - // Workaround for espM5SStack not having a defined camera + // Workaround for espM5SStack not having a defined camera #ifdef CONFIG_CAMERA_MODULE_NAME - ESP_LOGI(CAMERA_MANAGER_TAG, "[Camera]: Camera module is %s", CONFIG_CAMERA_MODULE_NAME); + ESP_LOGI(CAMERA_MANAGER_TAG, "[Camera]: Camera module is %s", CONFIG_CAMERA_MODULE_NAME); #else - ESP_LOGI(CAMERA_MANAGER_TAG, "[Camera]: Camera module is undefined"); + ESP_LOGI(CAMERA_MANAGER_TAG, "[Camera]: Camera module is undefined"); #endif - // camera external clock signal frequencies - // 10000000 stable - // 16500000 optimal freq on ESP32-CAM (default) - // 20000000 max freq on ESP32-CAM - // 24000000 optimal freq on ESP32-S3 // 23MHz same fps - int xclk_freq_hz = CONFIG_CAMERA_WIFI_XCLK_FREQ; + // camera external clock signal frequencies + // 10000000 stable + // 16500000 optimal freq on ESP32-CAM (default) + // 20000000 max freq on ESP32-CAM + // 24000000 optimal freq on ESP32-S3 // 23MHz same fps + int xclk_freq_hz = CONFIG_CAMERA_WIFI_XCLK_FREQ; #if CONFIG_CAMERA_MODULE_ESP_EYE - /* IO13, IO14 is designed for JTAG by default, - * to use it as generalized input, - * firstly declare it as pullup input - **/ - gpio_reset_pin(13); - gpio_reset_pin(14); - gpio_set_direction(13, GPIO_MODE_INPUT); - gpio_set_direction(14, GPIO_MODE_INPUT); - gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); - gpio_set_pull_mode(14, GPIO_PULLUP_ONLY); - ESP_LOGI(CAMERA_MANAGER_TAG, "ESP_EYE"); + /* IO13, IO14 is designed for JTAG by default, + * to use it as generalized input, + * firstly declare it as pullup input + **/ + gpio_reset_pin(13); + gpio_reset_pin(14); + gpio_set_direction(13, GPIO_MODE_INPUT); + gpio_set_direction(14, GPIO_MODE_INPUT); + gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); + gpio_set_pull_mode(14, GPIO_PULLUP_ONLY); + ESP_LOGI(CAMERA_MANAGER_TAG, "ESP_EYE"); #elif CONFIG_CAMERA_MODULE_CAM_BOARD - /* IO13, IO14 is designed for JTAG by default, - * to use it as generalized input, - * firstly declare it as pullup input - **/ + /* IO13, IO14 is designed for JTAG by default, + * to use it as generalized input, + * firstly declare it as pullup input + **/ - gpio_reset_pin(13); - gpio_reset_pin(14); - gpio_set_direction(13, GPIO_MODE_INPUT); - gpio_set_direction(14, GPIO_MODE_INPUT); - gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); - gpio_set_pull_mode(14, GPIO_PULLUP_ONLY); + gpio_reset_pin(13); + gpio_reset_pin(14); + gpio_set_direction(13, GPIO_MODE_INPUT); + gpio_set_direction(14, GPIO_MODE_INPUT); + gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); + gpio_set_pull_mode(14, GPIO_PULLUP_ONLY); - ESP_LOGI(CAMERA_MANAGER_TAG, "CAM_BOARD"); + ESP_LOGI(CAMERA_MANAGER_TAG, "CAM_BOARD"); #endif #if CONFIG_GENERAL_INCLUDE_UVC_MODE - xclk_freq_hz = CONFIG_CAMERA_USB_XCLK_FREQ; + xclk_freq_hz = CONFIG_CAMERA_USB_XCLK_FREQ; #endif - config = { - .pin_pwdn = CONFIG_PWDN_GPIO_NUM, // CAM_PIN_PWDN, - .pin_reset = CONFIG_RESET_GPIO_NUM, // CAM_PIN_RESET, - .pin_xclk = CONFIG_XCLK_GPIO_NUM, // CAM_PIN_XCLK, - .pin_sccb_sda = CONFIG_SIOD_GPIO_NUM, // CAM_PIN_SIOD, - .pin_sccb_scl = CONFIG_SIOC_GPIO_NUM, // CAM_PIN_SIOC, + config = { + .pin_pwdn = CONFIG_PWDN_GPIO_NUM, // CAM_PIN_PWDN, + .pin_reset = CONFIG_RESET_GPIO_NUM, // CAM_PIN_RESET, + .pin_xclk = CONFIG_XCLK_GPIO_NUM, // CAM_PIN_XCLK, + .pin_sccb_sda = CONFIG_SIOD_GPIO_NUM, // CAM_PIN_SIOD, + .pin_sccb_scl = CONFIG_SIOC_GPIO_NUM, // CAM_PIN_SIOC, - .pin_d7 = CONFIG_Y9_GPIO_NUM, /// CAM_PIN_D7, - .pin_d6 = CONFIG_Y8_GPIO_NUM, /// CAM_PIN_D6, - .pin_d5 = CONFIG_Y7_GPIO_NUM, // CAM_PIN_D5, - .pin_d4 = CONFIG_Y6_GPIO_NUM, // CAM_PIN_D4, - .pin_d3 = CONFIG_Y5_GPIO_NUM, // CAM_PIN_D3, - .pin_d2 = CONFIG_Y4_GPIO_NUM, // CAM_PIN_D2, - .pin_d1 = CONFIG_Y3_GPIO_NUM, // CAM_PIN_D1, - .pin_d0 = CONFIG_Y2_GPIO_NUM, // CAM_PIN_D0, - .pin_vsync = CONFIG_VSYNC_GPIO_NUM, // CAM_PIN_VSYNC, - .pin_href = CONFIG_HREF_GPIO_NUM, // CAM_PIN_HREF, - .pin_pclk = CONFIG_PCLK_GPIO_NUM, // CAM_PIN_PCLK, + .pin_d7 = CONFIG_Y9_GPIO_NUM, /// CAM_PIN_D7, + .pin_d6 = CONFIG_Y8_GPIO_NUM, /// CAM_PIN_D6, + .pin_d5 = CONFIG_Y7_GPIO_NUM, // CAM_PIN_D5, + .pin_d4 = CONFIG_Y6_GPIO_NUM, // CAM_PIN_D4, + .pin_d3 = CONFIG_Y5_GPIO_NUM, // CAM_PIN_D3, + .pin_d2 = CONFIG_Y4_GPIO_NUM, // CAM_PIN_D2, + .pin_d1 = CONFIG_Y3_GPIO_NUM, // CAM_PIN_D1, + .pin_d0 = CONFIG_Y2_GPIO_NUM, // CAM_PIN_D0, + .pin_vsync = CONFIG_VSYNC_GPIO_NUM, // CAM_PIN_VSYNC, + .pin_href = CONFIG_HREF_GPIO_NUM, // CAM_PIN_HREF, + .pin_pclk = CONFIG_PCLK_GPIO_NUM, // CAM_PIN_PCLK, - .xclk_freq_hz = xclk_freq_hz, // Set in config - .ledc_timer = LEDC_TIMER_0, - .ledc_channel = LEDC_CHANNEL_0, + .xclk_freq_hz = xclk_freq_hz, // Set in config + .ledc_timer = LEDC_TIMER_0, + .ledc_channel = LEDC_CHANNEL_0, - .pixel_format = PIXFORMAT_JPEG, // YUV422,GRAYSCALE,RGB565,JPEG - .frame_size = FRAMESIZE_240X240, // QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates. + .pixel_format = PIXFORMAT_JPEG, // YUV422,GRAYSCALE,RGB565,JPEG + .frame_size = FRAMESIZE_240X240, // QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has + // improved a lot, but JPEG mode always gives better frame rates. - .jpeg_quality = 8, // 0-63, for OV series camera sensors, lower number means higher quality // Below 6 stability problems - .fb_count = 2, // When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode. - .fb_location = CAMERA_FB_IN_DRAM, - .grab_mode = CAMERA_GRAB_WHEN_EMPTY, // was CAMERA_GRAB_LATEST; new mode reduces frame skips at cost of minor latency - }; + .jpeg_quality = 8, // 0-63, for OV series camera sensors, lower number means higher quality // Below 6 stability problems + .fb_count = 2, // When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode. + .fb_location = CAMERA_FB_IN_DRAM, + .grab_mode = CAMERA_GRAB_WHEN_EMPTY, // was CAMERA_GRAB_LATEST; new mode reduces frame skips at cost of minor latency + }; } void CameraManager::setupCameraSensor() { - ESP_LOGI(CAMERA_MANAGER_TAG, "Setting up camera sensor"); + ESP_LOGI(CAMERA_MANAGER_TAG, "Setting up camera sensor"); - camera_sensor = esp_camera_sensor_get(); - // fixes corrupted jpegs, https://github.com/espressif/esp32-camera/issues/203 - // documentation https://www.uctronics.com/download/cam_module/OV2640DS.pdf - camera_sensor->set_reg( - camera_sensor, 0xff, 0xff, - 0x00); // banksel, here we're directly writing to the registers. - // 0xFF==0x00 is the first bank, there's also 0xFF==0x01 - camera_sensor->set_reg(camera_sensor, 0xd3, 0xff, 5); // clock - camera_sensor->set_brightness(camera_sensor, 2); // -2 to 2 - camera_sensor->set_contrast(camera_sensor, 2); // -2 to 2 - camera_sensor->set_saturation(camera_sensor, -2); // -2 to 2 + camera_sensor = esp_camera_sensor_get(); + // fixes corrupted jpegs, https://github.com/espressif/esp32-camera/issues/203 + // documentation https://www.uctronics.com/download/cam_module/OV2640DS.pdf + camera_sensor->set_reg(camera_sensor, 0xff, 0xff, + 0x00); // banksel, here we're directly writing to the registers. + // 0xFF==0x00 is the first bank, there's also 0xFF==0x01 + camera_sensor->set_reg(camera_sensor, 0xd3, 0xff, 5); // clock + camera_sensor->set_brightness(camera_sensor, 2); // -2 to 2 + camera_sensor->set_contrast(camera_sensor, 2); // -2 to 2 + camera_sensor->set_saturation(camera_sensor, -2); // -2 to 2 - // white balance control - camera_sensor->set_whitebal(camera_sensor, 1); // 0 = disable , 1 = enable - camera_sensor->set_awb_gain(camera_sensor, 0); // 0 = disable , 1 = enable - camera_sensor->set_wb_mode(camera_sensor, - 0); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - - // Sunny, 2 - Cloudy, 3 - Office, 4 - Home) + // white balance control + camera_sensor->set_whitebal(camera_sensor, 1); // 0 = disable , 1 = enable + camera_sensor->set_awb_gain(camera_sensor, 0); // 0 = disable , 1 = enable + camera_sensor->set_wb_mode(camera_sensor, + 0); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - + // Sunny, 2 - Cloudy, 3 - Office, 4 - Home) - // controls the exposure - camera_sensor->set_exposure_ctrl(camera_sensor, - 0); // 0 = disable , 1 = enable - camera_sensor->set_aec2(camera_sensor, 0); // 0 = disable , 1 = enable - camera_sensor->set_ae_level(camera_sensor, 0); // -2 to 2 - camera_sensor->set_aec_value(camera_sensor, 300); // 0 to 1200 + // controls the exposure + camera_sensor->set_exposure_ctrl(camera_sensor, + 0); // 0 = disable , 1 = enable + camera_sensor->set_aec2(camera_sensor, 0); // 0 = disable , 1 = enable + camera_sensor->set_ae_level(camera_sensor, 0); // -2 to 2 + camera_sensor->set_aec_value(camera_sensor, 300); // 0 to 1200 - // controls the gain - camera_sensor->set_gain_ctrl(camera_sensor, 0); // 0 = disable , 1 = enable + // controls the gain + camera_sensor->set_gain_ctrl(camera_sensor, 0); // 0 = disable , 1 = enable - // automatic gain control gain, controls by how much the resulting image - // should be amplified - camera_sensor->set_agc_gain(camera_sensor, 2); // 0 to 30 - camera_sensor->set_gainceiling(camera_sensor, static_cast(6)); // 0 to 6 + // automatic gain control gain, controls by how much the resulting image + // should be amplified + camera_sensor->set_agc_gain(camera_sensor, 2); // 0 to 30 + camera_sensor->set_gainceiling(camera_sensor, static_cast(6)); // 0 to 6 - // black and white pixel correction, averages the white and black spots - camera_sensor->set_bpc(camera_sensor, 1); // 0 = disable , 1 = enable - camera_sensor->set_wpc(camera_sensor, 1); // 0 = disable , 1 = enable - // digital clamp white balance - camera_sensor->set_dcw(camera_sensor, 0); // 0 = disable , 1 = enable + // black and white pixel correction, averages the white and black spots + camera_sensor->set_bpc(camera_sensor, 1); // 0 = disable , 1 = enable + camera_sensor->set_wpc(camera_sensor, 1); // 0 = disable , 1 = enable + // digital clamp white balance + camera_sensor->set_dcw(camera_sensor, 0); // 0 = disable , 1 = enable - // gamma correction - camera_sensor->set_raw_gma( - camera_sensor, - 1); // 0 = disable , 1 = enable (makes much lighter and noisy) + // gamma correction + camera_sensor->set_raw_gma(camera_sensor, + 1); // 0 = disable , 1 = enable (makes much lighter and noisy) - camera_sensor->set_lenc(camera_sensor, 0); // 0 = disable , 1 = enable // 0 = - // disable , 1 = enable + camera_sensor->set_lenc(camera_sensor, 0); // 0 = disable , 1 = enable // 0 = + // disable , 1 = enable - camera_sensor->set_colorbar(camera_sensor, 0); // 0 = disable , 1 = enable + camera_sensor->set_colorbar(camera_sensor, 0); // 0 = disable , 1 = enable - camera_sensor->set_special_effect( - camera_sensor, - 2); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, - // 4 - Green Tint, 5 - Blue Tint, 6 - Sepia) + camera_sensor->set_special_effect(camera_sensor, + 2); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, + // 4 - Green Tint, 5 - Blue Tint, 6 - Sepia) - // it gets overriden somewhere somehow - camera_sensor->set_framesize(camera_sensor, FRAMESIZE_240X240); - ESP_LOGI(CAMERA_MANAGER_TAG, "Setting up camera sensor done"); + // it gets overriden somewhere somehow + camera_sensor->set_framesize(camera_sensor, FRAMESIZE_240X240); + ESP_LOGI(CAMERA_MANAGER_TAG, "Setting up camera sensor done"); } bool CameraManager::setupCamera() { - ESP_LOGI(CAMERA_MANAGER_TAG, "Setting up camera pinout"); - this->setupCameraPinout(); - ESP_LOGI(CAMERA_MANAGER_TAG, "Initializing camera..."); + ESP_LOGI(CAMERA_MANAGER_TAG, "Setting up camera pinout"); + this->setupCameraPinout(); + ESP_LOGI(CAMERA_MANAGER_TAG, "Initializing camera..."); - if (auto const hasCameraBeenInitialized = esp_camera_init(&config); hasCameraBeenInitialized == ESP_OK) - { - ESP_LOGI(CAMERA_MANAGER_TAG, "Camera initialized: %s \r\n", - esp_err_to_name(hasCameraBeenInitialized)); + if (auto const hasCameraBeenInitialized = esp_camera_init(&config); hasCameraBeenInitialized == ESP_OK) + { + ESP_LOGI(CAMERA_MANAGER_TAG, "Camera initialized: %s \r\n", esp_err_to_name(hasCameraBeenInitialized)); - constexpr auto event = SystemEvent{EventSource::CAMERA, CameraState_e::Camera_Success}; - xQueueSend(this->eventQueue, &event, 10); - } - else - { - ESP_LOGE(CAMERA_MANAGER_TAG, "Camera initialization failed with error: %s \r\n", - esp_err_to_name(hasCameraBeenInitialized)); - ESP_LOGE(CAMERA_MANAGER_TAG, "Camera most likely not seated properly in the socket. " - "Please " - "fix the " - "camera and reboot the device.\r\n"); - constexpr auto event = SystemEvent{EventSource::CAMERA, CameraState_e::Camera_Error}; - xQueueSend(this->eventQueue, &event, 10); - return false; - } + constexpr auto event = SystemEvent{EventSource::CAMERA, CameraState_e::Camera_Success}; + xQueueSend(this->eventQueue, &event, 10); + } + else + { + ESP_LOGE(CAMERA_MANAGER_TAG, "Camera initialization failed with error: %s \r\n", esp_err_to_name(hasCameraBeenInitialized)); + ESP_LOGE(CAMERA_MANAGER_TAG, + "Camera most likely not seated properly in the socket. " + "Please " + "fix the " + "camera and reboot the device.\r\n"); + constexpr auto event = SystemEvent{EventSource::CAMERA, CameraState_e::Camera_Error}; + xQueueSend(this->eventQueue, &event, 10); + return false; + } #if CONFIG_GENERAL_INCLUDE_UVC_MODE - const auto temp_sensor = esp_camera_sensor_get(); + const auto temp_sensor = esp_camera_sensor_get(); - // Thanks to lick_it, we discovered that OV5640 likes to overheat when - // running at higher than usual xclk frequencies. - // Hence, why we're limiting the faster ones for OV2640 - if (const auto camera_id = temp_sensor->id.PID; camera_id == OV5640_PID) - { - config.xclk_freq_hz = OV5640_XCLK_FREQ_HZ; - esp_camera_deinit(); - esp_camera_init(&config); - } + // Thanks to lick_it, we discovered that OV5640 likes to overheat when + // running at higher than usual xclk frequencies. + // Hence, why we're limiting the faster ones for OV2640 + if (const auto camera_id = temp_sensor->id.PID; camera_id == OV5640_PID) + { + config.xclk_freq_hz = OV5640_XCLK_FREQ_HZ; + esp_camera_deinit(); + esp_camera_init(&config); + } #endif - this->setupCameraSensor(); - return true; + this->setupCameraSensor(); + return true; } void CameraManager::loadConfigData() { - ESP_LOGD(CAMERA_MANAGER_TAG, "Loading camera config data"); - CameraConfig_t cameraConfig = projectConfig->getCameraConfig(); - this->setHFlip(cameraConfig.href); - this->setVFlip(cameraConfig.vflip); - this->setCameraResolution(static_cast(cameraConfig.framesize)); - camera_sensor->set_quality(camera_sensor, cameraConfig.quality); - camera_sensor->set_agc_gain(camera_sensor, cameraConfig.brightness); - ESP_LOGD(CAMERA_MANAGER_TAG, "Loading camera config data done"); + ESP_LOGD(CAMERA_MANAGER_TAG, "Loading camera config data"); + CameraConfig_t cameraConfig = projectConfig->getCameraConfig(); + this->setHFlip(cameraConfig.href); + this->setVFlip(cameraConfig.vflip); + this->setCameraResolution(static_cast(cameraConfig.framesize)); + camera_sensor->set_quality(camera_sensor, cameraConfig.quality); + camera_sensor->set_agc_gain(camera_sensor, cameraConfig.brightness); + ESP_LOGD(CAMERA_MANAGER_TAG, "Loading camera config data done"); } int CameraManager::setCameraResolution(const framesize_t frameSize) { - if (camera_sensor->pixformat == PIXFORMAT_JPEG) - { - return camera_sensor->set_framesize(camera_sensor, frameSize); - } - return -1; + if (camera_sensor->pixformat == PIXFORMAT_JPEG) + { + return camera_sensor->set_framesize(camera_sensor, frameSize); + } + return -1; } int CameraManager::setVFlip(const int direction) { - return camera_sensor->set_vflip(camera_sensor, direction); + return camera_sensor->set_vflip(camera_sensor, direction); } int CameraManager::setHFlip(const int direction) { - return camera_sensor->set_hmirror(camera_sensor, direction); + return camera_sensor->set_hmirror(camera_sensor, direction); } -int CameraManager::setVieWindow(int offsetX, - int offsetY, - int outputX, - int outputY) +int CameraManager::setVieWindow(int offsetX, int offsetY, int outputX, int outputY) { - - // todo safariMonkey made a PoC, implement it here - return 0; + // todo safariMonkey made a PoC, implement it here + return 0; } \ No newline at end of file diff --git a/components/CameraManager/CameraManager/CameraManager.hpp b/components/CameraManager/CameraManager/CameraManager.hpp index 390cfcf..21c952a 100644 --- a/components/CameraManager/CameraManager/CameraManager.hpp +++ b/components/CameraManager/CameraManager/CameraManager.hpp @@ -2,40 +2,40 @@ #ifndef CAMERAMANAGER_HPP #define CAMERAMANAGER_HPP -#include "esp_log.h" -#include "esp_camera.h" #include "driver/gpio.h" +#include "esp_camera.h" +#include "esp_log.h" #include "esp_psram.h" #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" -#include #include +#include #define OV5640_XCLK_FREQ_HZ CONFIG_CAMERA_WIFI_XCLK_FREQ class CameraManager { -private: - sensor_t *camera_sensor; - std::shared_ptr projectConfig; - QueueHandle_t eventQueue; - camera_config_t config; + private: + sensor_t* camera_sensor; + std::shared_ptr projectConfig; + QueueHandle_t eventQueue; + camera_config_t config; -public: - CameraManager(std::shared_ptr projectConfig, QueueHandle_t eventQueue); - int setCameraResolution(framesize_t frameSize); - bool setupCamera(); - int setVFlip(int direction); - int setHFlip(int direction); - int setVieWindow(int offsetX, int offsetY, int outputX, int outputY); + public: + CameraManager(std::shared_ptr projectConfig, QueueHandle_t eventQueue); + int setCameraResolution(framesize_t frameSize); + bool setupCamera(); + int setVFlip(int direction); + int setHFlip(int direction); + int setVieWindow(int offsetX, int offsetY, int outputX, int outputY); -private: - void loadConfigData(); - void setupCameraPinout(); - void setupCameraSensor(); + private: + void loadConfigData(); + void setupCameraPinout(); + void setupCameraSensor(); }; -#endif // CAMERAMANAGER_HPP \ No newline at end of file +#endif // CAMERAMANAGER_HPP \ No newline at end of file diff --git a/components/CommandManager/CommandManager/CommandManager.cpp b/components/CommandManager/CommandManager/CommandManager.cpp index 61dc9bf..295eca3 100644 --- a/components/CommandManager/CommandManager/CommandManager.cpp +++ b/components/CommandManager/CommandManager/CommandManager.cpp @@ -30,140 +30,117 @@ std::unordered_map commandTypeMap = { {"get_who_am_i", CommandType::GET_WHO_AM_I}, }; -std::function CommandManager::createCommand(const CommandType type, const nlohmann::json &json) const +std::function CommandManager::createCommand(const CommandType type, const nlohmann::json& json) const { - switch (type) - { - case CommandType::PING: - return {PingCommand}; - case CommandType::PAUSE: - return [json] - { return PauseCommand(json); }; - case CommandType::UPDATE_OTA_CREDENTIALS: - return [this, json] - { return updateOTACredentialsCommand(this->registry, json); }; - case CommandType::SET_WIFI: - return [this, json] - { return setWiFiCommand(this->registry, json); }; - case CommandType::UPDATE_WIFI: - return [this, json] - { return updateWiFiCommand(this->registry, json); }; - case CommandType::UPDATE_AP_WIFI: - return [this, json] - { return updateAPWiFiCommand(this->registry, json); }; - case CommandType::DELETE_NETWORK: - return [this, json] - { return deleteWiFiCommand(this->registry, json); }; - case CommandType::SET_MDNS: - return [this, json] - { return setMDNSCommand(this->registry, json); }; - case CommandType::GET_MDNS_NAME: - return [this] - { return getMDNSNameCommand(this->registry); }; - case CommandType::UPDATE_CAMERA: - return [this, json] - { return updateCameraCommand(this->registry, json); }; - case CommandType::GET_CONFIG: - return [this] - { return getConfigCommand(this->registry); }; - case CommandType::SAVE_CONFIG: - return [this] - { return saveConfigCommand(this->registry); }; - case CommandType::RESET_CONFIG: - return [this, json] - { return resetConfigCommand(this->registry, json); }; - case CommandType::RESTART_DEVICE: - return restartDeviceCommand; - case CommandType::SCAN_NETWORKS: - return [this, json] - { return scanNetworksCommand(this->registry, json); }; - case CommandType::START_STREAMING: - return startStreamingCommand; - case CommandType::GET_WIFI_STATUS: - return [this] - { return getWiFiStatusCommand(this->registry); }; - case CommandType::CONNECT_WIFI: - return [this] - { return connectWiFiCommand(this->registry); }; - case CommandType::SWITCH_MODE: - return [this, json] - { return switchModeCommand(this->registry, json); }; - case CommandType::GET_DEVICE_MODE: - return [this] - { return getDeviceModeCommand(this->registry); }; - case CommandType::SET_LED_DUTY_CYCLE: - return [this, json] - { return updateLEDDutyCycleCommand(this->registry, json); }; - case CommandType::GET_LED_DUTY_CYCLE: - return [this] - { return getLEDDutyCycleCommand(this->registry); }; - case CommandType::GET_SERIAL: - return [this] - { return getSerialNumberCommand(this->registry); }; - case CommandType::GET_LED_CURRENT: - return [this] - { return getLEDCurrentCommand(this->registry); }; - case CommandType::GET_BATTERY_STATUS: - return [this] - { return getBatteryStatusCommand(this->registry); }; - case CommandType::GET_WHO_AM_I: - return [this] - { return getInfoCommand(this->registry); }; - default: - return nullptr; - } + switch (type) + { + case CommandType::PING: + return {PingCommand}; + case CommandType::PAUSE: + return [json] { return PauseCommand(json); }; + case CommandType::UPDATE_OTA_CREDENTIALS: + return [this, json] { return updateOTACredentialsCommand(this->registry, json); }; + case CommandType::SET_WIFI: + return [this, json] { return setWiFiCommand(this->registry, json); }; + case CommandType::UPDATE_WIFI: + return [this, json] { return updateWiFiCommand(this->registry, json); }; + case CommandType::UPDATE_AP_WIFI: + return [this, json] { return updateAPWiFiCommand(this->registry, json); }; + case CommandType::DELETE_NETWORK: + return [this, json] { return deleteWiFiCommand(this->registry, json); }; + case CommandType::SET_MDNS: + return [this, json] { return setMDNSCommand(this->registry, json); }; + case CommandType::GET_MDNS_NAME: + return [this] { return getMDNSNameCommand(this->registry); }; + case CommandType::UPDATE_CAMERA: + return [this, json] { return updateCameraCommand(this->registry, json); }; + case CommandType::GET_CONFIG: + return [this] { return getConfigCommand(this->registry); }; + case CommandType::SAVE_CONFIG: + return [this] { return saveConfigCommand(this->registry); }; + case CommandType::RESET_CONFIG: + return [this, json] { return resetConfigCommand(this->registry, json); }; + case CommandType::RESTART_DEVICE: + return restartDeviceCommand; + case CommandType::SCAN_NETWORKS: + return [this, json] { return scanNetworksCommand(this->registry, json); }; + case CommandType::START_STREAMING: + return startStreamingCommand; + case CommandType::GET_WIFI_STATUS: + return [this] { return getWiFiStatusCommand(this->registry); }; + case CommandType::CONNECT_WIFI: + return [this] { return connectWiFiCommand(this->registry); }; + case CommandType::SWITCH_MODE: + return [this, json] { return switchModeCommand(this->registry, json); }; + case CommandType::GET_DEVICE_MODE: + return [this] { return getDeviceModeCommand(this->registry); }; + case CommandType::SET_LED_DUTY_CYCLE: + return [this, json] { return updateLEDDutyCycleCommand(this->registry, json); }; + case CommandType::GET_LED_DUTY_CYCLE: + return [this] { return getLEDDutyCycleCommand(this->registry); }; + case CommandType::GET_SERIAL: + return [this] { return getSerialNumberCommand(this->registry); }; + case CommandType::GET_LED_CURRENT: + return [this] { return getLEDCurrentCommand(this->registry); }; + case CommandType::GET_BATTERY_STATUS: + return [this] { return getBatteryStatusCommand(this->registry); }; + case CommandType::GET_WHO_AM_I: + return [this] { return getInfoCommand(this->registry); }; + default: + return nullptr; + } } CommandManagerResponse CommandManager::executeFromJson(const std::string_view json) const { - if (!nlohmann::json::accept(json)) - { - return CommandManagerResponse(nlohmann::json{{"error", "Initial JSON Parse - Invalid JSON"}}); - } - - nlohmann::json parsedJson = nlohmann::json::parse(json); - if (!parsedJson.contains("commands") || !parsedJson["commands"].is_array() || parsedJson["commands"].empty()) - { - return CommandManagerResponse(CommandResult::getErrorResult("Commands missing")); - } - - nlohmann::json results = nlohmann::json::array(); - - for (auto &commandObject : parsedJson["commands"].items()) - { - auto commandData = commandObject.value(); - if (!commandData.contains("command")) + if (!nlohmann::json::accept(json)) { - return CommandManagerResponse({{"command", "Unknown command"}, {"error", "Missing command type"}}); + return CommandManagerResponse(nlohmann::json{{"error", "Initial JSON Parse - Invalid JSON"}}); } - const auto commandName = commandData["command"].get(); - if (!commandTypeMap.contains(commandName)) + nlohmann::json parsedJson = nlohmann::json::parse(json); + if (!parsedJson.contains("commands") || !parsedJson["commands"].is_array() || parsedJson["commands"].empty()) { - return CommandManagerResponse({{"command", commandName}, {"error", "Unknown command"}}); + return CommandManagerResponse(CommandResult::getErrorResult("Commands missing")); } - const auto commandType = commandTypeMap.at(commandName); - const auto commandPayload = commandData.contains("data") ? commandData["data"] : nlohmann::json::object(); + nlohmann::json results = nlohmann::json::array(); - auto command = createCommand(commandType, commandPayload); - results.push_back({ - {"command", commandName}, - {"result", command()}, - }); - } - auto response = nlohmann::json{{"results", results}}; - return CommandManagerResponse(response); + for (auto& commandObject : parsedJson["commands"].items()) + { + auto commandData = commandObject.value(); + if (!commandData.contains("command")) + { + return CommandManagerResponse({{"command", "Unknown command"}, {"error", "Missing command type"}}); + } + + const auto commandName = commandData["command"].get(); + if (!commandTypeMap.contains(commandName)) + { + return CommandManagerResponse({{"command", commandName}, {"error", "Unknown command"}}); + } + + const auto commandType = commandTypeMap.at(commandName); + const auto commandPayload = commandData.contains("data") ? commandData["data"] : nlohmann::json::object(); + + auto command = createCommand(commandType, commandPayload); + results.push_back({ + {"command", commandName}, + {"result", command()}, + }); + } + auto response = nlohmann::json{{"results", results}}; + return CommandManagerResponse(response); } CommandManagerResponse CommandManager::executeFromType(const CommandType type, const std::string_view json) const { - const auto command = createCommand(type, json); + const auto command = createCommand(type, json); - if (command == nullptr) - { - return CommandManagerResponse({{"command", type}, {"error", "Unknown command"}}); - } + if (command == nullptr) + { + return CommandManagerResponse({{"command", type}, {"error", "Unknown command"}}); + } - return CommandManagerResponse(nlohmann::json{{"result", command()}}); + return CommandManagerResponse(nlohmann::json{{"result", command()}}); } \ No newline at end of file diff --git a/components/CommandManager/CommandManager/CommandManager.hpp b/components/CommandManager/CommandManager/CommandManager.hpp index 1ddc5ad..c74e3ff 100644 --- a/components/CommandManager/CommandManager/CommandManager.hpp +++ b/components/CommandManager/CommandManager/CommandManager.hpp @@ -1,66 +1,66 @@ #ifndef COMMANDMANAGER_HPP #define COMMANDMANAGER_HPP -#include #include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include +#include #include "CommandResult.hpp" #include "CommandSchema.hpp" #include "DependencyRegistry.hpp" -#include "commands/simple_commands.hpp" #include "commands/camera_commands.hpp" #include "commands/config_commands.hpp" -#include "commands/mdns_commands.hpp" -#include "commands/wifi_commands.hpp" #include "commands/device_commands.hpp" +#include "commands/mdns_commands.hpp" #include "commands/scan_commands.hpp" -#include +#include "commands/simple_commands.hpp" +#include "commands/wifi_commands.hpp" enum class CommandType { - None, - PING, - PAUSE, - SET_WIFI, - UPDATE_OTA_CREDENTIALS, - UPDATE_WIFI, - DELETE_NETWORK, - UPDATE_AP_WIFI, - SET_MDNS, - GET_MDNS_NAME, - UPDATE_CAMERA, - SAVE_CONFIG, - GET_CONFIG, - RESET_CONFIG, - RESTART_DEVICE, - SCAN_NETWORKS, - START_STREAMING, - GET_WIFI_STATUS, - CONNECT_WIFI, - SWITCH_MODE, - GET_DEVICE_MODE, - SET_LED_DUTY_CYCLE, - GET_LED_DUTY_CYCLE, - GET_SERIAL, - GET_LED_CURRENT, - GET_BATTERY_STATUS, - GET_WHO_AM_I, + None, + PING, + PAUSE, + SET_WIFI, + UPDATE_OTA_CREDENTIALS, + UPDATE_WIFI, + DELETE_NETWORK, + UPDATE_AP_WIFI, + SET_MDNS, + GET_MDNS_NAME, + UPDATE_CAMERA, + SAVE_CONFIG, + GET_CONFIG, + RESET_CONFIG, + RESTART_DEVICE, + SCAN_NETWORKS, + START_STREAMING, + GET_WIFI_STATUS, + CONNECT_WIFI, + SWITCH_MODE, + GET_DEVICE_MODE, + SET_LED_DUTY_CYCLE, + GET_LED_DUTY_CYCLE, + GET_SERIAL, + GET_LED_CURRENT, + GET_BATTERY_STATUS, + GET_WHO_AM_I, }; class CommandManager { - std::shared_ptr registry; + std::shared_ptr registry; -public: - explicit CommandManager(const std::shared_ptr &DependencyRegistry) : registry(DependencyRegistry) {}; - std::function createCommand(const CommandType type, const nlohmann::json &json) const; + public: + explicit CommandManager(const std::shared_ptr& DependencyRegistry) : registry(DependencyRegistry) {}; + std::function createCommand(const CommandType type, const nlohmann::json& json) const; - CommandManagerResponse executeFromJson(std::string_view json) const; - CommandManagerResponse executeFromType(CommandType type, std::string_view json) const; + CommandManagerResponse executeFromJson(std::string_view json) const; + CommandManagerResponse executeFromType(CommandType type, std::string_view json) const; }; #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/CommandResult.cpp b/components/CommandManager/CommandManager/CommandResult.cpp index 9396908..a6542c9 100644 --- a/components/CommandManager/CommandManager/CommandResult.cpp +++ b/components/CommandManager/CommandManager/CommandResult.cpp @@ -1,24 +1,24 @@ #include "CommandResult.hpp" -void to_json(nlohmann::json &j, const CommandResult &result) +void to_json(nlohmann::json& j, const CommandResult& result) { - j = nlohmann::json{{"status", result.isSuccess() ? "success" : "error"}, {"data", result.getData()}}; + j = nlohmann::json{{"status", result.isSuccess() ? "success" : "error"}, {"data", result.getData()}}; } // defined only for interface compatibility, should not be used directly -void from_json(const nlohmann::json &j, CommandResult &result) +void from_json(const nlohmann::json& j, CommandResult& result) { - auto message = j.at("message"); - j.at("status") == "success" ? result = CommandResult::getSuccessResult(message) : result = CommandResult::getErrorResult(message); + auto message = j.at("message"); + j.at("status") == "success" ? result = CommandResult::getSuccessResult(message) : result = CommandResult::getErrorResult(message); } -void to_json(nlohmann::json &j, const CommandManagerResponse &result) +void to_json(nlohmann::json& j, const CommandManagerResponse& result) { - j = result.getData(); + j = result.getData(); } // defined only for interface compatibility, should not be used directly -void from_json(const nlohmann::json &j, CommandManagerResponse &result) +void from_json(const nlohmann::json& j, CommandManagerResponse& result) { - result = CommandManagerResponse(j.at("result")); + result = CommandManagerResponse(j.at("result")); } \ No newline at end of file diff --git a/components/CommandManager/CommandManager/CommandResult.hpp b/components/CommandManager/CommandManager/CommandResult.hpp index 9dee2b0..beb1c49 100644 --- a/components/CommandManager/CommandManager/CommandResult.hpp +++ b/components/CommandManager/CommandManager/CommandResult.hpp @@ -2,58 +2,67 @@ #ifndef COMMAND_RESULT #define COMMAND_RESULT -#include -#include #include +#include #include +#include using json = nlohmann::json; class CommandResult { -public: - enum class Status - { - SUCCESS, - FAILURE, - }; + public: + enum class Status + { + SUCCESS, + FAILURE, + }; -private: - nlohmann::json data; - Status status; + private: + nlohmann::json data; + Status status; -public: - CommandResult(nlohmann::json data, const Status status) : data(data), status(status) {} + public: + CommandResult(nlohmann::json data, const Status status) : data(data), status(status) {} - bool isSuccess() const { return status == Status::SUCCESS; } + bool isSuccess() const + { + return status == Status::SUCCESS; + } - static CommandResult getSuccessResult(nlohmann::json message) - { - return CommandResult(message, Status::SUCCESS); - } + static CommandResult getSuccessResult(nlohmann::json message) + { + return CommandResult(message, Status::SUCCESS); + } - static CommandResult getErrorResult(nlohmann::json message) - { - return CommandResult(message, Status::FAILURE); - } + static CommandResult getErrorResult(nlohmann::json message) + { + return CommandResult(message, Status::FAILURE); + } - nlohmann::json getData() const { return this->data; } + nlohmann::json getData() const + { + return this->data; + } }; -void to_json(nlohmann::json &j, const CommandResult &result); -void from_json(const nlohmann::json &j, CommandResult &result); +void to_json(nlohmann::json& j, const CommandResult& result); +void from_json(const nlohmann::json& j, CommandResult& result); class CommandManagerResponse { -private: - nlohmann::json data; + private: + nlohmann::json data; -public: - CommandManagerResponse(nlohmann::json data) : data(data) {} - nlohmann::json getData() const { return this->data; } + public: + CommandManagerResponse(nlohmann::json data) : data(data) {} + nlohmann::json getData() const + { + return this->data; + } }; -void to_json(nlohmann::json &j, const CommandManagerResponse &result); -void from_json(const nlohmann::json &j, CommandManagerResponse &result); +void to_json(nlohmann::json& j, const CommandManagerResponse& result); +void from_json(const nlohmann::json& j, CommandManagerResponse& result); #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/CommandSchema.cpp b/components/CommandManager/CommandManager/CommandSchema.cpp index 2ecead6..236f0ca 100644 --- a/components/CommandManager/CommandManager/CommandSchema.cpp +++ b/components/CommandManager/CommandManager/CommandSchema.cpp @@ -1,81 +1,82 @@ #include "CommandSchema.hpp" -void to_json(nlohmann::json &j, const UpdateWifiPayload &payload) +void to_json(nlohmann::json& j, const UpdateWifiPayload& payload) { - j = nlohmann::json{{"name", payload.name}, {"ssid", payload.ssid}, {"password", payload.password}, {"channel", payload.channel}, {"power", payload.power}}; + j = nlohmann::json{{"name", payload.name}, {"ssid", payload.ssid}, {"password", payload.password}, {"channel", payload.channel}, {"power", payload.power}}; } -void from_json(const nlohmann::json &j, UpdateWifiPayload &payload) +void from_json(const nlohmann::json& j, UpdateWifiPayload& payload) { - payload.name = j.at("name").get(); - if (j.contains("ssid")) - { - payload.ssid = j.at("ssid").get(); - } + payload.name = j.at("name").get(); + if (j.contains("ssid")) + { + payload.ssid = j.at("ssid").get(); + } - if (j.contains("password")) - { - payload.password = j.at("password").get(); - } + if (j.contains("password")) + { + payload.password = j.at("password").get(); + } - if (j.contains("channel")) - { - payload.channel = j.at("channel").get(); - } + if (j.contains("channel")) + { + payload.channel = j.at("channel").get(); + } - if (j.contains("power")) - { - payload.power = j.at("power").get(); - } + if (j.contains("power")) + { + payload.power = j.at("power").get(); + } } -void to_json(nlohmann::json &j, const UpdateAPWiFiPayload &payload) +void to_json(nlohmann::json& j, const UpdateAPWiFiPayload& payload) { - j = nlohmann::json{{"ssid", payload.ssid}, {"password", payload.password}, {"channel", payload.channel}}; + j = nlohmann::json{{"ssid", payload.ssid}, {"password", payload.password}, {"channel", payload.channel}}; } -void from_json(const nlohmann::json &j, UpdateAPWiFiPayload &payload) +void from_json(const nlohmann::json& j, UpdateAPWiFiPayload& payload) { - if (j.contains("ssid")) - { - payload.ssid = j.at("ssid").get(); - } + if (j.contains("ssid")) + { + payload.ssid = j.at("ssid").get(); + } - if (j.contains("password")) - { - payload.password = j.at("password").get(); - } - if (j.contains("channel")) - { - payload.channel = j.at("channel").get(); - } + if (j.contains("password")) + { + payload.password = j.at("password").get(); + } + if (j.contains("channel")) + { + payload.channel = j.at("channel").get(); + } } -void to_json(nlohmann::json &j, const UpdateCameraConfigPayload &payload) +void to_json(nlohmann::json& j, const UpdateCameraConfigPayload& payload) { - j = nlohmann::json{{"vflip", payload.vflip}, {"href", payload.href}, {"framesize", payload.framesize}, {"quality", payload.quality}, {"brightness", payload.brightness}}; + j = nlohmann::json{ + {"vflip", payload.vflip}, {"href", payload.href}, {"framesize", payload.framesize}, {"quality", payload.quality}, {"brightness", payload.brightness}}; } -void from_json(const nlohmann::json &j, UpdateCameraConfigPayload &payload) +void from_json(const nlohmann::json& j, UpdateCameraConfigPayload& payload) { - if (j.contains("vflip")) - { - payload.vflip = j.at("vflip").get(); - } - if (j.contains("href")) - { - payload.href = j.at("href").get(); - } - if (j.contains("framesize")) - { - payload.framesize = j.at("framesize").get(); - } - if (j.contains("quality")) - { - payload.quality = j.at("quality").get(); - } - if (j.contains("brightness")) - { - payload.brightness = j.at("brightness").get(); - } + if (j.contains("vflip")) + { + payload.vflip = j.at("vflip").get(); + } + if (j.contains("href")) + { + payload.href = j.at("href").get(); + } + if (j.contains("framesize")) + { + payload.framesize = j.at("framesize").get(); + } + if (j.contains("quality")) + { + payload.quality = j.at("quality").get(); + } + if (j.contains("brightness")) + { + payload.brightness = j.at("brightness").get(); + } } \ No newline at end of file diff --git a/components/CommandManager/CommandManager/CommandSchema.hpp b/components/CommandManager/CommandManager/CommandSchema.hpp index ee761dc..171a5f7 100644 --- a/components/CommandManager/CommandManager/CommandSchema.hpp +++ b/components/CommandManager/CommandManager/CommandSchema.hpp @@ -8,59 +8,59 @@ struct BasePayload struct WifiPayload : BasePayload { - std::string name; - std::string ssid; - std::string password; - uint8_t channel; - uint8_t power; + std::string name; + std::string ssid; + std::string password; + uint8_t channel; + uint8_t power; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(WifiPayload, name, ssid, password, channel, power) struct UpdateWifiPayload : BasePayload { - std::string name; - std::optional ssid; - std::optional password; - std::optional channel; - std::optional power; + std::string name; + std::optional ssid; + std::optional password; + std::optional channel; + std::optional power; }; -void to_json(nlohmann::json &j, const UpdateWifiPayload &payload); -void from_json(const nlohmann::json &j, UpdateWifiPayload &payload); +void to_json(nlohmann::json& j, const UpdateWifiPayload& payload); +void from_json(const nlohmann::json& j, UpdateWifiPayload& payload); struct deleteNetworkPayload : BasePayload { - std::string name; + std::string name; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(deleteNetworkPayload, name) struct UpdateAPWiFiPayload : BasePayload { - std::optional ssid; - std::optional password; - std::optional channel; + std::optional ssid; + std::optional password; + std::optional channel; }; -void to_json(nlohmann::json &j, const UpdateAPWiFiPayload &payload); -void from_json(const nlohmann::json &j, UpdateAPWiFiPayload &payload); +void to_json(nlohmann::json& j, const UpdateAPWiFiPayload& payload); +void from_json(const nlohmann::json& j, UpdateAPWiFiPayload& payload); struct MDNSPayload : BasePayload { - std::string hostname; + std::string hostname; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(MDNSPayload, hostname) struct UpdateCameraConfigPayload : BasePayload { - std::optional vflip; - std::optional href; - std::optional framesize; - std::optional quality; - std::optional brightness; - // TODO add more options here + std::optional vflip; + std::optional href; + std::optional framesize; + std::optional quality; + std::optional brightness; + // TODO add more options here }; -void to_json(nlohmann::json &j, const UpdateCameraConfigPayload &payload); -void from_json(const nlohmann::json &j, UpdateCameraConfigPayload &payload); +void to_json(nlohmann::json& j, const UpdateCameraConfigPayload& payload); +void from_json(const nlohmann::json& j, UpdateCameraConfigPayload& payload); #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/DependencyRegistry.hpp b/components/CommandManager/CommandManager/DependencyRegistry.hpp index 28d3df4..1b29d21 100644 --- a/components/CommandManager/CommandManager/DependencyRegistry.hpp +++ b/components/CommandManager/CommandManager/DependencyRegistry.hpp @@ -6,35 +6,35 @@ enum class DependencyType { - project_config, - camera_manager, - wifi_manager, - led_manager, - monitoring_manager + project_config, + camera_manager, + wifi_manager, + led_manager, + monitoring_manager }; class DependencyRegistry { - std::unordered_map> services; + std::unordered_map> services; -public: - template - void registerService(DependencyType dependencyType, std::shared_ptr service) - { - this->services[dependencyType] = std::static_pointer_cast(service); - } - - template - std::shared_ptr resolve(DependencyType dependencyType) - { - auto serviceIT = this->services.find(dependencyType); - if (serviceIT != this->services.end()) + public: + template + void registerService(DependencyType dependencyType, std::shared_ptr service) { - return std::static_pointer_cast(serviceIT->second); + this->services[dependencyType] = std::static_pointer_cast(service); } - return nullptr; - } + template + std::shared_ptr resolve(DependencyType dependencyType) + { + auto serviceIT = this->services.find(dependencyType); + if (serviceIT != this->services.end()) + { + return std::static_pointer_cast(serviceIT->second); + } + + return nullptr; + } }; #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/camera_commands.cpp b/components/CommandManager/CommandManager/commands/camera_commands.cpp index b58dc62..e17a175 100644 --- a/components/CommandManager/CommandManager/commands/camera_commands.cpp +++ b/components/CommandManager/CommandManager/commands/camera_commands.cpp @@ -1,17 +1,15 @@ #include "camera_commands.hpp" -CommandResult updateCameraCommand(std::shared_ptr registry, const nlohmann::json &json) +CommandResult updateCameraCommand(std::shared_ptr registry, const nlohmann::json& json) { - auto payload = json.get(); + auto payload = json.get(); - std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); - auto oldConfig = projectConfig->getCameraConfig(); - projectConfig->setCameraConfig( - payload.vflip.has_value() ? payload.vflip.value() : oldConfig.vflip, - payload.framesize.has_value() ? payload.framesize.value() : oldConfig.framesize, - payload.href.has_value() ? payload.href.value() : oldConfig.href, - payload.quality.has_value() ? payload.quality.value() : oldConfig.quality, - payload.brightness.has_value() ? payload.brightness.value() : oldConfig.brightness); + std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); + auto oldConfig = projectConfig->getCameraConfig(); + projectConfig->setCameraConfig( + payload.vflip.has_value() ? payload.vflip.value() : oldConfig.vflip, payload.framesize.has_value() ? payload.framesize.value() : oldConfig.framesize, + payload.href.has_value() ? payload.href.value() : oldConfig.href, payload.quality.has_value() ? payload.quality.value() : oldConfig.quality, + payload.brightness.has_value() ? payload.brightness.value() : oldConfig.brightness); - return CommandResult::getSuccessResult("Config updated"); + return CommandResult::getSuccessResult("Config updated"); } \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/camera_commands.hpp b/components/CommandManager/CommandManager/commands/camera_commands.hpp index 81780b9..7dd5e57 100644 --- a/components/CommandManager/CommandManager/commands/camera_commands.hpp +++ b/components/CommandManager/CommandManager/commands/camera_commands.hpp @@ -1,16 +1,16 @@ #ifndef CAMERA_COMMANDS_HPP #define CAMERA_COMMANDS_HPP +#include #include #include -#include +#include #include +#include #include "CommandResult.hpp" #include "CommandSchema.hpp" #include "DependencyRegistry.hpp" -#include -#include -CommandResult updateCameraCommand(std::shared_ptr registry, const nlohmann::json &json); +CommandResult updateCameraCommand(std::shared_ptr registry, const nlohmann::json& json); #endif diff --git a/components/CommandManager/CommandManager/commands/config_commands.cpp b/components/CommandManager/CommandManager/commands/config_commands.cpp index b6fa289..e6a9b40 100644 --- a/components/CommandManager/CommandManager/commands/config_commands.cpp +++ b/components/CommandManager/CommandManager/commands/config_commands.cpp @@ -2,45 +2,45 @@ CommandResult saveConfigCommand(std::shared_ptr registry) { - std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); + std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); - projectConfig->save(); - return CommandResult::getSuccessResult("Config saved"); + projectConfig->save(); + return CommandResult::getSuccessResult("Config saved"); } CommandResult getConfigCommand(std::shared_ptr registry) { - std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); + std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); - auto configRepresentation = projectConfig->getTrackerConfig().toRepresentation(); - return CommandResult::getSuccessResult(configRepresentation); + auto configRepresentation = projectConfig->getTrackerConfig().toRepresentation(); + return CommandResult::getSuccessResult(configRepresentation); } -CommandResult resetConfigCommand(std::shared_ptr registry, const nlohmann::json &json) +CommandResult resetConfigCommand(std::shared_ptr registry, const nlohmann::json& json) { - std::array supported_sections = { - "all", - }; + std::array supported_sections = { + "all", + }; - if (!json.contains("section")) - { - return CommandResult::getErrorResult("Invalid payload - missing section"); - } + if (!json.contains("section")) + { + return CommandResult::getErrorResult("Invalid payload - missing section"); + } - auto section = json["section"].get(); + auto section = json["section"].get(); - if (std::find(supported_sections.begin(), supported_sections.end(), section) == supported_sections.end()) - { - return CommandResult::getErrorResult("Selected section is unsupported"); - } + if (std::find(supported_sections.begin(), supported_sections.end(), section) == supported_sections.end()) + { + return CommandResult::getErrorResult("Selected section is unsupported"); + } - // we cannot match on string, and making a map would be overkill right now, sooo - // todo, add more granular control for other sections, like only reset camera, or only reset wifi - if (section == "all") - { - std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); - projectConfig->reset(); - } + // we cannot match on string, and making a map would be overkill right now, sooo + // todo, add more granular control for other sections, like only reset camera, or only reset wifi + if (section == "all") + { + std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); + projectConfig->reset(); + } - return CommandResult::getSuccessResult("Config reset"); + return CommandResult::getSuccessResult("Config reset"); } \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/config_commands.hpp b/components/CommandManager/CommandManager/commands/config_commands.hpp index 337d267..e1e52f6 100644 --- a/components/CommandManager/CommandManager/commands/config_commands.hpp +++ b/components/CommandManager/CommandManager/commands/config_commands.hpp @@ -1,13 +1,13 @@ #include #include -#include +#include #include +#include #include "CommandResult.hpp" #include "CommandSchema.hpp" #include "DependencyRegistry.hpp" -#include CommandResult saveConfigCommand(std::shared_ptr registry); CommandResult getConfigCommand(std::shared_ptr registry); -CommandResult resetConfigCommand(std::shared_ptr registry, const nlohmann::json &json); \ No newline at end of file +CommandResult resetConfigCommand(std::shared_ptr registry, const nlohmann::json& json); \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/device_commands.cpp b/components/CommandManager/CommandManager/commands/device_commands.cpp index 5dbee0d..547a6ab 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.cpp +++ b/components/CommandManager/CommandManager/commands/device_commands.cpp @@ -1,10 +1,10 @@ #include "device_commands.hpp" +#include #include "LEDManager.hpp" #include "MonitoringManager.hpp" #include "esp_mac.h" -#include -CommandResult setDeviceModeCommand(std::shared_ptr registry, const nlohmann::json &json) +CommandResult setDeviceModeCommand(std::shared_ptr registry, const nlohmann::json& json) { if (!json.contains("mode") || !json["mode"].is_number_integer()) { @@ -23,9 +23,8 @@ CommandResult setDeviceModeCommand(std::shared_ptr registry, return CommandResult::getSuccessResult("Device mode set"); } -CommandResult updateOTACredentialsCommand(std::shared_ptr registry, const nlohmann::json &json) +CommandResult updateOTACredentialsCommand(std::shared_ptr registry, const nlohmann::json& json) { - const auto projectConfig = registry->resolve(DependencyType::project_config); const auto oldDeviceConfig = projectConfig->getDeviceConfig(); auto OTALogin = oldDeviceConfig.OTALogin; @@ -57,7 +56,7 @@ CommandResult updateOTACredentialsCommand(std::shared_ptr re return CommandResult::getSuccessResult("OTA Config set"); } -CommandResult updateLEDDutyCycleCommand(std::shared_ptr registry, const nlohmann::json &json) +CommandResult updateLEDDutyCycleCommand(std::shared_ptr registry, const nlohmann::json& json) { if (!json.contains("dutyCycle") || !json["dutyCycle"].is_number_integer()) { @@ -105,10 +104,7 @@ CommandResult startStreamingCommand() // from *inside* the serial handler, we'd deadlock. // we can just pass nullptr to the vtaskdelete(), // but then we won't get any response, so we schedule a timer instead - esp_timer_create_args_t args{ - .callback = activateStreaming, - .arg = nullptr, - .name = "activateStreaming"}; + esp_timer_create_args_t args{.callback = activateStreaming, .arg = nullptr, .name = "activateStreaming"}; esp_timer_handle_t activateStreamingTimer; esp_timer_create(&args, &activateStreamingTimer); @@ -117,9 +113,8 @@ CommandResult startStreamingCommand() return CommandResult::getSuccessResult("Streaming starting"); } -CommandResult switchModeCommand(std::shared_ptr registry, const nlohmann::json &json) +CommandResult switchModeCommand(std::shared_ptr registry, const nlohmann::json& json) { - if (!json.contains("mode") || !json["mode"].is_string()) { return CommandResult::getErrorResult("Invalid payload - missing mode"); @@ -159,7 +154,7 @@ CommandResult getDeviceModeCommand(std::shared_ptr registry) const auto projectConfig = registry->resolve(DependencyType::project_config); StreamingMode currentMode = projectConfig->getDeviceMode(); - const char *modeStr = "unknown"; + const char* modeStr = "unknown"; switch (currentMode) { case StreamingMode::UVC: @@ -188,13 +183,11 @@ CommandResult getSerialNumberCommand(std::shared_ptr /*regis char serial_no_sep[13]; // Serial without separators (12 hex chars) - std::snprintf(serial_no_sep, sizeof(serial_no_sep), "%02X%02X%02X%02X%02X%02X", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + std::snprintf(serial_no_sep, sizeof(serial_no_sep), "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); char mac_colon[18]; // MAC with colons - std::snprintf(mac_colon, sizeof(mac_colon), "%02X:%02X:%02X:%02X:%02X:%02X", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + std::snprintf(mac_colon, sizeof(mac_colon), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); const auto json = nlohmann::json{ {"serial", serial_no_sep}, @@ -246,8 +239,8 @@ CommandResult getBatteryStatusCommand(std::shared_ptr regist CommandResult getInfoCommand(std::shared_ptr /*registry*/) { - const char *who = CONFIG_GENERAL_BOARD; - const char *ver = CONFIG_GENERAL_VERSION; + const char* who = CONFIG_GENERAL_BOARD; + const char* ver = CONFIG_GENERAL_VERSION; // Ensure non-null strings if (!who) who = ""; diff --git a/components/CommandManager/CommandManager/commands/device_commands.hpp b/components/CommandManager/CommandManager/commands/device_commands.hpp index 4a71a78..25b0dc0 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.hpp +++ b/components/CommandManager/CommandManager/commands/device_commands.hpp @@ -1,24 +1,24 @@ #include "CommandResult.hpp" -#include "ProjectConfig.hpp" -#include "OpenIrisTasks.hpp" #include "DependencyRegistry.hpp" +#include "OpenIrisTasks.hpp" +#include "ProjectConfig.hpp" #include "esp_timer.h" #include "main_globals.hpp" #include -#include #include +#include -CommandResult updateOTACredentialsCommand(std::shared_ptr registry, const nlohmann::json &json); +CommandResult updateOTACredentialsCommand(std::shared_ptr registry, const nlohmann::json& json); -CommandResult updateLEDDutyCycleCommand(std::shared_ptr registry, const nlohmann::json &json); +CommandResult updateLEDDutyCycleCommand(std::shared_ptr registry, const nlohmann::json& json); CommandResult getLEDDutyCycleCommand(std::shared_ptr registry); CommandResult restartDeviceCommand(); CommandResult startStreamingCommand(); -CommandResult switchModeCommand(std::shared_ptr registry, const nlohmann::json &json); +CommandResult switchModeCommand(std::shared_ptr registry, const nlohmann::json& json); CommandResult getDeviceModeCommand(std::shared_ptr registry); diff --git a/components/CommandManager/CommandManager/commands/mdns_commands.cpp b/components/CommandManager/CommandManager/commands/mdns_commands.cpp index 52015ee..228fcdf 100644 --- a/components/CommandManager/CommandManager/commands/mdns_commands.cpp +++ b/components/CommandManager/CommandManager/commands/mdns_commands.cpp @@ -1,22 +1,22 @@ #include "mdns_commands.hpp" -CommandResult setMDNSCommand(std::shared_ptr registry, const nlohmann::json &json) +CommandResult setMDNSCommand(std::shared_ptr registry, const nlohmann::json& json) { - const auto payload = json.get(); - if (payload.hostname.empty()) - return CommandResult::getErrorResult("Invalid payload - empty hostname"); + const auto payload = json.get(); + if (payload.hostname.empty()) + return CommandResult::getErrorResult("Invalid payload - empty hostname"); - std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); - projectConfig->setMDNSConfig(payload.hostname); + std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); + projectConfig->setMDNSConfig(payload.hostname); - return CommandResult::getSuccessResult("Config updated"); + return CommandResult::getSuccessResult("Config updated"); } CommandResult getMDNSNameCommand(std::shared_ptr registry) { - const auto projectConfig = registry->resolve(DependencyType::project_config); - auto mdnsConfig = projectConfig->getMDNSConfig(); + const auto projectConfig = registry->resolve(DependencyType::project_config); + auto mdnsConfig = projectConfig->getMDNSConfig(); - const auto json = nlohmann::json{{"hostname", mdnsConfig.hostname}}; - return CommandResult::getSuccessResult(json); + const auto json = nlohmann::json{{"hostname", mdnsConfig.hostname}}; + return CommandResult::getSuccessResult(json); } \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/mdns_commands.hpp b/components/CommandManager/CommandManager/commands/mdns_commands.hpp index 1b07203..bd7ad38 100644 --- a/components/CommandManager/CommandManager/commands/mdns_commands.hpp +++ b/components/CommandManager/CommandManager/commands/mdns_commands.hpp @@ -1,11 +1,11 @@ #include #include -#include +#include #include +#include #include "CommandResult.hpp" #include "CommandSchema.hpp" #include "DependencyRegistry.hpp" -#include -CommandResult setMDNSCommand(std::shared_ptr registry, const nlohmann::json &json); +CommandResult setMDNSCommand(std::shared_ptr registry, const nlohmann::json& json); CommandResult getMDNSNameCommand(std::shared_ptr registry); \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/scan_commands.cpp b/components/CommandManager/CommandManager/commands/scan_commands.cpp index 4553b10..5d1b6e6 100644 --- a/components/CommandManager/CommandManager/commands/scan_commands.cpp +++ b/components/CommandManager/CommandManager/commands/scan_commands.cpp @@ -1,7 +1,7 @@ #include "scan_commands.hpp" #include "sdkconfig.h" -CommandResult scanNetworksCommand(std::shared_ptr registry, const nlohmann::json &json) +CommandResult scanNetworksCommand(std::shared_ptr registry, const nlohmann::json& json) { #if !CONFIG_GENERAL_ENABLE_WIRELESS return CommandResult::getErrorResult("Not supported by current firmware"); @@ -24,16 +24,14 @@ CommandResult scanNetworksCommand(std::shared_ptr registry, nlohmann::json result; std::vector networksJson; - for (const auto &network : networks) + for (const auto& network : networks) { nlohmann::json networkItem; networkItem["ssid"] = network.ssid; networkItem["channel"] = network.channel; networkItem["rssi"] = network.rssi; char mac_str[18]; - sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", - network.mac[0], network.mac[1], network.mac[2], - network.mac[3], network.mac[4], network.mac[5]); + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", network.mac[0], network.mac[1], network.mac[2], network.mac[3], network.mac[4], network.mac[5]); networkItem["mac_address"] = mac_str; networkItem["auth_mode"] = network.auth_mode; networksJson.push_back(networkItem); diff --git a/components/CommandManager/CommandManager/commands/scan_commands.hpp b/components/CommandManager/CommandManager/commands/scan_commands.hpp index 4e6ba2b..26d94af 100644 --- a/components/CommandManager/CommandManager/commands/scan_commands.hpp +++ b/components/CommandManager/CommandManager/commands/scan_commands.hpp @@ -1,13 +1,13 @@ #ifndef SCAN_COMMANDS_HPP #define SCAN_COMMANDS_HPP +#include +#include +#include #include "CommandResult.hpp" #include "DependencyRegistry.hpp" #include "esp_log.h" -#include -#include -#include -CommandResult scanNetworksCommand(std::shared_ptr registry, const nlohmann::json &json); +CommandResult scanNetworksCommand(std::shared_ptr registry, const nlohmann::json& json); #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/simple_commands.cpp b/components/CommandManager/CommandManager/commands/simple_commands.cpp index 018d1e5..7229071 100644 --- a/components/CommandManager/CommandManager/commands/simple_commands.cpp +++ b/components/CommandManager/CommandManager/commands/simple_commands.cpp @@ -1,32 +1,32 @@ #include "simple_commands.hpp" -static const char *TAG = "SimpleCommands"; +static const char* TAG = "SimpleCommands"; CommandResult PingCommand() { - return CommandResult::getSuccessResult("pong"); + return CommandResult::getSuccessResult("pong"); }; -CommandResult PauseCommand(const nlohmann::json &json) +CommandResult PauseCommand(const nlohmann::json& json) { - auto pause = true; + auto pause = true; - if (json.contains("pause") && json["pause"].is_boolean()) - { - pause = json["pause"].get(); - } + if (json.contains("pause") && json["pause"].is_boolean()) + { + pause = json["pause"].get(); + } - ESP_LOGI(TAG, "Pause command received: %s", pause ? "true" : "false"); + ESP_LOGI(TAG, "Pause command received: %s", pause ? "true" : "false"); - setStartupPaused(pause); - if (pause) - { - ESP_LOGI(TAG, "Startup paused - device will remain in configuration mode"); - return CommandResult::getSuccessResult("Startup paused"); - } - else - { - ESP_LOGI(TAG, "Startup resumed"); - return CommandResult::getSuccessResult("Startup resumed"); - } + setStartupPaused(pause); + if (pause) + { + ESP_LOGI(TAG, "Startup paused - device will remain in configuration mode"); + return CommandResult::getSuccessResult("Startup paused"); + } + else + { + ESP_LOGI(TAG, "Startup resumed"); + return CommandResult::getSuccessResult("Startup resumed"); + } }; diff --git a/components/CommandManager/CommandManager/commands/simple_commands.hpp b/components/CommandManager/CommandManager/commands/simple_commands.hpp index ed75517..c5a1cc1 100644 --- a/components/CommandManager/CommandManager/commands/simple_commands.hpp +++ b/components/CommandManager/CommandManager/commands/simple_commands.hpp @@ -1,13 +1,13 @@ #ifndef SIMPLE_COMMANDS #define SIMPLE_COMMANDS +#include #include #include "CommandResult.hpp" -#include "main_globals.hpp" #include "esp_log.h" -#include +#include "main_globals.hpp" CommandResult PingCommand(); -CommandResult PauseCommand(const nlohmann::json &json); +CommandResult PauseCommand(const nlohmann::json& json); #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/wifi_commands.cpp b/components/CommandManager/CommandManager/commands/wifi_commands.cpp index f99b517..2b789d6 100644 --- a/components/CommandManager/CommandManager/commands/wifi_commands.cpp +++ b/components/CommandManager/CommandManager/commands/wifi_commands.cpp @@ -2,176 +2,165 @@ #include "esp_netif.h" #include "sdkconfig.h" -CommandResult setWiFiCommand(std::shared_ptr registry, const nlohmann::json &json) +CommandResult setWiFiCommand(std::shared_ptr registry, const nlohmann::json& json) { #if !CONFIG_GENERAL_ENABLE_WIRELESS - return CommandResult::getErrorResult("Not supported by current firmware"); + return CommandResult::getErrorResult("Not supported by current firmware"); #endif - auto payload = json.get(); - if (payload.name.empty()) - { - payload.name = std::string("main"); - } + auto payload = json.get(); + if (payload.name.empty()) + { + payload.name = std::string("main"); + } - if (payload.ssid.empty()) - { - return CommandResult::getErrorResult("Invalid payload: missing SSID"); - } + if (payload.ssid.empty()) + { + return CommandResult::getErrorResult("Invalid payload: missing SSID"); + } - std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); - projectConfig->setWifiConfig( - payload.name, - payload.ssid, - payload.password, - payload.channel, - payload.power); - - return CommandResult::getSuccessResult("Config updated"); -} - -CommandResult deleteWiFiCommand(std::shared_ptr registry, const nlohmann::json &json) -{ -#if !CONFIG_GENERAL_ENABLE_WIRELESS - return CommandResult::getErrorResult("Not supported by current firmware"); -#endif - - const auto payload = json.get(); - if (payload.name.empty()) - return CommandResult::getErrorResult("Invalid payload"); - - auto projectConfig = registry->resolve(DependencyType::project_config); - - projectConfig->deleteWifiConfig(payload.name); - return CommandResult::getSuccessResult("Config updated"); -} - -CommandResult updateWiFiCommand(std::shared_ptr registry, const nlohmann::json &json) -{ -#if !CONFIG_GENERAL_ENABLE_WIRELESS - return CommandResult::getErrorResult("Not supported by current firmware"); -#endif - - auto payload = json.get(); - if (payload.name.empty()) - { - return CommandResult::getErrorResult("Invalid payload - missing network name"); - } - - auto projectConfig = registry->resolve(DependencyType::project_config); - auto storedNetworks = projectConfig->getWifiConfigs(); - if (const auto networkToUpdate = std::ranges::find_if( - storedNetworks, - [&](auto &network) - { return network.name == payload.name; }); - networkToUpdate != storedNetworks.end()) - { - projectConfig->setWifiConfig( - payload.name, - payload.ssid.has_value() ? payload.ssid.value() : networkToUpdate->ssid, - payload.password.has_value() ? payload.password.value() : networkToUpdate->password, - payload.channel.has_value() ? payload.channel.value() : networkToUpdate->channel, - payload.power.has_value() ? payload.power.value() : networkToUpdate->power); + std::shared_ptr projectConfig = registry->resolve(DependencyType::project_config); + projectConfig->setWifiConfig(payload.name, payload.ssid, payload.password, payload.channel, payload.power); return CommandResult::getSuccessResult("Config updated"); - } - else - return CommandResult::getErrorResult("Requested network does not exist"); } -CommandResult updateAPWiFiCommand(std::shared_ptr registry, const nlohmann::json &json) +CommandResult deleteWiFiCommand(std::shared_ptr registry, const nlohmann::json& json) { #if !CONFIG_GENERAL_ENABLE_WIRELESS - return CommandResult::getErrorResult("Not supported by current firmware"); + return CommandResult::getErrorResult("Not supported by current firmware"); #endif - const auto payload = json.get(); + const auto payload = json.get(); + if (payload.name.empty()) + return CommandResult::getErrorResult("Invalid payload"); - auto projectConfig = registry->resolve(DependencyType::project_config); - const auto previousAPConfig = projectConfig->getAPWifiConfig(); + auto projectConfig = registry->resolve(DependencyType::project_config); - projectConfig->setAPWifiConfig( - payload.ssid.has_value() ? payload.ssid.value() : previousAPConfig.ssid, - payload.password.has_value() ? payload.password.value() : previousAPConfig.password, - payload.channel.has_value() ? payload.channel.value() : previousAPConfig.channel); + projectConfig->deleteWifiConfig(payload.name); + return CommandResult::getSuccessResult("Config updated"); +} - return CommandResult::getSuccessResult("Config updated"); +CommandResult updateWiFiCommand(std::shared_ptr registry, const nlohmann::json& json) +{ +#if !CONFIG_GENERAL_ENABLE_WIRELESS + return CommandResult::getErrorResult("Not supported by current firmware"); +#endif + + auto payload = json.get(); + if (payload.name.empty()) + { + return CommandResult::getErrorResult("Invalid payload - missing network name"); + } + + auto projectConfig = registry->resolve(DependencyType::project_config); + auto storedNetworks = projectConfig->getWifiConfigs(); + if (const auto networkToUpdate = std::ranges::find_if(storedNetworks, [&](auto& network) { return network.name == payload.name; }); + networkToUpdate != storedNetworks.end()) + { + projectConfig->setWifiConfig(payload.name, payload.ssid.has_value() ? payload.ssid.value() : networkToUpdate->ssid, + payload.password.has_value() ? payload.password.value() : networkToUpdate->password, + payload.channel.has_value() ? payload.channel.value() : networkToUpdate->channel, + payload.power.has_value() ? payload.power.value() : networkToUpdate->power); + + return CommandResult::getSuccessResult("Config updated"); + } + else + return CommandResult::getErrorResult("Requested network does not exist"); +} + +CommandResult updateAPWiFiCommand(std::shared_ptr registry, const nlohmann::json& json) +{ +#if !CONFIG_GENERAL_ENABLE_WIRELESS + return CommandResult::getErrorResult("Not supported by current firmware"); +#endif + + const auto payload = json.get(); + + auto projectConfig = registry->resolve(DependencyType::project_config); + const auto previousAPConfig = projectConfig->getAPWifiConfig(); + + projectConfig->setAPWifiConfig(payload.ssid.has_value() ? payload.ssid.value() : previousAPConfig.ssid, + payload.password.has_value() ? payload.password.value() : previousAPConfig.password, + payload.channel.has_value() ? payload.channel.value() : previousAPConfig.channel); + + return CommandResult::getSuccessResult("Config updated"); } CommandResult getWiFiStatusCommand(std::shared_ptr registry) { #if !CONFIG_GENERAL_ENABLE_WIRELESS - return CommandResult::getErrorResult("Not supported by current firmware"); + return CommandResult::getErrorResult("Not supported by current firmware"); #endif - auto wifiManager = registry->resolve(DependencyType::wifi_manager); - auto projectConfig = registry->resolve(DependencyType::project_config); + auto wifiManager = registry->resolve(DependencyType::wifi_manager); + auto projectConfig = registry->resolve(DependencyType::project_config); - auto wifiState = wifiManager->GetCurrentWiFiState(); - auto networks = projectConfig->getWifiConfigs(); - nlohmann::json result; + auto wifiState = wifiManager->GetCurrentWiFiState(); + auto networks = projectConfig->getWifiConfigs(); + nlohmann::json result; - switch (wifiState) - { - case WiFiState_e::WiFiState_NotInitialized: - result["status"] = "not_initialized"; - break; - case WiFiState_e::WiFiState_Initialized: - result["status"] = "initialized"; - break; - case WiFiState_e::WiFiState_ReadyToConnect: - result["status"] = "ready"; - break; - case WiFiState_e::WiFiState_Connecting: - result["status"] = "connecting"; - break; - case WiFiState_e::WiFiState_WaitingForIp: - result["status"] = "waiting_for_ip"; - break; - case WiFiState_e::WiFiState_Connected: - result["status"] = "connected"; - break; - case WiFiState_e::WiFiState_Disconnected: - result["status"] = "disconnected"; - break; - case WiFiState_e::WiFiState_Error: - result["status"] = "error"; - break; - } - - if (wifiState == WiFiState_e::WiFiState_Connected) - { - // Get IP address from ESP32 - esp_netif_ip_info_t ip_info; - esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); - if (netif && esp_netif_get_ip_info(netif, &ip_info) == ESP_OK) + switch (wifiState) { - char ip_str[16]; - sprintf(ip_str, IPSTR, IP2STR(&ip_info.ip)); - result["ip_address"] = ip_str; + case WiFiState_e::WiFiState_NotInitialized: + result["status"] = "not_initialized"; + break; + case WiFiState_e::WiFiState_Initialized: + result["status"] = "initialized"; + break; + case WiFiState_e::WiFiState_ReadyToConnect: + result["status"] = "ready"; + break; + case WiFiState_e::WiFiState_Connecting: + result["status"] = "connecting"; + break; + case WiFiState_e::WiFiState_WaitingForIp: + result["status"] = "waiting_for_ip"; + break; + case WiFiState_e::WiFiState_Connected: + result["status"] = "connected"; + break; + case WiFiState_e::WiFiState_Disconnected: + result["status"] = "disconnected"; + break; + case WiFiState_e::WiFiState_Error: + result["status"] = "error"; + break; } - } - return CommandResult::getSuccessResult(result); + if (wifiState == WiFiState_e::WiFiState_Connected) + { + // Get IP address from ESP32 + esp_netif_ip_info_t ip_info; + esp_netif_t* netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + if (netif && esp_netif_get_ip_info(netif, &ip_info) == ESP_OK) + { + char ip_str[16]; + sprintf(ip_str, IPSTR, IP2STR(&ip_info.ip)); + result["ip_address"] = ip_str; + } + } + + return CommandResult::getSuccessResult(result); } CommandResult connectWiFiCommand(std::shared_ptr registry) { #if !CONFIG_GENERAL_ENABLE_WIRELESS - return CommandResult::getErrorResult("Not supported by current firmware"); + return CommandResult::getErrorResult("Not supported by current firmware"); #endif - auto wifiManager = registry->resolve(DependencyType::wifi_manager); - auto projectConfig = registry->resolve(DependencyType::project_config); + auto wifiManager = registry->resolve(DependencyType::wifi_manager); + auto projectConfig = registry->resolve(DependencyType::project_config); - auto networks = projectConfig->getWifiConfigs(); - if (networks.empty()) - { - return CommandResult::getErrorResult("No WiFi networks configured"); - } + auto networks = projectConfig->getWifiConfigs(); + if (networks.empty()) + { + return CommandResult::getErrorResult("No WiFi networks configured"); + } - // Trigger WiFi connection attempt - wifiManager->TryConnectToStoredNetworks(); + // Trigger WiFi connection attempt + wifiManager->TryConnectToStoredNetworks(); - return CommandResult::getSuccessResult("WiFi connection attempt started"); + return CommandResult::getSuccessResult("WiFi connection attempt started"); } diff --git a/components/CommandManager/CommandManager/commands/wifi_commands.hpp b/components/CommandManager/CommandManager/commands/wifi_commands.hpp index fd36e72..b004fac 100644 --- a/components/CommandManager/CommandManager/commands/wifi_commands.hpp +++ b/components/CommandManager/CommandManager/commands/wifi_commands.hpp @@ -1,21 +1,21 @@ #include -#include #include #include -#include +#include #include +#include +#include #include "CommandResult.hpp" #include "CommandSchema.hpp" #include "DependencyRegistry.hpp" -#include -CommandResult setWiFiCommand(std::shared_ptr registry, const nlohmann::json &json); +CommandResult setWiFiCommand(std::shared_ptr registry, const nlohmann::json& json); -CommandResult deleteWiFiCommand(std::shared_ptr registry, const nlohmann::json &json); +CommandResult deleteWiFiCommand(std::shared_ptr registry, const nlohmann::json& json); -CommandResult updateWiFiCommand(std::shared_ptr registry, const nlohmann::json &json); +CommandResult updateWiFiCommand(std::shared_ptr registry, const nlohmann::json& json); -CommandResult updateAPWiFiCommand(std::shared_ptr registry, const nlohmann::json &json); +CommandResult updateAPWiFiCommand(std::shared_ptr registry, const nlohmann::json& json); CommandResult getWiFiStatusCommand(std::shared_ptr registry); CommandResult connectWiFiCommand(std::shared_ptr registry); diff --git a/components/Helpers/Helpers/helpers.cpp b/components/Helpers/Helpers/helpers.cpp index 264e1c6..c4a0292 100644 --- a/components/Helpers/Helpers/helpers.cpp +++ b/components/Helpers/Helpers/helpers.cpp @@ -1,85 +1,85 @@ #include "helpers.hpp" -char *Helpers::itoa(int value, char *result, int base) +char* Helpers::itoa(int value, char* result, int base) { - // check that the base if valid - if (base < 2 || base > 36) - { - *result = '\0'; - return result; - } - - char *ptr = result, *ptr1 = result, tmp_char; - int tmp_value; - - do - { - tmp_value = value; - value /= base; - *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)]; - } while (value); - - // Apply negative sign - if (tmp_value < 0) - *ptr++ = '-'; - *ptr-- = '\0'; - while (ptr1 < ptr) - { - tmp_char = *ptr; - *ptr-- = *ptr1; - *ptr1++ = tmp_char; - } - return result; -} - -void split(const std::string &str, const std::string &splitBy, std::vector &tokens) -{ - /* Store the original string in the array, so we can loop the rest - * of the algorithm. */ - tokens.emplace_back(str); - - // Store the split index in a 'size_t' (unsigned integer) type. - size_t splitAt; - // Store the size of what we're splicing out. - size_t splitLen = splitBy.size(); - // Create a string for temporarily storing the fragment we're processing. - std::string frag; - // Loop infinitely - break is internal. - while (true) - { - /* Store the last string in the vector, which is the only logical - * candidate for processing. */ - frag = tokens.back(); - /* The index where the split is. */ - splitAt = frag.find(splitBy); - // If we didn't find a new split point... - if (splitAt == std::string::npos) + // check that the base if valid + if (base < 2 || base > 36) { - // Break the loop and (implicitly) return. - break; + *result = '\0'; + return result; } - /* Put everything from the left side of the split where the string - * being processed used to be. */ - tokens.back() = frag.substr(0, splitAt); - /* Push everything from the right side of the split to the next empty - * index in the vector. */ - tokens.emplace_back(frag.substr(splitAt + splitLen, frag.size() - (splitAt + splitLen))); - } + + char *ptr = result, *ptr1 = result, tmp_char; + int tmp_value; + + do + { + tmp_value = value; + value /= base; + *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)]; + } while (value); + + // Apply negative sign + if (tmp_value < 0) + *ptr++ = '-'; + *ptr-- = '\0'; + while (ptr1 < ptr) + { + tmp_char = *ptr; + *ptr-- = *ptr1; + *ptr1++ = tmp_char; + } + return result; } -std::vector Helpers::split(const std::string &s, char delimiter) +void split(const std::string& str, const std::string& splitBy, std::vector& tokens) { - std::vector parts; - std::string part; - std::istringstream tokenStream(s); - while (std::getline(tokenStream, part, delimiter)) - { - parts.push_back(part); - } - return parts; + /* Store the original string in the array, so we can loop the rest + * of the algorithm. */ + tokens.emplace_back(str); + + // Store the split index in a 'size_t' (unsigned integer) type. + size_t splitAt; + // Store the size of what we're splicing out. + size_t splitLen = splitBy.size(); + // Create a string for temporarily storing the fragment we're processing. + std::string frag; + // Loop infinitely - break is internal. + while (true) + { + /* Store the last string in the vector, which is the only logical + * candidate for processing. */ + frag = tokens.back(); + /* The index where the split is. */ + splitAt = frag.find(splitBy); + // If we didn't find a new split point... + if (splitAt == std::string::npos) + { + // Break the loop and (implicitly) return. + break; + } + /* Put everything from the left side of the split where the string + * being processed used to be. */ + tokens.back() = frag.substr(0, splitAt); + /* Push everything from the right side of the split to the next empty + * index in the vector. */ + tokens.emplace_back(frag.substr(splitAt + splitLen, frag.size() - (splitAt + splitLen))); + } +} + +std::vector Helpers::split(const std::string& s, char delimiter) +{ + std::vector parts; + std::string part; + std::istringstream tokenStream(s); + while (std::getline(tokenStream, part, delimiter)) + { + parts.push_back(part); + } + return parts; } int64_t Helpers::getTimeInMillis() { - return (esp_timer_get_time() / 1000); + return (esp_timer_get_time() / 1000); } \ No newline at end of file diff --git a/components/Helpers/Helpers/helpers.hpp b/components/Helpers/Helpers/helpers.hpp index 28082c8..156ffe7 100644 --- a/components/Helpers/Helpers/helpers.hpp +++ b/components/Helpers/Helpers/helpers.hpp @@ -1,40 +1,40 @@ #pragma once #ifndef HELPERS_HPP #define HELPERS_HPP -#include "esp_timer.h" -#include -#include -#include #include #include +#include +#include +#include +#include "esp_timer.h" namespace Helpers { - char *itoa(int value, char *result, int base); - void split(std::string str, std::string splitBy, std::vector &tokens); - std::vector split(const std::string &s, char delimiter); +char* itoa(int value, char* result, int base); +void split(std::string str, std::string splitBy, std::vector& tokens); +std::vector split(const std::string& s, char delimiter); - /// @brief - /// @tparam ...Args - /// @param format - /// @param ...args - /// @return - template - std::string format_string(const std::string &format, Args... args) - { - int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' +/// @brief +/// @tparam ...Args +/// @param format +/// @param ...args +/// @return +template +std::string format_string(const std::string& format, Args... args) +{ + int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' if (size_s <= 0) { - std::cout << "Error during formatting."; - return ""; + std::cout << "Error during formatting."; + return ""; } auto size = static_cast(size_s); std::unique_ptr buf(new char[size]); std::snprintf(buf.get(), size, format.c_str(), args...); - return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside - } - - int64_t getTimeInMillis(); + return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside } -#endif // HELPERS_HPP +int64_t getTimeInMillis(); +} // namespace Helpers + +#endif // HELPERS_HPP diff --git a/components/Helpers/Helpers/main_globals.cpp b/components/Helpers/Helpers/main_globals.cpp index da51271..88b8594 100644 --- a/components/Helpers/Helpers/main_globals.cpp +++ b/components/Helpers/Helpers/main_globals.cpp @@ -28,12 +28,18 @@ void setStartupPaused(bool startupPaused) } // Function to manually activate streaming -void activateStreaming(void *arg) +void activateStreaming(void* arg) { force_activate_streaming(); } // USB handover state static bool s_usbHandoverDone = false; -bool getUsbHandoverDone() { return s_usbHandoverDone; } -void setUsbHandoverDone(bool done) { s_usbHandoverDone = done; } \ No newline at end of file +bool getUsbHandoverDone() +{ + return s_usbHandoverDone; +} +void setUsbHandoverDone(bool done) +{ + s_usbHandoverDone = done; +} \ No newline at end of file diff --git a/components/Helpers/Helpers/main_globals.hpp b/components/Helpers/Helpers/main_globals.hpp index 2505cca..04937a9 100644 --- a/components/Helpers/Helpers/main_globals.hpp +++ b/components/Helpers/Helpers/main_globals.hpp @@ -9,7 +9,7 @@ // Function to manually activate streaming // designed to be scheduled as a task // so that the serial manager has time to return the response -void activateStreaming(void *arg); +void activateStreaming(void* arg); bool getStartupCommandReceived(); void setStartupCommandReceived(bool startupCommandReceived); diff --git a/components/LEDManager/LEDManager/LEDManager.cpp b/components/LEDManager/LEDManager/LEDManager.cpp index b3baa4e..587d057 100644 --- a/components/LEDManager/LEDManager/LEDManager.cpp +++ b/components/LEDManager/LEDManager/LEDManager.cpp @@ -1,6 +1,6 @@ #include "LEDManager.hpp" -const char *LED_MANAGER_TAG = "[LED_MANAGER]"; +const char* LED_MANAGER_TAG = "[LED_MANAGER]"; // Pattern design rules: // - Error states: isError=true, repeat indefinitely, easily distinguishable (avoid overlap). @@ -8,25 +8,25 @@ const char *LED_MANAGER_TAG = "[LED_MANAGER]"; // - Non-repeating notification (e.g. Connected) gives user a brief confirmation burst then turns off. // Durations in ms. ledStateMap_t LEDManager::ledStateMap = { - { LEDStates_e::LedStateNone, { /*isError*/false, /*repeat*/false, {{LED_OFF, 1000}} } }, - { LEDStates_e::LedStateStreaming, { false, /*repeat steady*/true, {{LED_ON, 1000}} } }, - { LEDStates_e::LedStateStoppedStreaming, { false, true, {{LED_OFF, 1000}} } }, + {LEDStates_e::LedStateNone, {/*isError*/ false, /*repeat*/ false, {{LED_OFF, 1000}}}}, + {LEDStates_e::LedStateStreaming, {false, /*repeat steady*/ true, {{LED_ON, 1000}}}}, + {LEDStates_e::LedStateStoppedStreaming, {false, true, {{LED_OFF, 1000}}}}, // CameraError: double blink pattern repeating - { LEDStates_e::CameraError, { true, true, {{ {LED_ON,300}, {LED_OFF,300}, {LED_ON,300}, {LED_OFF,700} }} } }, + {LEDStates_e::CameraError, {true, true, {{{LED_ON, 300}, {LED_OFF, 300}, {LED_ON, 300}, {LED_OFF, 700}}}}}, // WiFiStateConnecting: balanced slow blink 400/400 - { LEDStates_e::WiFiStateConnecting, { false, true, {{ {LED_ON,400}, {LED_OFF,400} }} } }, + {LEDStates_e::WiFiStateConnecting, {false, true, {{{LED_ON, 400}, {LED_OFF, 400}}}}}, // WiFiStateConnected: short 3 quick flashes then done (was long noisy burst before) - { LEDStates_e::WiFiStateConnected, { false, false, {{ {LED_ON,150}, {LED_OFF,150}, {LED_ON,150}, {LED_OFF,150}, {LED_ON,150}, {LED_OFF,600} }} } }, + {LEDStates_e::WiFiStateConnected, {false, false, {{{LED_ON, 150}, {LED_OFF, 150}, {LED_ON, 150}, {LED_OFF, 150}, {LED_ON, 150}, {LED_OFF, 600}}}}}, // WiFiStateError: asymmetric attention pattern (fast, pause, long, pause, fast) - { LEDStates_e::WiFiStateError, { true, true, {{ {LED_ON,200}, {LED_OFF,100}, {LED_ON,500}, {LED_OFF,300} }} } }, + {LEDStates_e::WiFiStateError, {true, true, {{{LED_ON, 200}, {LED_OFF, 100}, {LED_ON, 500}, {LED_OFF, 300}}}}}, }; -LEDManager::LEDManager(gpio_num_t pin, gpio_num_t illumninator_led_pin, - QueueHandle_t ledStateQueue, std::shared_ptr deviceConfig) : blink_led_pin(pin), - illumninator_led_pin(illumninator_led_pin), - ledStateQueue(ledStateQueue), - currentState(LEDStates_e::LedStateNone), - deviceConfig(deviceConfig) +LEDManager::LEDManager(gpio_num_t pin, gpio_num_t illumninator_led_pin, QueueHandle_t ledStateQueue, std::shared_ptr deviceConfig) + : blink_led_pin(pin), + illumninator_led_pin(illumninator_led_pin), + ledStateQueue(ledStateQueue), + currentState(LEDStates_e::LedStateNone), + deviceConfig(deviceConfig) { } @@ -52,22 +52,17 @@ void LEDManager::setup() ESP_LOGI(LED_MANAGER_TAG, "Setting dutyCycle to: %lu ", dutyCycle); ledc_timer_config_t ledc_timer = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .duty_resolution = resolution, - .timer_num = LEDC_TIMER_0, - .freq_hz = freq, - .clk_cfg = LEDC_AUTO_CLK}; + .speed_mode = LEDC_LOW_SPEED_MODE, .duty_resolution = resolution, .timer_num = LEDC_TIMER_0, .freq_hz = freq, .clk_cfg = LEDC_AUTO_CLK}; ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); - ledc_channel_config_t ledc_channel = { - .gpio_num = this->illumninator_led_pin, - .speed_mode = LEDC_LOW_SPEED_MODE, - .channel = LEDC_CHANNEL_0, - .intr_type = LEDC_INTR_DISABLE, - .timer_sel = LEDC_TIMER_0, - .duty = dutyCycle, - .hpoint = 0}; + ledc_channel_config_t ledc_channel = {.gpio_num = this->illumninator_led_pin, + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = LEDC_CHANNEL_0, + .intr_type = LEDC_INTR_DISABLE, + .timer_sel = LEDC_TIMER_0, + .duty = dutyCycle, + .hpoint = 0}; ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel)); #endif @@ -190,14 +185,14 @@ void LEDManager::setExternalLEDDutyCycle(uint8_t dutyPercent) ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, dutyCycle)); ESP_ERROR_CHECK_WITHOUT_ABORT(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0)); #else - (void)dutyPercent; // unused + (void)dutyPercent; // unused ESP_LOGW(LED_MANAGER_TAG, "CONFIG_LED_EXTERNAL_CONTROL not enabled; ignoring duty update"); #endif } -void HandleLEDDisplayTask(void *pvParameter) +void HandleLEDDisplayTask(void* pvParameter) { - auto *ledManager = static_cast(pvParameter); + auto* ledManager = static_cast(pvParameter); TickType_t lastWakeTime = xTaskGetTickCount(); while (true) diff --git a/components/LEDManager/LEDManager/LEDManager.hpp b/components/LEDManager/LEDManager/LEDManager.hpp index a08ace3..c41401b 100644 --- a/components/LEDManager/LEDManager/LEDManager.hpp +++ b/components/LEDManager/LEDManager/LEDManager.hpp @@ -11,13 +11,13 @@ #endif #include +#include +#include #include #include +#include #include #include -#include -#include -#include // it kinda looks like different boards have these states swapped #define LED_OFF 1 @@ -25,57 +25,62 @@ struct BlinkPatterns_t { - int state; - int delayTime; + int state; + int delayTime; }; struct LEDStage { - bool isError; - bool isRepeatable; - std::vector patterns; + bool isError; + bool isRepeatable; + std::vector patterns; }; -typedef std::unordered_map - ledStateMap_t; +typedef std::unordered_map ledStateMap_t; class LEDManager { -public: - LEDManager(gpio_num_t blink_led_pin, gpio_num_t illumninator_led_pin, QueueHandle_t ledStateQueue, std::shared_ptr deviceConfig); + public: + LEDManager(gpio_num_t blink_led_pin, gpio_num_t illumninator_led_pin, QueueHandle_t ledStateQueue, std::shared_ptr deviceConfig); - void setup(); - void handleLED(); - size_t getTimeToDelayFor() const { return timeToDelayFor; } + void setup(); + void handleLED(); + size_t getTimeToDelayFor() const + { + return timeToDelayFor; + } - // Apply new external LED PWM duty cycle immediately (0-100) - void setExternalLEDDutyCycle(uint8_t dutyPercent); - uint8_t getExternalLEDDutyCycle() const { return deviceConfig ? deviceConfig->getDeviceConfig().led_external_pwm_duty_cycle : 0; } + // Apply new external LED PWM duty cycle immediately (0-100) + void setExternalLEDDutyCycle(uint8_t dutyPercent); + uint8_t getExternalLEDDutyCycle() const + { + return deviceConfig ? deviceConfig->getDeviceConfig().led_external_pwm_duty_cycle : 0; + } -private: - void toggleLED(bool state) const; - void displayCurrentPattern(); - void updateState(LEDStates_e newState); + private: + void toggleLED(bool state) const; + void displayCurrentPattern(); + void updateState(LEDStates_e newState); - gpio_num_t blink_led_pin; - gpio_num_t illumninator_led_pin; - QueueHandle_t ledStateQueue; + gpio_num_t blink_led_pin; + gpio_num_t illumninator_led_pin; + QueueHandle_t ledStateQueue; - static ledStateMap_t ledStateMap; + static ledStateMap_t ledStateMap; - LEDStates_e buffer; - LEDStates_e currentState; - std::shared_ptr deviceConfig; + LEDStates_e buffer; + LEDStates_e currentState; + std::shared_ptr deviceConfig; - size_t currentPatternIndex = 0; - size_t timeToDelayFor = 100; - bool finishedPattern = false; + size_t currentPatternIndex = 0; + size_t timeToDelayFor = 100; + bool finishedPattern = false; #if defined(CONFIG_LED_EXTERNAL_CONTROL) && defined(CONFIG_LED_EXTERNAL_AS_DEBUG) - bool hasStoredExternalDuty = false; - uint32_t storedExternalDuty = 0; // raw 0-255 + bool hasStoredExternalDuty = false; + uint32_t storedExternalDuty = 0; // raw 0-255 #endif }; -void HandleLEDDisplayTask(void *pvParameter); +void HandleLEDDisplayTask(void* pvParameter); #endif \ No newline at end of file diff --git a/components/MDNSManager/MDNSManager/MDNSManager.cpp b/components/MDNSManager/MDNSManager/MDNSManager.cpp index da288e4..d53a344 100644 --- a/components/MDNSManager/MDNSManager/MDNSManager.cpp +++ b/components/MDNSManager/MDNSManager/MDNSManager.cpp @@ -1,55 +1,55 @@ #include "MDNSManager.hpp" -static const char *MDNS_MANAGER_TAG = "[MDNS MANAGER]"; +static const char* MDNS_MANAGER_TAG = "[MDNS MANAGER]"; MDNSManager::MDNSManager(std::shared_ptr projectConfig, QueueHandle_t eventQueue) : projectConfig(projectConfig), eventQueue(eventQueue) {} esp_err_t MDNSManager::start() { - const std::string &mdnsName = "_openiristracker"; + const std::string& mdnsName = "_openiristracker"; - { - SystemEvent event = {EventSource::MDNS, MDNSState_e::MDNSState_Starting}; - xQueueSend(this->eventQueue, &event, 10); - } + { + SystemEvent event = {EventSource::MDNS, MDNSState_e::MDNSState_Starting}; + xQueueSend(this->eventQueue, &event, 10); + } - esp_err_t result = mdns_init(); - if (result != ESP_OK) - { - SystemEvent event = {EventSource::MDNS, MDNSState_e::MDNSState_Error}; + esp_err_t result = mdns_init(); + if (result != ESP_OK) + { + SystemEvent event = {EventSource::MDNS, MDNSState_e::MDNSState_Error}; + xQueueSend(this->eventQueue, &event, 10); + ESP_LOGE(MDNS_MANAGER_TAG, "Failed to initialize mDNS server: %s", esp_err_to_name(result)); + return result; + } + + auto mdnsConfig = projectConfig->getMDNSConfig(); + result = mdns_hostname_set(mdnsConfig.hostname.c_str()); + if (result != ESP_OK) + { + SystemEvent event = {EventSource::MDNS, MDNSState_e::MDNSState_Error}; + xQueueSend(this->eventQueue, &event, 10); + ESP_LOGE(MDNS_MANAGER_TAG, "Failed to set hostname: %s", esp_err_to_name(result)); + return result; + } + + mdns_txt_item_t serviceTxtData[3] = { + {"stream_port", "80"}, + {"api_port", "81"}, + }; + + mdns_service_add(nullptr, mdnsName.c_str(), "_tcp", 80, serviceTxtData, 2); + result = mdns_service_instance_name_set(mdnsName.c_str(), "_tcp", mdnsName.c_str()); + if (result != ESP_OK) + { + SystemEvent event = {EventSource::MDNS, MDNSState_e::MDNSState_Error}; + xQueueSend(this->eventQueue, &event, 10); + + ESP_LOGE(MDNS_MANAGER_TAG, "Failed to set mDNS instance name: %s", esp_err_to_name(result)); + return result; + } + + SystemEvent event = {EventSource::MDNS, MDNSState_e::MDNSState_Started}; xQueueSend(this->eventQueue, &event, 10); - ESP_LOGE(MDNS_MANAGER_TAG, "Failed to initialize mDNS server: %s", esp_err_to_name(result)); + return result; - } - - auto mdnsConfig = projectConfig->getMDNSConfig(); - result = mdns_hostname_set(mdnsConfig.hostname.c_str()); - if (result != ESP_OK) - { - SystemEvent event = {EventSource::MDNS, MDNSState_e::MDNSState_Error}; - xQueueSend(this->eventQueue, &event, 10); - ESP_LOGE(MDNS_MANAGER_TAG, "Failed to set hostname: %s", esp_err_to_name(result)); - return result; - } - - mdns_txt_item_t serviceTxtData[3] = { - {"stream_port", "80"}, - {"api_port", "81"}, - }; - - mdns_service_add(nullptr, mdnsName.c_str(), "_tcp", 80, serviceTxtData, 2); - result = mdns_service_instance_name_set(mdnsName.c_str(), "_tcp", mdnsName.c_str()); - if (result != ESP_OK) - { - SystemEvent event = {EventSource::MDNS, MDNSState_e::MDNSState_Error}; - xQueueSend(this->eventQueue, &event, 10); - - ESP_LOGE(MDNS_MANAGER_TAG, "Failed to set mDNS instance name: %s", esp_err_to_name(result)); - return result; - } - - SystemEvent event = {EventSource::MDNS, MDNSState_e::MDNSState_Started}; - xQueueSend(this->eventQueue, &event, 10); - - return result; } \ No newline at end of file diff --git a/components/MDNSManager/MDNSManager/MDNSManager.hpp b/components/MDNSManager/MDNSManager/MDNSManager.hpp index e5fab97..6d5d582 100644 --- a/components/MDNSManager/MDNSManager/MDNSManager.hpp +++ b/components/MDNSManager/MDNSManager/MDNSManager.hpp @@ -1,9 +1,9 @@ #pragma once #ifndef MDNSMANAGER_HPP #define MDNSMANAGER_HPP -#include #include #include +#include #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" @@ -11,13 +11,13 @@ class MDNSManager { -private: - std::shared_ptr projectConfig; - QueueHandle_t eventQueue; + private: + std::shared_ptr projectConfig; + QueueHandle_t eventQueue; -public: - MDNSManager(std::shared_ptr projectConfig, QueueHandle_t eventQueue); - esp_err_t start(); + public: + MDNSManager(std::shared_ptr projectConfig, QueueHandle_t eventQueue); + esp_err_t start(); }; -#endif // MDNSMANAGER_HPP +#endif // MDNSMANAGER_HPP diff --git a/components/Monitoring/Monitoring/AdcSampler.cpp b/components/Monitoring/Monitoring/AdcSampler.cpp index 387a7ba..2afe2c6 100644 --- a/components/Monitoring/Monitoring/AdcSampler.cpp +++ b/components/Monitoring/Monitoring/AdcSampler.cpp @@ -13,7 +13,7 @@ #if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32) #include -static const char *TAG = "[AdcSampler]"; +static const char* TAG = "[AdcSampler]"; // Static member initialization adc_oneshot_unit_handle_t AdcSampler::shared_unit_ = nullptr; @@ -22,11 +22,11 @@ AdcSampler::~AdcSampler() { if (cali_handle_) { - #if defined(CONFIG_IDF_TARGET_ESP32S3) +#if defined(CONFIG_IDF_TARGET_ESP32S3) adc_cali_delete_scheme_curve_fitting(cali_handle_); - #elif defined(CONFIG_IDF_TARGET_ESP32) +#elif defined(CONFIG_IDF_TARGET_ESP32) adc_cali_delete_scheme_line_fitting(cali_handle_); - #endif +#endif cali_handle_ = nullptr; } } @@ -68,8 +68,8 @@ bool AdcSampler::init(int gpio, adc_atten_t atten, adc_bitwidth_t bitwidth, size // Try calibration (requires eFuse data) // ESP32-S3 uses curve-fitting, ESP32 uses line-fitting esp_err_t cal_err = ESP_FAIL; - - #if defined(CONFIG_IDF_TARGET_ESP32S3) + +#if defined(CONFIG_IDF_TARGET_ESP32S3) // ESP32-S3 curve fitting calibration adc_cali_curve_fitting_config_t cal_cfg = { .unit_id = unit_, @@ -78,7 +78,7 @@ bool AdcSampler::init(int gpio, adc_atten_t atten, adc_bitwidth_t bitwidth, size .bitwidth = bitwidth_, }; cal_err = adc_cali_create_scheme_curve_fitting(&cal_cfg, &cali_handle_); - #elif defined(CONFIG_IDF_TARGET_ESP32) +#elif defined(CONFIG_IDF_TARGET_ESP32) // ESP32 line-fitting calibration is per-unit, not per-channel adc_cali_line_fitting_config_t cal_cfg = { .unit_id = unit_, @@ -86,8 +86,8 @@ bool AdcSampler::init(int gpio, adc_atten_t atten, adc_bitwidth_t bitwidth, size .bitwidth = bitwidth_, }; cal_err = adc_cali_create_scheme_line_fitting(&cal_cfg, &cali_handle_); - #endif - +#endif + if (cal_err == ESP_OK) { cali_inited_ = true; @@ -187,11 +187,10 @@ bool AdcSampler::configure_channel(int gpio, adc_atten_t atten, adc_bitwidth_t b esp_err_t err = adc_oneshot_config_channel(shared_unit_, channel_, &chan_cfg); if (err != ESP_OK) { - ESP_LOGE(TAG, "adc_oneshot_config_channel failed (GPIO %d, CH %d): %s", - gpio, static_cast(channel_), esp_err_to_name(err)); + ESP_LOGE(TAG, "adc_oneshot_config_channel failed (GPIO %d, CH %d): %s", gpio, static_cast(channel_), esp_err_to_name(err)); return false; } return true; } -#endif // CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32 +#endif // CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32 diff --git a/components/Monitoring/Monitoring/AdcSampler.hpp b/components/Monitoring/Monitoring/AdcSampler.hpp index a98235c..21b4e45 100644 --- a/components/Monitoring/Monitoring/AdcSampler.hpp +++ b/components/Monitoring/Monitoring/AdcSampler.hpp @@ -21,10 +21,10 @@ #include "sdkconfig.h" #if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32) -#include "esp_adc/adc_oneshot.h" +#include #include "esp_adc/adc_cali.h" #include "esp_adc/adc_cali_scheme.h" -#include +#include "esp_adc/adc_oneshot.h" /** * @class AdcSampler @@ -35,15 +35,15 @@ */ class AdcSampler { -public: + public: AdcSampler() = default; ~AdcSampler(); // Non-copyable, non-movable (owns hardware resources) - AdcSampler(const AdcSampler &) = delete; - AdcSampler &operator=(const AdcSampler &) = delete; - AdcSampler(AdcSampler &&) = delete; - AdcSampler &operator=(AdcSampler &&) = delete; + AdcSampler(const AdcSampler&) = delete; + AdcSampler& operator=(const AdcSampler&) = delete; + AdcSampler(AdcSampler&&) = delete; + AdcSampler& operator=(AdcSampler&&) = delete; /** * @brief Initialize the ADC channel on the shared ADC1 oneshot unit @@ -53,10 +53,7 @@ public: * @param window_size Moving average window size (>=1) * @return true on success, false on failure */ - bool init(int gpio, - adc_atten_t atten = ADC_ATTEN_DB_12, - adc_bitwidth_t bitwidth = ADC_BITWIDTH_DEFAULT, - size_t window_size = 1); + bool init(int gpio, adc_atten_t atten = ADC_ATTEN_DB_12, adc_bitwidth_t bitwidth = ADC_BITWIDTH_DEFAULT, size_t window_size = 1); /** * @brief Perform one ADC conversion and update filtered value @@ -68,15 +65,21 @@ public: * @brief Get the filtered ADC reading in millivolts * @return Filtered voltage in mV */ - int getFilteredMilliVolts() const { return filtered_mv_; } + int getFilteredMilliVolts() const + { + return filtered_mv_; + } /** * @brief Check if ADC sampling is supported on current platform * @return true if supported */ - static constexpr bool isSupported() { return true; } + static constexpr bool isSupported() + { + return true; + } -private: + private: // Hardware initialization helpers bool ensure_unit(); bool configure_channel(int gpio, adc_atten_t atten, adc_bitwidth_t bitwidth); @@ -85,7 +88,7 @@ private: * @brief Platform-specific GPIO to ADC channel mapping * @note Implemented separately in AdcSampler_esp32.cpp and AdcSampler_esp32s3.cpp */ - static bool map_gpio_to_channel(int gpio, adc_unit_t &unit, adc_channel_t &channel); + static bool map_gpio_to_channel(int gpio, adc_unit_t& unit, adc_channel_t& channel); // Shared ADC1 oneshot handle (single instance for all AdcSampler objects) static adc_oneshot_unit_handle_t shared_unit_; @@ -110,10 +113,22 @@ private: // Stub for unsupported targets to keep interfaces consistent class AdcSampler { -public: - bool init(int /*gpio*/, int /*atten*/ = 0, int /*bitwidth*/ = 0, size_t /*window_size*/ = 1) { return false; } - bool sampleOnce() { return false; } - int getFilteredMilliVolts() const { return 0; } - static constexpr bool isSupported() { return false; } + public: + bool init(int /*gpio*/, int /*atten*/ = 0, int /*bitwidth*/ = 0, size_t /*window_size*/ = 1) + { + return false; + } + bool sampleOnce() + { + return false; + } + int getFilteredMilliVolts() const + { + return 0; + } + static constexpr bool isSupported() + { + return false; + } }; #endif diff --git a/components/Monitoring/Monitoring/AdcSampler_esp32.cpp b/components/Monitoring/Monitoring/AdcSampler_esp32.cpp index 936afe2..140c5c8 100644 --- a/components/Monitoring/Monitoring/AdcSampler_esp32.cpp +++ b/components/Monitoring/Monitoring/AdcSampler_esp32.cpp @@ -19,9 +19,9 @@ #if defined(CONFIG_IDF_TARGET_ESP32) -bool AdcSampler::map_gpio_to_channel(int gpio, adc_unit_t &unit, adc_channel_t &channel) +bool AdcSampler::map_gpio_to_channel(int gpio, adc_unit_t& unit, adc_channel_t& channel) { - unit = ADC_UNIT_1; // Only use ADC1 to avoid Wi-Fi conflict + unit = ADC_UNIT_1; // Only use ADC1 to avoid Wi-Fi conflict // ESP32: ADC1 GPIO mapping (GPIO32-39) switch (gpio) diff --git a/components/Monitoring/Monitoring/AdcSampler_esp32s3.cpp b/components/Monitoring/Monitoring/AdcSampler_esp32s3.cpp index a9cc976..e115f27 100644 --- a/components/Monitoring/Monitoring/AdcSampler_esp32s3.cpp +++ b/components/Monitoring/Monitoring/AdcSampler_esp32s3.cpp @@ -21,9 +21,9 @@ #if defined(CONFIG_IDF_TARGET_ESP32S3) -bool AdcSampler::map_gpio_to_channel(int gpio, adc_unit_t &unit, adc_channel_t &channel) +bool AdcSampler::map_gpio_to_channel(int gpio, adc_unit_t& unit, adc_channel_t& channel) { - unit = ADC_UNIT_1; // Only use ADC1 to avoid Wi-Fi conflict + unit = ADC_UNIT_1; // Only use ADC1 to avoid Wi-Fi conflict // ESP32-S3: ADC1 on GPIO1–10 → CH0–CH9 if (gpio >= 1 && gpio <= 10) @@ -36,4 +36,4 @@ bool AdcSampler::map_gpio_to_channel(int gpio, adc_unit_t &unit, adc_channel_t & return false; } -#endif // CONFIG_IDF_TARGET_ESP32S3 +#endif // CONFIG_IDF_TARGET_ESP32S3 diff --git a/components/Monitoring/Monitoring/BatteryMonitor.cpp b/components/Monitoring/Monitoring/BatteryMonitor.cpp index 97d2f95..51bbcab 100644 --- a/components/Monitoring/Monitoring/BatteryMonitor.cpp +++ b/components/Monitoring/Monitoring/BatteryMonitor.cpp @@ -9,7 +9,7 @@ #include "BatteryMonitor.hpp" #include -static const char *TAG = "[BatteryMonitor]"; +static const char* TAG = "[BatteryMonitor]"; bool BatteryMonitor::setup() { @@ -86,8 +86,8 @@ float BatteryMonitor::voltageToPercentage(int voltage_mv) // Linear interpolation between lookup table points for (size_t i = 0; i < soc_lookup_.size() - 1; ++i) { - const auto &high = soc_lookup_[i]; - const auto &low = soc_lookup_[i + 1]; + const auto& high = soc_lookup_[i]; + const auto& low = soc_lookup_[i + 1]; if (volts <= high.voltage_mv && volts >= low.voltage_mv) { diff --git a/components/Monitoring/Monitoring/BatteryMonitor.hpp b/components/Monitoring/Monitoring/BatteryMonitor.hpp index defdf63..0ba02e1 100644 --- a/components/Monitoring/Monitoring/BatteryMonitor.hpp +++ b/components/Monitoring/Monitoring/BatteryMonitor.hpp @@ -20,7 +20,6 @@ #include "AdcSampler.hpp" #include "sdkconfig.h" - /** * @struct BatteryStatus * @brief Battery status information @@ -48,7 +47,7 @@ struct BatteryStatus */ class BatteryMonitor { -public: + public: BatteryMonitor() = default; ~BatteryMonitor() = default; @@ -87,7 +86,7 @@ public: #endif } -private: + private: /** * @brief Li-ion/Li-Po voltage to SOC lookup table entry */ @@ -102,7 +101,7 @@ private: * Based on typical 3.7V nominal Li-ion/Li-Po cell characteristics */ static constexpr std::array soc_lookup_ = {{ - {4200.0f, 100.0f}, // Fully charged + {4200.0f, 100.0f}, // Fully charged {4060.0f, 90.0f}, {3980.0f, 80.0f}, {3920.0f, 70.0f}, @@ -112,10 +111,10 @@ private: {3770.0f, 30.0f}, {3740.0f, 20.0f}, {3680.0f, 10.0f}, - {3450.0f, 5.0f}, // Low battery warning - {3300.0f, 0.0f}, // Empty / cutoff voltage + {3450.0f, 5.0f}, // Low battery warning + {3300.0f, 0.0f}, // Empty / cutoff voltage }}; - float scale_{1.0f}; // Voltage divider scaling factor - mutable AdcSampler adc_; // ADC sampler instance (BSP layer) + float scale_{1.0f}; // Voltage divider scaling factor + mutable AdcSampler adc_; // ADC sampler instance (BSP layer) }; diff --git a/components/Monitoring/Monitoring/CurrentMonitor.cpp b/components/Monitoring/Monitoring/CurrentMonitor.cpp index 792b575..64a0c67 100644 --- a/components/Monitoring/Monitoring/CurrentMonitor.cpp +++ b/components/Monitoring/Monitoring/CurrentMonitor.cpp @@ -9,7 +9,7 @@ #include "CurrentMonitor.hpp" #include -static const char *TAG = "[CurrentMonitor]"; +static const char* TAG = "[CurrentMonitor]"; void CurrentMonitor::setup() { @@ -40,7 +40,7 @@ float CurrentMonitor::getCurrentMilliAmps() const if (!AdcSampler::isSupported()) return 0.0f; - const int shunt_milliohm = CONFIG_MONITORING_LED_SHUNT_MILLIOHM; // mΩ + const int shunt_milliohm = CONFIG_MONITORING_LED_SHUNT_MILLIOHM; // mΩ if (shunt_milliohm <= 0) return 0.0f; diff --git a/components/Monitoring/Monitoring/CurrentMonitor.hpp b/components/Monitoring/Monitoring/CurrentMonitor.hpp index b474196..19e5328 100644 --- a/components/Monitoring/Monitoring/CurrentMonitor.hpp +++ b/components/Monitoring/Monitoring/CurrentMonitor.hpp @@ -17,8 +17,8 @@ */ #include -#include "sdkconfig.h" #include "AdcSampler.hpp" +#include "sdkconfig.h" /** * @class CurrentMonitor @@ -34,7 +34,7 @@ */ class CurrentMonitor { -public: + public: CurrentMonitor() = default; ~CurrentMonitor() = default; @@ -54,8 +54,8 @@ public: #endif } -private: - mutable AdcSampler adc_; // ADC sampler instance (BSP layer) + private: + mutable AdcSampler adc_; // ADC sampler instance (BSP layer) }; #endif diff --git a/components/Monitoring/Monitoring/MonitoringManager.cpp b/components/Monitoring/Monitoring/MonitoringManager.cpp index 1f265a3..a737c87 100644 --- a/components/Monitoring/Monitoring/MonitoringManager.cpp +++ b/components/Monitoring/Monitoring/MonitoringManager.cpp @@ -10,7 +10,7 @@ #include #include "sdkconfig.h" -static const char *TAG = "[MonitoringManager]"; +static const char* TAG = "[MonitoringManager]"; void MonitoringManager::setup() { @@ -18,11 +18,8 @@ void MonitoringManager::setup() if (CurrentMonitor::isEnabled()) { cm_.setup(); - ESP_LOGI(TAG, "LED current monitoring enabled. Interval=%dms, Samples=%d, Gain=%d, R=%dmΩ", - CONFIG_MONITORING_LED_INTERVAL_MS, - CONFIG_MONITORING_LED_SAMPLES, - CONFIG_MONITORING_LED_GAIN, - CONFIG_MONITORING_LED_SHUNT_MILLIOHM); + ESP_LOGI(TAG, "LED current monitoring enabled. Interval=%dms, Samples=%d, Gain=%d, R=%dmΩ", CONFIG_MONITORING_LED_INTERVAL_MS, + CONFIG_MONITORING_LED_SAMPLES, CONFIG_MONITORING_LED_GAIN, CONFIG_MONITORING_LED_SHUNT_MILLIOHM); } else { @@ -36,11 +33,8 @@ void MonitoringManager::setup() if (BatteryMonitor::isEnabled()) { bm_.setup(); - ESP_LOGI(TAG, "Battery monitoring enabled. Interval=%dms, Samples=%d, R-Top=%dΩ, R-Bottom=%dΩ", - CONFIG_MONITORING_BATTERY_INTERVAL_MS, - CONFIG_MONITORING_BATTERY_SAMPLES, - CONFIG_MONITORING_BATTERY_DIVIDER_R_TOP_OHM, - CONFIG_MONITORING_BATTERY_DIVIDER_R_BOTTOM_OHM); + ESP_LOGI(TAG, "Battery monitoring enabled. Interval=%dms, Samples=%d, R-Top=%dΩ, R-Bottom=%dΩ", CONFIG_MONITORING_BATTERY_INTERVAL_MS, + CONFIG_MONITORING_BATTERY_SAMPLES, CONFIG_MONITORING_BATTERY_DIVIDER_R_TOP_OHM, CONFIG_MONITORING_BATTERY_DIVIDER_R_BOTTOM_OHM); } else { @@ -77,9 +71,9 @@ void MonitoringManager::stop() } } -void MonitoringManager::taskEntry(void *arg) +void MonitoringManager::taskEntry(void* arg) { - static_cast(arg)->run(); + static_cast(arg)->run(); } void MonitoringManager::run() @@ -105,7 +99,7 @@ void MonitoringManager::run() while (true) { now_tick = xTaskGetTickCount(); - TickType_t wait_ticks = pdMS_TO_TICKS(50); // Default wait time + TickType_t wait_ticks = pdMS_TO_TICKS(50); // Default wait time #if CONFIG_MONITORING_LED_CURRENT if (CurrentMonitor::isEnabled() && now_tick >= next_tick_led) diff --git a/components/Monitoring/Monitoring/MonitoringManager.hpp b/components/Monitoring/Monitoring/MonitoringManager.hpp index 36069e7..c8962d9 100644 --- a/components/Monitoring/Monitoring/MonitoringManager.hpp +++ b/components/Monitoring/Monitoring/MonitoringManager.hpp @@ -35,7 +35,7 @@ */ class MonitoringManager { -public: + public: MonitoringManager() = default; ~MonitoringManager() = default; @@ -57,8 +57,8 @@ public: return CurrentMonitor::isEnabled() || BatteryMonitor::isEnabled(); } -private: - static void taskEntry(void *arg); + private: + static void taskEntry(void* arg); void run(); TaskHandle_t task_{nullptr}; diff --git a/components/OpenIrisTasks/OpenIrisTasks/OpenIrisTasks.cpp b/components/OpenIrisTasks/OpenIrisTasks/OpenIrisTasks.cpp index 71b8a84..a6bd986 100644 --- a/components/OpenIrisTasks/OpenIrisTasks/OpenIrisTasks.cpp +++ b/components/OpenIrisTasks/OpenIrisTasks/OpenIrisTasks.cpp @@ -1,19 +1,17 @@ #include "OpenIrisTasks.hpp" -void restart_the_board(void *arg) { - esp_restart(); +void restart_the_board(void* arg) +{ + esp_restart(); } void OpenIrisTasks::ScheduleRestart(const int milliseconds) { - esp_timer_handle_t timerHandle; - constexpr esp_timer_create_args_t args = { - .callback = &restart_the_board, - .arg = nullptr, - .name = "restartBoard"}; + esp_timer_handle_t timerHandle; + constexpr esp_timer_create_args_t args = {.callback = &restart_the_board, .arg = nullptr, .name = "restartBoard"}; - if (const auto result = esp_timer_create(&args, &timerHandle); result == ESP_OK) - { - esp_timer_start_once(timerHandle, milliseconds); - } + if (const auto result = esp_timer_create(&args, &timerHandle); result == ESP_OK) + { + esp_timer_start_once(timerHandle, milliseconds); + } } \ No newline at end of file diff --git a/components/OpenIrisTasks/OpenIrisTasks/OpenIrisTasks.hpp b/components/OpenIrisTasks/OpenIrisTasks/OpenIrisTasks.hpp index 2897b57..2609bf3 100644 --- a/components/OpenIrisTasks/OpenIrisTasks/OpenIrisTasks.hpp +++ b/components/OpenIrisTasks/OpenIrisTasks/OpenIrisTasks.hpp @@ -2,14 +2,14 @@ #ifndef OPENIRISTASKS_HPP #define OPENIRISTASKS_HPP -#include "helpers.hpp" +#include "esp_system.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "esp_system.h" +#include "helpers.hpp" namespace OpenIrisTasks { - void ScheduleRestart(int milliseconds); +void ScheduleRestart(int milliseconds); }; #endif \ No newline at end of file diff --git a/components/Preferences/Preferences/Preferences.cpp b/components/Preferences/Preferences/Preferences.cpp index c09a9e6..7ae8f53 100644 --- a/components/Preferences/Preferences/Preferences.cpp +++ b/components/Preferences/Preferences/Preferences.cpp @@ -3,56 +3,56 @@ #include "Preferences.hpp" -const char *PREFERENCES_TAG = "[PREFERENCES]"; -const char *nvs_errors[] = {"OTHER", "NOT_INITIALIZED", "NOT_FOUND", "TYPE_MISMATCH", "READ_ONLY", "NOT_ENOUGH_SPACE", "INVALID_NAME", - "INVALID_HANDLE", "REMOVE_FAILED", "KEY_TOO_LONG", "PAGE_FULL", "INVALID_STATE", "INVALID_LENGTH"}; +const char* PREFERENCES_TAG = "[PREFERENCES]"; +const char* nvs_errors[] = {"OTHER", "NOT_INITIALIZED", "NOT_FOUND", "TYPE_MISMATCH", "READ_ONLY", "NOT_ENOUGH_SPACE", "INVALID_NAME", + "INVALID_HANDLE", "REMOVE_FAILED", "KEY_TOO_LONG", "PAGE_FULL", "INVALID_STATE", "INVALID_LENGTH"}; #define nvs_error(e) (((e) > ESP_ERR_NVS_BASE) ? nvs_errors[(e) & ~(ESP_ERR_NVS_BASE)] : nvs_errors[0]) Preferences::Preferences() : _handle(0), _started(false), _readOnly(false) {} -bool Preferences::begin(const char *name, bool readOnly, const char *partition_label) +bool Preferences::begin(const char* name, bool readOnly, const char* partition_label) { - if (_started) - { - return false; - } - _readOnly = readOnly; - esp_err_t err = ESP_OK; - if (partition_label != NULL) - { - err = nvs_flash_init_partition(partition_label); + if (_started) + { + return false; + } + _readOnly = readOnly; + esp_err_t err = ESP_OK; + if (partition_label != NULL) + { + err = nvs_flash_init_partition(partition_label); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_flash_init_partition failed: %s", nvs_error(err)); + return false; + } + err = nvs_open_from_partition(partition_label, name, readOnly ? NVS_READONLY : NVS_READWRITE, &_handle); + } + else + { + err = nvs_open(name, readOnly ? NVS_READONLY : NVS_READWRITE, &_handle); + } if (err) { - ESP_LOGE(PREFERENCES_TAG, "nvs_flash_init_partition failed: %s", nvs_error(err)); - return false; + ESP_LOGE(PREFERENCES_TAG, "nvs_open failed: %s", nvs_error(err)); + return false; } - err = nvs_open_from_partition(partition_label, name, readOnly ? NVS_READONLY : NVS_READWRITE, &_handle); - } - else - { - err = nvs_open(name, readOnly ? NVS_READONLY : NVS_READWRITE, &_handle); - } - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_open failed: %s", nvs_error(err)); - return false; - } - _started = true; - return true; + _started = true; + return true; } Preferences::~Preferences() { - end(); + end(); } void Preferences::end() { - if (!_started) - { - return; - } - nvs_close(_handle); - _started = false; + if (!_started) + { + return; + } + nvs_close(_handle); + _started = false; } /* @@ -61,608 +61,608 @@ void Preferences::end() bool Preferences::clear() { - if (!_started || _readOnly) - { - return false; - } - esp_err_t err = nvs_erase_all(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_erase_all fail: %s", nvs_error(err)); - return false; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s", nvs_error(err)); - return false; - } - return true; + if (!_started || _readOnly) + { + return false; + } + esp_err_t err = nvs_erase_all(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_erase_all fail: %s", nvs_error(err)); + return false; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s", nvs_error(err)); + return false; + } + return true; } /* * Remove a key * */ -bool Preferences::remove(const char *key) +bool Preferences::remove(const char* key) { - if (!_started || !key || _readOnly) - { - return false; - } + if (!_started || !key || _readOnly) + { + return false; + } - esp_err_t err = nvs_erase_key(_handle, key); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_erase_key fail: %s %s", key, nvs_error(err)); - return false; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); - return false; - } - return true; + esp_err_t err = nvs_erase_key(_handle, key); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_erase_key fail: %s %s", key, nvs_error(err)); + return false; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); + return false; + } + return true; } /* * Put a key value * */ -size_t Preferences::putChar(const char *key, int8_t value) +size_t Preferences::putChar(const char* key, int8_t value) { - if (!_started || !key || _readOnly) - { - return 0; - } - esp_err_t err = nvs_set_i8(_handle, key, value); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_set_i8 fail: %s %s", key, nvs_error(err)); - return 0; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); - return 0; - } - return 1; + if (!_started || !key || _readOnly) + { + return 0; + } + esp_err_t err = nvs_set_i8(_handle, key, value); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_set_i8 fail: %s %s", key, nvs_error(err)); + return 0; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); + return 0; + } + return 1; } -size_t Preferences::putUChar(const char *key, uint8_t value) +size_t Preferences::putUChar(const char* key, uint8_t value) { - if (!_started || !key || _readOnly) - { - return 0; - } - esp_err_t err = nvs_set_u8(_handle, key, value); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_set_u8 fail: %s %s", key, nvs_error(err)); - return 0; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); - return 0; - } - return 1; + if (!_started || !key || _readOnly) + { + return 0; + } + esp_err_t err = nvs_set_u8(_handle, key, value); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_set_u8 fail: %s %s", key, nvs_error(err)); + return 0; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); + return 0; + } + return 1; } -size_t Preferences::putShort(const char *key, int16_t value) +size_t Preferences::putShort(const char* key, int16_t value) { - if (!_started || !key || _readOnly) - { - return 0; - } - esp_err_t err = nvs_set_i16(_handle, key, value); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_set_i16 fail: %s %s", key, nvs_error(err)); - return 0; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); - return 0; - } - return 2; + if (!_started || !key || _readOnly) + { + return 0; + } + esp_err_t err = nvs_set_i16(_handle, key, value); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_set_i16 fail: %s %s", key, nvs_error(err)); + return 0; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); + return 0; + } + return 2; } -size_t Preferences::putUShort(const char *key, uint16_t value) +size_t Preferences::putUShort(const char* key, uint16_t value) { - if (!_started || !key || _readOnly) - { - return 0; - } - esp_err_t err = nvs_set_u16(_handle, key, value); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_set_u16 fail: %s %s", key, nvs_error(err)); - return 0; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); - return 0; - } - return 2; + if (!_started || !key || _readOnly) + { + return 0; + } + esp_err_t err = nvs_set_u16(_handle, key, value); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_set_u16 fail: %s %s", key, nvs_error(err)); + return 0; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); + return 0; + } + return 2; } -size_t Preferences::putInt(const char *key, int32_t value) +size_t Preferences::putInt(const char* key, int32_t value) { - if (!_started || !key || _readOnly) - { - return 0; - } - esp_err_t err = nvs_set_i32(_handle, key, value); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_set_i32 fail: %s %s", key, nvs_error(err)); - return 0; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); - return 0; - } - return 4; + if (!_started || !key || _readOnly) + { + return 0; + } + esp_err_t err = nvs_set_i32(_handle, key, value); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_set_i32 fail: %s %s", key, nvs_error(err)); + return 0; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); + return 0; + } + return 4; } -size_t Preferences::putUInt(const char *key, uint32_t value) +size_t Preferences::putUInt(const char* key, uint32_t value) { - if (!_started || !key || _readOnly) - { - return 0; - } - esp_err_t err = nvs_set_u32(_handle, key, value); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_set_u32 fail: %s %s", key, nvs_error(err)); - return 0; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); - return 0; - } - return 4; + if (!_started || !key || _readOnly) + { + return 0; + } + esp_err_t err = nvs_set_u32(_handle, key, value); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_set_u32 fail: %s %s", key, nvs_error(err)); + return 0; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); + return 0; + } + return 4; } -size_t Preferences::putLong(const char *key, int32_t value) +size_t Preferences::putLong(const char* key, int32_t value) { - return putInt(key, value); + return putInt(key, value); } -size_t Preferences::putULong(const char *key, uint32_t value) +size_t Preferences::putULong(const char* key, uint32_t value) { - return putUInt(key, value); + return putUInt(key, value); } -size_t Preferences::putLong64(const char *key, int64_t value) +size_t Preferences::putLong64(const char* key, int64_t value) { - if (!_started || !key || _readOnly) - { - return 0; - } - esp_err_t err = nvs_set_i64(_handle, key, value); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_set_i64 fail: %s %s", key, nvs_error(err)); - return 0; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); - return 0; - } - return 8; + if (!_started || !key || _readOnly) + { + return 0; + } + esp_err_t err = nvs_set_i64(_handle, key, value); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_set_i64 fail: %s %s", key, nvs_error(err)); + return 0; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); + return 0; + } + return 8; } -size_t Preferences::putULong64(const char *key, uint64_t value) +size_t Preferences::putULong64(const char* key, uint64_t value) { - if (!_started || !key || _readOnly) - { - return 0; - } - esp_err_t err = nvs_set_u64(_handle, key, value); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_set_u64 fail: %s %s", key, nvs_error(err)); - return 0; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); - return 0; - } - return 8; + if (!_started || !key || _readOnly) + { + return 0; + } + esp_err_t err = nvs_set_u64(_handle, key, value); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_set_u64 fail: %s %s", key, nvs_error(err)); + return 0; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); + return 0; + } + return 8; } -size_t Preferences::putFloat(const char *key, const float_t value) +size_t Preferences::putFloat(const char* key, const float_t value) { - return putBytes(key, (void *)&value, sizeof(float_t)); + return putBytes(key, (void*)&value, sizeof(float_t)); } -size_t Preferences::putDouble(const char *key, const double_t value) +size_t Preferences::putDouble(const char* key, const double_t value) { - return putBytes(key, (void *)&value, sizeof(double_t)); + return putBytes(key, (void*)&value, sizeof(double_t)); } -size_t Preferences::putBool(const char *key, const bool value) +size_t Preferences::putBool(const char* key, const bool value) { - return putUChar(key, (uint8_t)(value ? 1 : 0)); + return putUChar(key, (uint8_t)(value ? 1 : 0)); } -size_t Preferences::putString(const char *key, const char *value) +size_t Preferences::putString(const char* key, const char* value) { - if (!_started || !key || !value || _readOnly) - { - return 0; - } - esp_err_t err = nvs_set_str(_handle, key, value); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_set_str fail: %s %s", key, nvs_error(err)); - return 0; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); - return 0; - } - return strlen(value); + if (!_started || !key || !value || _readOnly) + { + return 0; + } + esp_err_t err = nvs_set_str(_handle, key, value); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_set_str fail: %s %s", key, nvs_error(err)); + return 0; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); + return 0; + } + return strlen(value); } -size_t Preferences::putString(const char *key, const std::string value) +size_t Preferences::putString(const char* key, const std::string value) { - return putString(key, value.c_str()); + return putString(key, value.c_str()); } -size_t Preferences::putBytes(const char *key, const void *value, size_t len) +size_t Preferences::putBytes(const char* key, const void* value, size_t len) { - if (!_started || !key || !value || !len || _readOnly) - { - return 0; - } - esp_err_t err = nvs_set_blob(_handle, key, value, len); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_set_blob fail: %s %s", key, nvs_error(err)); - return 0; - } - err = nvs_commit(_handle); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); - return 0; - } - return len; + if (!_started || !key || !value || !len || _readOnly) + { + return 0; + } + esp_err_t err = nvs_set_blob(_handle, key, value, len); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_set_blob fail: %s %s", key, nvs_error(err)); + return 0; + } + err = nvs_commit(_handle); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_commit fail: %s %s", key, nvs_error(err)); + return 0; + } + return len; } -PreferenceType Preferences::getType(const char *key) +PreferenceType Preferences::getType(const char* key) { - if (!_started || !key || strlen(key) > 15) - { + if (!_started || !key || strlen(key) > 15) + { + return PT_INVALID; + } + int8_t mt1; + uint8_t mt2; + int16_t mt3; + uint16_t mt4; + int32_t mt5; + uint32_t mt6; + int64_t mt7; + uint64_t mt8; + size_t len = 0; + if (nvs_get_i8(_handle, key, &mt1) == ESP_OK) + { + return PT_I8; + } + if (nvs_get_u8(_handle, key, &mt2) == ESP_OK) + { + return PT_U8; + } + if (nvs_get_i16(_handle, key, &mt3) == ESP_OK) + { + return PT_I16; + } + if (nvs_get_u16(_handle, key, &mt4) == ESP_OK) + { + return PT_U16; + } + if (nvs_get_i32(_handle, key, &mt5) == ESP_OK) + { + return PT_I32; + } + if (nvs_get_u32(_handle, key, &mt6) == ESP_OK) + { + return PT_U32; + } + if (nvs_get_i64(_handle, key, &mt7) == ESP_OK) + { + return PT_I64; + } + if (nvs_get_u64(_handle, key, &mt8) == ESP_OK) + { + return PT_U64; + } + if (nvs_get_str(_handle, key, NULL, &len) == ESP_OK) + { + return PT_STR; + } + if (nvs_get_blob(_handle, key, NULL, &len) == ESP_OK) + { + return PT_BLOB; + } return PT_INVALID; - } - int8_t mt1; - uint8_t mt2; - int16_t mt3; - uint16_t mt4; - int32_t mt5; - uint32_t mt6; - int64_t mt7; - uint64_t mt8; - size_t len = 0; - if (nvs_get_i8(_handle, key, &mt1) == ESP_OK) - { - return PT_I8; - } - if (nvs_get_u8(_handle, key, &mt2) == ESP_OK) - { - return PT_U8; - } - if (nvs_get_i16(_handle, key, &mt3) == ESP_OK) - { - return PT_I16; - } - if (nvs_get_u16(_handle, key, &mt4) == ESP_OK) - { - return PT_U16; - } - if (nvs_get_i32(_handle, key, &mt5) == ESP_OK) - { - return PT_I32; - } - if (nvs_get_u32(_handle, key, &mt6) == ESP_OK) - { - return PT_U32; - } - if (nvs_get_i64(_handle, key, &mt7) == ESP_OK) - { - return PT_I64; - } - if (nvs_get_u64(_handle, key, &mt8) == ESP_OK) - { - return PT_U64; - } - if (nvs_get_str(_handle, key, NULL, &len) == ESP_OK) - { - return PT_STR; - } - if (nvs_get_blob(_handle, key, NULL, &len) == ESP_OK) - { - return PT_BLOB; - } - return PT_INVALID; } -bool Preferences::isKey(const char *key) +bool Preferences::isKey(const char* key) { - return getType(key) != PT_INVALID; + return getType(key) != PT_INVALID; } /* * Get a key value * */ -int8_t Preferences::getChar(const char *key, const int8_t defaultValue) +int8_t Preferences::getChar(const char* key, const int8_t defaultValue) { - int8_t value = defaultValue; - if (!_started || !key) - { + int8_t value = defaultValue; + if (!_started || !key) + { + return value; + } + esp_err_t err = nvs_get_i8(_handle, key, &value); + if (err) + { + ESP_LOGV(PREFERENCES_TAG, "nvs_get_i8 fail: %s %s", key, nvs_error(err)); + } return value; - } - esp_err_t err = nvs_get_i8(_handle, key, &value); - if (err) - { - ESP_LOGV(PREFERENCES_TAG, "nvs_get_i8 fail: %s %s", key, nvs_error(err)); - } - return value; } -uint8_t Preferences::getUChar(const char *key, const uint8_t defaultValue) +uint8_t Preferences::getUChar(const char* key, const uint8_t defaultValue) { - uint8_t value = defaultValue; - if (!_started || !key) - { + uint8_t value = defaultValue; + if (!_started || !key) + { + return value; + } + esp_err_t err = nvs_get_u8(_handle, key, &value); + if (err) + { + ESP_LOGV(PREFERENCES_TAG, "nvs_get_u8 fail: %s %s", key, nvs_error(err)); + } return value; - } - esp_err_t err = nvs_get_u8(_handle, key, &value); - if (err) - { - ESP_LOGV(PREFERENCES_TAG, "nvs_get_u8 fail: %s %s", key, nvs_error(err)); - } - return value; } -int16_t Preferences::getShort(const char *key, const int16_t defaultValue) +int16_t Preferences::getShort(const char* key, const int16_t defaultValue) { - int16_t value = defaultValue; - if (!_started || !key) - { + int16_t value = defaultValue; + if (!_started || !key) + { + return value; + } + esp_err_t err = nvs_get_i16(_handle, key, &value); + if (err) + { + ESP_LOGV(PREFERENCES_TAG, "nvs_get_i16 fail: %s %s", key, nvs_error(err)); + } return value; - } - esp_err_t err = nvs_get_i16(_handle, key, &value); - if (err) - { - ESP_LOGV(PREFERENCES_TAG, "nvs_get_i16 fail: %s %s", key, nvs_error(err)); - } - return value; } -uint16_t Preferences::getUShort(const char *key, const uint16_t defaultValue) +uint16_t Preferences::getUShort(const char* key, const uint16_t defaultValue) { - uint16_t value = defaultValue; - if (!_started || !key) - { + uint16_t value = defaultValue; + if (!_started || !key) + { + return value; + } + esp_err_t err = nvs_get_u16(_handle, key, &value); + if (err) + { + ESP_LOGV(PREFERENCES_TAG, "nvs_get_u16 fail: %s %s", key, nvs_error(err)); + } return value; - } - esp_err_t err = nvs_get_u16(_handle, key, &value); - if (err) - { - ESP_LOGV(PREFERENCES_TAG, "nvs_get_u16 fail: %s %s", key, nvs_error(err)); - } - return value; } -int32_t Preferences::getInt(const char *key, const int32_t defaultValue) +int32_t Preferences::getInt(const char* key, const int32_t defaultValue) { - int32_t value = defaultValue; - if (!_started || !key) - { + int32_t value = defaultValue; + if (!_started || !key) + { + return value; + } + esp_err_t err = nvs_get_i32(_handle, key, &value); + if (err) + { + ESP_LOGV(PREFERENCES_TAG, "nvs_get_i32 fail: %s %s", key, nvs_error(err)); + } return value; - } - esp_err_t err = nvs_get_i32(_handle, key, &value); - if (err) - { - ESP_LOGV(PREFERENCES_TAG, "nvs_get_i32 fail: %s %s", key, nvs_error(err)); - } - return value; } -uint32_t Preferences::getUInt(const char *key, const uint32_t defaultValue) +uint32_t Preferences::getUInt(const char* key, const uint32_t defaultValue) { - uint32_t value = defaultValue; - if (!_started || !key) - { + uint32_t value = defaultValue; + if (!_started || !key) + { + return value; + } + esp_err_t err = nvs_get_u32(_handle, key, &value); + if (err) + { + ESP_LOGV(PREFERENCES_TAG, "nvs_get_u32 fail: %s %s", key, nvs_error(err)); + } return value; - } - esp_err_t err = nvs_get_u32(_handle, key, &value); - if (err) - { - ESP_LOGV(PREFERENCES_TAG, "nvs_get_u32 fail: %s %s", key, nvs_error(err)); - } - return value; } -int32_t Preferences::getLong(const char *key, const int32_t defaultValue) +int32_t Preferences::getLong(const char* key, const int32_t defaultValue) { - return getInt(key, defaultValue); + return getInt(key, defaultValue); } -uint32_t Preferences::getULong(const char *key, const uint32_t defaultValue) +uint32_t Preferences::getULong(const char* key, const uint32_t defaultValue) { - return getUInt(key, defaultValue); + return getUInt(key, defaultValue); } -int64_t Preferences::getLong64(const char *key, const int64_t defaultValue) +int64_t Preferences::getLong64(const char* key, const int64_t defaultValue) { - int64_t value = defaultValue; - if (!_started || !key) - { + int64_t value = defaultValue; + if (!_started || !key) + { + return value; + } + esp_err_t err = nvs_get_i64(_handle, key, &value); + if (err) + { + ESP_LOGV(PREFERENCES_TAG, "nvs_get_i64 fail: %s %s", key, nvs_error(err)); + } return value; - } - esp_err_t err = nvs_get_i64(_handle, key, &value); - if (err) - { - ESP_LOGV(PREFERENCES_TAG, "nvs_get_i64 fail: %s %s", key, nvs_error(err)); - } - return value; } -uint64_t Preferences::getULong64(const char *key, const uint64_t defaultValue) +uint64_t Preferences::getULong64(const char* key, const uint64_t defaultValue) { - uint64_t value = defaultValue; - if (!_started || !key) - { + uint64_t value = defaultValue; + if (!_started || !key) + { + return value; + } + esp_err_t err = nvs_get_u64(_handle, key, &value); + if (err) + { + ESP_LOGV(PREFERENCES_TAG, "nvs_get_u64 fail: %s %s", key, nvs_error(err)); + } return value; - } - esp_err_t err = nvs_get_u64(_handle, key, &value); - if (err) - { - ESP_LOGV(PREFERENCES_TAG, "nvs_get_u64 fail: %s %s", key, nvs_error(err)); - } - return value; } -float_t Preferences::getFloat(const char *key, const float_t defaultValue) +float_t Preferences::getFloat(const char* key, const float_t defaultValue) { - float_t value = defaultValue; - getBytes(key, (void *)&value, sizeof(float_t)); - return value; + float_t value = defaultValue; + getBytes(key, (void*)&value, sizeof(float_t)); + return value; } -double_t Preferences::getDouble(const char *key, const double_t defaultValue) +double_t Preferences::getDouble(const char* key, const double_t defaultValue) { - double_t value = defaultValue; - getBytes(key, (void *)&value, sizeof(double_t)); - return value; + double_t value = defaultValue; + getBytes(key, (void*)&value, sizeof(double_t)); + return value; } -bool Preferences::getBool(const char *key, const bool defaultValue) +bool Preferences::getBool(const char* key, const bool defaultValue) { - return getUChar(key, defaultValue ? 1 : 0) == 1; + return getUChar(key, defaultValue ? 1 : 0) == 1; } -size_t Preferences::getString(const char *key, char *value, const size_t maxLen) +size_t Preferences::getString(const char* key, char* value, const size_t maxLen) { - size_t len = 0; - if (!_started || !key || !value || !maxLen) - { - return 0; - } - esp_err_t err = nvs_get_str(_handle, key, NULL, &len); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_get_str len fail: %s %s", key, nvs_error(err)); - return 0; - } - if (len > maxLen) - { - ESP_LOGE(PREFERENCES_TAG, "not enough space in value: %u < %u", maxLen, len); - return 0; - } - err = nvs_get_str(_handle, key, value, &len); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_get_str fail: %s %s", key, nvs_error(err)); - return 0; - } - return len; -} - -std::string Preferences::getString(const char *key, const std::string defaultValue) -{ - char *value = NULL; - size_t len = 0; - if (!_started || !key) - { - return defaultValue; - } - esp_err_t err = nvs_get_str(_handle, key, value, &len); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_get_str len fail: %s %s", key, nvs_error(err)); - return defaultValue; - } - char buf[len]; - value = buf; - err = nvs_get_str(_handle, key, value, &len); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_get_str fail: %s %s", key, nvs_error(err)); - return defaultValue; - } - return std::string(buf); -} - -size_t Preferences::getBytesLength(const char *key) -{ - size_t len = 0; - if (!_started || !key) - { - return 0; - } - esp_err_t err = nvs_get_blob(_handle, key, NULL, &len); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_get_blob len fail: %s %s", key, nvs_error(err)); - return 0; - } - return len; -} - -size_t Preferences::getBytes(const char *key, void *buf, size_t maxLen) -{ - size_t len = getBytesLength(key); - if (!len || !buf || !maxLen) - { + size_t len = 0; + if (!_started || !key || !value || !maxLen) + { + return 0; + } + esp_err_t err = nvs_get_str(_handle, key, NULL, &len); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_get_str len fail: %s %s", key, nvs_error(err)); + return 0; + } + if (len > maxLen) + { + ESP_LOGE(PREFERENCES_TAG, "not enough space in value: %u < %u", maxLen, len); + return 0; + } + err = nvs_get_str(_handle, key, value, &len); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_get_str fail: %s %s", key, nvs_error(err)); + return 0; + } + return len; +} + +std::string Preferences::getString(const char* key, const std::string defaultValue) +{ + char* value = NULL; + size_t len = 0; + if (!_started || !key) + { + return defaultValue; + } + esp_err_t err = nvs_get_str(_handle, key, value, &len); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_get_str len fail: %s %s", key, nvs_error(err)); + return defaultValue; + } + char buf[len]; + value = buf; + err = nvs_get_str(_handle, key, value, &len); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_get_str fail: %s %s", key, nvs_error(err)); + return defaultValue; + } + return std::string(buf); +} + +size_t Preferences::getBytesLength(const char* key) +{ + size_t len = 0; + if (!_started || !key) + { + return 0; + } + esp_err_t err = nvs_get_blob(_handle, key, NULL, &len); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_get_blob len fail: %s %s", key, nvs_error(err)); + return 0; + } + return len; +} + +size_t Preferences::getBytes(const char* key, void* buf, size_t maxLen) +{ + size_t len = getBytesLength(key); + if (!len || !buf || !maxLen) + { + return len; + } + if (len > maxLen) + { + ESP_LOGE(PREFERENCES_TAG, "not enough space in buffer: %u < %u", maxLen, len); + return 0; + } + esp_err_t err = nvs_get_blob(_handle, key, buf, &len); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "nvs_get_blob fail: %s %s", key, nvs_error(err)); + return 0; + } return len; - } - if (len > maxLen) - { - ESP_LOGE(PREFERENCES_TAG, "not enough space in buffer: %u < %u", maxLen, len); - return 0; - } - esp_err_t err = nvs_get_blob(_handle, key, buf, &len); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "nvs_get_blob fail: %s %s", key, nvs_error(err)); - return 0; - } - return len; } size_t Preferences::freeEntries() { - nvs_stats_t nvs_stats; - esp_err_t err = nvs_get_stats(NULL, &nvs_stats); - if (err) - { - ESP_LOGE(PREFERENCES_TAG, "Failed to get nvs statistics"); - return 0; - } - return nvs_stats.free_entries; + nvs_stats_t nvs_stats; + esp_err_t err = nvs_get_stats(NULL, &nvs_stats); + if (err) + { + ESP_LOGE(PREFERENCES_TAG, "Failed to get nvs statistics"); + return 0; + } + return nvs_stats.free_entries; } diff --git a/components/Preferences/Preferences/Preferences.hpp b/components/Preferences/Preferences/Preferences.hpp index b757a18..87e81e3 100644 --- a/components/Preferences/Preferences/Preferences.hpp +++ b/components/Preferences/Preferences/Preferences.hpp @@ -5,83 +5,83 @@ #ifndef PREFERENCES_HPP #define PREFERENCES_HPP -#include -#include -#include #include +#include +#include +#include #include "esp_log.h" -#include "nvs_flash.h" #include "nvs.h" +#include "nvs_flash.h" typedef enum { - PT_I8, - PT_U8, - PT_I16, - PT_U16, - PT_I32, - PT_U32, - PT_I64, - PT_U64, - PT_STR, - PT_BLOB, - PT_INVALID + PT_I8, + PT_U8, + PT_I16, + PT_U16, + PT_I32, + PT_U32, + PT_I64, + PT_U64, + PT_STR, + PT_BLOB, + PT_INVALID } PreferenceType; class Preferences { -protected: - uint32_t _handle; - bool _started; - bool _readOnly; + protected: + uint32_t _handle; + bool _started; + bool _readOnly; -public: - Preferences(); - ~Preferences(); + public: + Preferences(); + ~Preferences(); - bool begin(const char *name, bool readOnly = false, const char *partition_label = nullptr); - void end(); + bool begin(const char* name, bool readOnly = false, const char* partition_label = nullptr); + void end(); - bool clear(); - bool remove(const char *key); + bool clear(); + bool remove(const char* key); - size_t putChar(const char *key, int8_t value); - size_t putUChar(const char *key, uint8_t value); - size_t putShort(const char *key, int16_t value); - size_t putUShort(const char *key, uint16_t value); - size_t putInt(const char *key, int32_t value); - size_t putUInt(const char *key, uint32_t value); - size_t putLong(const char *key, int32_t value); - size_t putULong(const char *key, uint32_t value); - size_t putLong64(const char *key, int64_t value); - size_t putULong64(const char *key, uint64_t value); - size_t putFloat(const char *key, float_t value); - size_t putDouble(const char *key, double_t value); - size_t putBool(const char *key, bool value); - size_t putString(const char *key, const char *value); - size_t putString(const char *key, std::string value); - size_t putBytes(const char *key, const void *value, size_t len); + size_t putChar(const char* key, int8_t value); + size_t putUChar(const char* key, uint8_t value); + size_t putShort(const char* key, int16_t value); + size_t putUShort(const char* key, uint16_t value); + size_t putInt(const char* key, int32_t value); + size_t putUInt(const char* key, uint32_t value); + size_t putLong(const char* key, int32_t value); + size_t putULong(const char* key, uint32_t value); + size_t putLong64(const char* key, int64_t value); + size_t putULong64(const char* key, uint64_t value); + size_t putFloat(const char* key, float_t value); + size_t putDouble(const char* key, double_t value); + size_t putBool(const char* key, bool value); + size_t putString(const char* key, const char* value); + size_t putString(const char* key, std::string value); + size_t putBytes(const char* key, const void* value, size_t len); - bool isKey(const char *key); - PreferenceType getType(const char *key); - int8_t getChar(const char *key, int8_t defaultValue = 0); - uint8_t getUChar(const char *key, uint8_t defaultValue = 0); - int16_t getShort(const char *key, int16_t defaultValue = 0); - uint16_t getUShort(const char *key, uint16_t defaultValue = 0); - int32_t getInt(const char *key, int32_t defaultValue = 0); - uint32_t getUInt(const char *key, uint32_t defaultValue = 0); - int32_t getLong(const char *key, int32_t defaultValue = 0); - uint32_t getULong(const char *key, uint32_t defaultValue = 0); - int64_t getLong64(const char *key, int64_t defaultValue = 0); - uint64_t getULong64(const char *key, uint64_t defaultValue = 0); - float_t getFloat(const char *key, float_t defaultValue = NAN); - double_t getDouble(const char *key, double_t defaultValue = NAN); - bool getBool(const char *key, bool defaultValue = false); - size_t getString(const char *key, char *value, size_t maxLen); - std::string getString(const char *key, std::string defaultValue = std::string()); - size_t getBytesLength(const char *key); - size_t getBytes(const char *key, void *buf, size_t maxLen); - size_t freeEntries(); + bool isKey(const char* key); + PreferenceType getType(const char* key); + int8_t getChar(const char* key, int8_t defaultValue = 0); + uint8_t getUChar(const char* key, uint8_t defaultValue = 0); + int16_t getShort(const char* key, int16_t defaultValue = 0); + uint16_t getUShort(const char* key, uint16_t defaultValue = 0); + int32_t getInt(const char* key, int32_t defaultValue = 0); + uint32_t getUInt(const char* key, uint32_t defaultValue = 0); + int32_t getLong(const char* key, int32_t defaultValue = 0); + uint32_t getULong(const char* key, uint32_t defaultValue = 0); + int64_t getLong64(const char* key, int64_t defaultValue = 0); + uint64_t getULong64(const char* key, uint64_t defaultValue = 0); + float_t getFloat(const char* key, float_t defaultValue = NAN); + double_t getDouble(const char* key, double_t defaultValue = NAN); + bool getBool(const char* key, bool defaultValue = false); + size_t getString(const char* key, char* value, size_t maxLen); + std::string getString(const char* key, std::string defaultValue = std::string()); + size_t getBytesLength(const char* key); + size_t getBytes(const char* key, void* buf, size_t maxLen); + size_t freeEntries(); }; #endif diff --git a/components/ProjectConfig/ProjectConfig/Models.hpp b/components/ProjectConfig/ProjectConfig/Models.hpp index 8561dad..f7c9a8f 100644 --- a/components/ProjectConfig/ProjectConfig/Models.hpp +++ b/components/ProjectConfig/ProjectConfig/Models.hpp @@ -2,166 +2,163 @@ #ifndef PROJECT_CONFIG_MODELS_HPP #define PROJECT_CONFIG_MODELS_HPP +#include +#include #include #include #include -#include -#include "sdkconfig.h" -#include #include "esp_log.h" +#include "sdkconfig.h" struct BaseConfigModel { - BaseConfigModel(Preferences *pref) : pref(pref) {} + BaseConfigModel(Preferences* pref) : pref(pref) {} - void load(); - void save(); - std::string toRepresentation(); + void load(); + void save(); + std::string toRepresentation(); - Preferences *pref; + Preferences* pref; }; enum class StreamingMode { - SETUP, - UVC, - WIFI, + SETUP, + UVC, + WIFI, }; struct DeviceMode_t : BaseConfigModel { - StreamingMode mode; - explicit DeviceMode_t(Preferences *pref) : BaseConfigModel(pref), mode(StreamingMode::SETUP) {} + StreamingMode mode; + explicit DeviceMode_t(Preferences* pref) : BaseConfigModel(pref), mode(StreamingMode::SETUP) {} - void load() - { - // Default mode can be controlled via sdkconfig: - // - If CONFIG_START_IN_UVC_MODE is enabled, default to UVC - // - Otherwise default to SETUP - int default_mode = + void load() + { + // Default mode can be controlled via sdkconfig: + // - If CONFIG_START_IN_UVC_MODE is enabled, default to UVC + // - Otherwise default to SETUP + int default_mode = #if CONFIG_START_IN_UVC_MODE - static_cast(StreamingMode::UVC); + static_cast(StreamingMode::UVC); #else - static_cast(StreamingMode::SETUP); + static_cast(StreamingMode::SETUP); #endif - int stored_mode = this->pref->getInt("mode", default_mode); - this->mode = static_cast(stored_mode); - ESP_LOGI("DeviceMode", "Loaded device mode: %d", stored_mode); - } + int stored_mode = this->pref->getInt("mode", default_mode); + this->mode = static_cast(stored_mode); + ESP_LOGI("DeviceMode", "Loaded device mode: %d", stored_mode); + } - void save() const - { - this->pref->putInt("mode", static_cast(this->mode)); - ESP_LOGI("DeviceMode", "Saved device mode: %d", static_cast(this->mode)); - } + void save() const + { + this->pref->putInt("mode", static_cast(this->mode)); + ESP_LOGI("DeviceMode", "Saved device mode: %d", static_cast(this->mode)); + } }; struct DeviceConfig_t : BaseConfigModel { - DeviceConfig_t(Preferences *pref) : BaseConfigModel(pref) {} + DeviceConfig_t(Preferences* pref) : BaseConfigModel(pref) {} - std::string OTALogin; - std::string OTAPassword; - int led_external_pwm_duty_cycle; - int OTAPort; + std::string OTALogin; + std::string OTAPassword; + int led_external_pwm_duty_cycle; + int OTAPort; - void load() - { - this->OTALogin = this->pref->getString("OTALogin", "openiris"); - this->OTAPassword = this->pref->getString("OTAPassword", "openiris"); - this->OTAPort = this->pref->getInt("OTAPort", 3232); + void load() + { + this->OTALogin = this->pref->getString("OTALogin", "openiris"); + this->OTAPassword = this->pref->getString("OTAPassword", "openiris"); + this->OTAPort = this->pref->getInt("OTAPort", 3232); #if CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE - this->led_external_pwm_duty_cycle = this->pref->getInt("led_ext_pwm", CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE); + this->led_external_pwm_duty_cycle = this->pref->getInt("led_ext_pwm", CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE); #else - this->led_external_pwm_duty_cycle = this->pref->getInt("led_ext_pwm", 100); + this->led_external_pwm_duty_cycle = this->pref->getInt("led_ext_pwm", 100); #endif - }; + }; - void save() const - { - this->pref->putString("OTALogin", this->OTALogin.c_str()); - this->pref->putString("OTAPassword", this->OTAPassword.c_str()); - this->pref->putInt("OTAPort", this->OTAPort); - this->pref->putInt("led_ext_pwm", this->led_external_pwm_duty_cycle); - }; + void save() const + { + this->pref->putString("OTALogin", this->OTALogin.c_str()); + this->pref->putString("OTAPassword", this->OTAPassword.c_str()); + this->pref->putInt("OTAPort", this->OTAPort); + this->pref->putInt("led_ext_pwm", this->led_external_pwm_duty_cycle); + }; - std::string toRepresentation() const - { - return Helpers::format_string( - "\"device_config\": {\"OTALogin\": \"%s\", \"OTAPassword\": \"%s\", " - "\"OTAPort\": %u, \"led_external_pwm_duty_cycle\": %u}", - this->OTALogin.c_str(), this->OTAPassword.c_str(), this->OTAPort, this->led_external_pwm_duty_cycle); - }; + std::string toRepresentation() const + { + return Helpers::format_string( + "\"device_config\": {\"OTALogin\": \"%s\", \"OTAPassword\": \"%s\", " + "\"OTAPort\": %u, \"led_external_pwm_duty_cycle\": %u}", + this->OTALogin.c_str(), this->OTAPassword.c_str(), this->OTAPort, this->led_external_pwm_duty_cycle); + }; }; struct MDNSConfig_t : BaseConfigModel { - MDNSConfig_t(Preferences *pref) : BaseConfigModel(pref) {} + MDNSConfig_t(Preferences* pref) : BaseConfigModel(pref) {} - std::string hostname; + std::string hostname; - void load() - { - // Default hostname comes from GENERAL_ADVERTISED_NAME (unified advertised name) - std::string default_hostname = CONFIG_GENERAL_ADVERTISED_NAME; - if (default_hostname.empty()) + void load() { - default_hostname = "openiristracker"; - } + // Default hostname comes from GENERAL_ADVERTISED_NAME (unified advertised name) + std::string default_hostname = CONFIG_GENERAL_ADVERTISED_NAME; + if (default_hostname.empty()) + { + default_hostname = "openiristracker"; + } - this->hostname = this->pref->getString("hostname", default_hostname); - }; + this->hostname = this->pref->getString("hostname", default_hostname); + }; - void save() const - { - this->pref->putString("hostname", this->hostname.c_str()); - }; + void save() const + { + this->pref->putString("hostname", this->hostname.c_str()); + }; - std::string toRepresentation() - { - return Helpers::format_string( - "\"mdns_config\": {\"hostname\": \"%s\"}", - this->hostname.c_str()); - }; + std::string toRepresentation() + { + return Helpers::format_string("\"mdns_config\": {\"hostname\": \"%s\"}", this->hostname.c_str()); + }; }; struct CameraConfig_t : BaseConfigModel { - CameraConfig_t(Preferences *pref) : BaseConfigModel(pref) {} + CameraConfig_t(Preferences* pref) : BaseConfigModel(pref) {} - uint8_t vflip; - uint8_t href; - uint8_t framesize; - uint8_t quality; - uint8_t brightness; + uint8_t vflip; + uint8_t href; + uint8_t framesize; + uint8_t quality; + uint8_t brightness; - void load() - { - this->vflip = this->pref->getInt("vflip", 0); - this->href = this->pref->getInt("href", 0); - this->framesize = this->pref->getInt("framesize", 5); - this->quality = this->pref->getInt("quality", 7); - this->brightness = this->pref->getInt("brightness", 2); - }; + void load() + { + this->vflip = this->pref->getInt("vflip", 0); + this->href = this->pref->getInt("href", 0); + this->framesize = this->pref->getInt("framesize", 5); + this->quality = this->pref->getInt("quality", 7); + this->brightness = this->pref->getInt("brightness", 2); + }; - void save() const - { - this->pref->putInt("vflip", this->vflip); - this->pref->putInt("href", this->href); - this->pref->putInt("framesize", this->framesize); - this->pref->putInt("quality", this->quality); - this->pref->putInt("brightness", this->brightness); - }; + void save() const + { + this->pref->putInt("vflip", this->vflip); + this->pref->putInt("href", this->href); + this->pref->putInt("framesize", this->framesize); + this->pref->putInt("quality", this->quality); + this->pref->putInt("brightness", this->brightness); + }; - std::string toRepresentation() - { - return Helpers::format_string( - "\"camera_config\": {\"vflip\": %d,\"framesize\": %d,\"href\": " - "%d,\"quality\": %d,\"brightness\": %d}", - this->vflip, this->framesize, this->href, this->quality, - this->brightness); - }; + std::string toRepresentation() + { + return Helpers::format_string( + "\"camera_config\": {\"vflip\": %d,\"framesize\": %d,\"href\": " + "%d,\"quality\": %d,\"brightness\": %d}", + this->vflip, this->framesize, this->href, this->quality, this->brightness); + }; }; // with wifi, we have to work a bit differently @@ -170,177 +167,154 @@ struct CameraConfig_t : BaseConfigModel // save them under an indexed name and load them as such. struct WiFiConfig_t : BaseConfigModel { - // default constructor used for loading - WiFiConfig_t(Preferences *pref) : BaseConfigModel(pref) {} + // default constructor used for loading + WiFiConfig_t(Preferences* pref) : BaseConfigModel(pref) {} - WiFiConfig_t( - Preferences *pref, - const uint8_t index, - std::string name, - std::string ssid, - std::string password, - const uint8_t channel, - const uint8_t power) - : BaseConfigModel(pref), - index(index), - name(std::move(name)), - ssid(std::move(ssid)), - password(std::move(password)), - channel(channel), - power(power) {} + WiFiConfig_t(Preferences* pref, const uint8_t index, std::string name, std::string ssid, std::string password, const uint8_t channel, const uint8_t power) + : BaseConfigModel(pref), index(index), name(std::move(name)), ssid(std::move(ssid)), password(std::move(password)), channel(channel), power(power) + { + } - uint8_t index; - std::string name; - std::string ssid; - std::string password; - uint8_t channel; - uint8_t power; + uint8_t index; + std::string name; + std::string ssid; + std::string password; + uint8_t channel; + uint8_t power; - void load(const uint8_t index) - { - this->index = index; - char buffer[2]; + void load(const uint8_t index) + { + this->index = index; + char buffer[2]; - auto const iter_str = std::string(Helpers::itoa(index, buffer, 10)); - this->name = this->pref->getString(("name" + iter_str).c_str(), ""); - this->ssid = this->pref->getString(("ssid" + iter_str).c_str(), ""); - this->password = this->pref->getString(("password" + iter_str).c_str(), ""); - this->channel = this->pref->getUInt(("channel" + iter_str).c_str()); - this->power = this->pref->getUInt(("power" + iter_str).c_str()); + auto const iter_str = std::string(Helpers::itoa(index, buffer, 10)); + this->name = this->pref->getString(("name" + iter_str).c_str(), ""); + this->ssid = this->pref->getString(("ssid" + iter_str).c_str(), ""); + this->password = this->pref->getString(("password" + iter_str).c_str(), ""); + this->channel = this->pref->getUInt(("channel" + iter_str).c_str()); + this->power = this->pref->getUInt(("power" + iter_str).c_str()); - ESP_LOGI("WiFiConfig", "Loaded network %d: name=%s, ssid=%s, channel=%d", - index, this->name.c_str(), this->ssid.c_str(), this->channel); - }; + ESP_LOGI("WiFiConfig", "Loaded network %d: name=%s, ssid=%s, channel=%d", index, this->name.c_str(), this->ssid.c_str(), this->channel); + }; - void save() const - { - char buffer[2]; - auto const iter_str = std::string(Helpers::itoa(this->index, buffer, 10)); + void save() const + { + char buffer[2]; + auto const iter_str = std::string(Helpers::itoa(this->index, buffer, 10)); - this->pref->putString(("name" + iter_str).c_str(), this->name.c_str()); - this->pref->putString(("ssid" + iter_str).c_str(), this->ssid.c_str()); - this->pref->putString(("password" + iter_str).c_str(), this->password.c_str()); - this->pref->putUInt(("channel" + iter_str).c_str(), this->channel); - this->pref->putUInt(("power" + iter_str).c_str(), this->power); + this->pref->putString(("name" + iter_str).c_str(), this->name.c_str()); + this->pref->putString(("ssid" + iter_str).c_str(), this->ssid.c_str()); + this->pref->putString(("password" + iter_str).c_str(), this->password.c_str()); + this->pref->putUInt(("channel" + iter_str).c_str(), this->channel); + this->pref->putUInt(("power" + iter_str).c_str(), this->power); - ESP_LOGI("WiFiConfig", "Saved network %d: name=%s, ssid=%s, channel=%d", - this->index, this->name.c_str(), this->ssid.c_str(), this->channel); - }; + ESP_LOGI("WiFiConfig", "Saved network %d: name=%s, ssid=%s, channel=%d", this->index, this->name.c_str(), this->ssid.c_str(), this->channel); + }; - std::string toRepresentation() - { - return Helpers::format_string( - "{\"name\": \"%s\", \"ssid\": \"%s\", \"password\": \"%s\", \"channel\": %u, \"power\": %u}", - this->name.c_str(), this->ssid.c_str(), this->password.c_str(), - this->channel, this->power); - }; + std::string toRepresentation() + { + return Helpers::format_string("{\"name\": \"%s\", \"ssid\": \"%s\", \"password\": \"%s\", \"channel\": %u, \"power\": %u}", this->name.c_str(), + this->ssid.c_str(), this->password.c_str(), this->channel, this->power); + }; }; struct AP_WiFiConfig_t : BaseConfigModel { - AP_WiFiConfig_t(Preferences *pref) : BaseConfigModel(pref) {} + AP_WiFiConfig_t(Preferences* pref) : BaseConfigModel(pref) {} - std::string ssid; - std::string password; - uint8_t channel; + std::string ssid; + std::string password; + uint8_t channel; - void load() - { - this->ssid = this->pref->getString("apSSID", CONFIG_WIFI_AP_SSID); - this->password = this->pref->getString("apPassword", CONFIG_WIFI_AP_PASSWORD); - }; + void load() + { + this->ssid = this->pref->getString("apSSID", CONFIG_WIFI_AP_SSID); + this->password = this->pref->getString("apPassword", CONFIG_WIFI_AP_PASSWORD); + }; - void save() const - { - this->pref->putString("apSSID", this->ssid.c_str()); - this->pref->putString("apPass", this->password.c_str()); - this->pref->putUInt("apChannel", this->channel); - }; + void save() const + { + this->pref->putString("apSSID", this->ssid.c_str()); + this->pref->putString("apPass", this->password.c_str()); + this->pref->putUInt("apChannel", this->channel); + }; - std::string toRepresentation() - { - return Helpers::format_string( - "\"ap_wifi_config\": {\"ssid\": \"%s\", \"password\": \"%s\", " - "\"channel\": %u}", - this->ssid.c_str(), this->password.c_str(), this->channel); - }; + std::string toRepresentation() + { + return Helpers::format_string( + "\"ap_wifi_config\": {\"ssid\": \"%s\", \"password\": \"%s\", " + "\"channel\": %u}", + this->ssid.c_str(), this->password.c_str(), this->channel); + }; }; struct WiFiTxPower_t : BaseConfigModel { - WiFiTxPower_t(Preferences *pref) : BaseConfigModel(pref) {} + WiFiTxPower_t(Preferences* pref) : BaseConfigModel(pref) {} - uint8_t power; + uint8_t power; - void load() - { - this->power = this->pref->getUInt("txpower", 52); - }; + void load() + { + this->power = this->pref->getUInt("txpower", 52); + }; - void save() const - { - this->pref->putUInt("txpower", this->power); - }; + void save() const + { + this->pref->putUInt("txpower", this->power); + }; - std::string toRepresentation() - { - return Helpers::format_string("\"wifi_tx_power\": {\"power\": %u}", this->power); - }; + std::string toRepresentation() + { + return Helpers::format_string("\"wifi_tx_power\": {\"power\": %u}", this->power); + }; }; class TrackerConfig_t { -public: - DeviceConfig_t device; - DeviceMode_t device_mode; - CameraConfig_t camera; - std::vector networks; - AP_WiFiConfig_t ap_network; - MDNSConfig_t mdns; - WiFiTxPower_t txpower; + public: + DeviceConfig_t device; + DeviceMode_t device_mode; + CameraConfig_t camera; + std::vector networks; + AP_WiFiConfig_t ap_network; + MDNSConfig_t mdns; + WiFiTxPower_t txpower; - TrackerConfig_t( - DeviceConfig_t device, - DeviceMode_t device_mode, - CameraConfig_t camera, - std::vector networks, - AP_WiFiConfig_t ap_network, - MDNSConfig_t mdns, - WiFiTxPower_t txpower) : device(std::move(device)), - device_mode(std::move(device_mode)), - camera(std::move(camera)), - networks(std::move(networks)), - ap_network(std::move(ap_network)), - mdns(std::move(mdns)), - txpower(std::move(txpower)) {} - - std::string toRepresentation() - { - std::string WifiConfigRepresentation; - - // we need a valid json representation, so we can't have a dangling comma at the end - if (!this->networks.empty()) + TrackerConfig_t(DeviceConfig_t device, DeviceMode_t device_mode, CameraConfig_t camera, std::vector networks, AP_WiFiConfig_t ap_network, + MDNSConfig_t mdns, WiFiTxPower_t txpower) + : device(std::move(device)), + device_mode(std::move(device_mode)), + camera(std::move(camera)), + networks(std::move(networks)), + ap_network(std::move(ap_network)), + mdns(std::move(mdns)), + txpower(std::move(txpower)) { - if (this->networks.size() > 1) - { - for (auto i = 0; i < this->networks.size() - 1; i++) - { - WifiConfigRepresentation += Helpers::format_string("%s, ", this->networks[i].toRepresentation().c_str()); - } - } - - WifiConfigRepresentation += Helpers::format_string("%s", this->networks[networks.size() - 1].toRepresentation().c_str()); } - return Helpers::format_string( - "{%s, %s, %s, \"networks\": [%s], %s, %s}", - this->device.toRepresentation().c_str(), - this->mdns.toRepresentation().c_str(), - this->camera.toRepresentation().c_str(), - WifiConfigRepresentation.c_str(), - this->ap_network.toRepresentation().c_str(), - this->txpower.toRepresentation().c_str()); - } + std::string toRepresentation() + { + std::string WifiConfigRepresentation; + + // we need a valid json representation, so we can't have a dangling comma at the end + if (!this->networks.empty()) + { + if (this->networks.size() > 1) + { + for (auto i = 0; i < this->networks.size() - 1; i++) + { + WifiConfigRepresentation += Helpers::format_string("%s, ", this->networks[i].toRepresentation().c_str()); + } + } + + WifiConfigRepresentation += Helpers::format_string("%s", this->networks[networks.size() - 1].toRepresentation().c_str()); + } + + return Helpers::format_string("{%s, %s, %s, \"networks\": [%s], %s, %s}", this->device.toRepresentation().c_str(), + this->mdns.toRepresentation().c_str(), this->camera.toRepresentation().c_str(), WifiConfigRepresentation.c_str(), + this->ap_network.toRepresentation().c_str(), this->txpower.toRepresentation().c_str()); + } }; #endif \ No newline at end of file diff --git a/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp b/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp index 04f12e5..5e030ed 100644 --- a/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp +++ b/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp @@ -2,90 +2,88 @@ static auto CONFIGURATION_TAG = "[CONFIGURATION]"; -int getNetworkCount(Preferences *pref) +int getNetworkCount(Preferences* pref) { - return pref->getInt("networkcount", 0); + return pref->getInt("networkcount", 0); } -void saveNetworkCount(Preferences *pref, const int count) +void saveNetworkCount(Preferences* pref, const int count) { - pref->putInt("networkcount", count); + pref->putInt("networkcount", count); } -ProjectConfig::ProjectConfig(Preferences *pref) : pref(pref), - _already_loaded(false), - config(DeviceConfig_t(pref), - DeviceMode_t(pref), - CameraConfig_t(pref), - std::vector{}, - AP_WiFiConfig_t(pref), - MDNSConfig_t(pref), - WiFiTxPower_t(pref)) {} +ProjectConfig::ProjectConfig(Preferences* pref) + : pref(pref), + _already_loaded(false), + config(DeviceConfig_t(pref), DeviceMode_t(pref), CameraConfig_t(pref), std::vector{}, AP_WiFiConfig_t(pref), MDNSConfig_t(pref), + WiFiTxPower_t(pref)) +{ +} ProjectConfig::~ProjectConfig() = default; void ProjectConfig::save() const { - ESP_LOGD(CONFIGURATION_TAG, "Saving project config"); - this->config.device.save(); - this->config.device_mode.save(); - this->config.camera.save(); - this->config.mdns.save(); - this->config.txpower.save(); - this->config.ap_network.save(); + ESP_LOGD(CONFIGURATION_TAG, "Saving project config"); + this->config.device.save(); + this->config.device_mode.save(); + this->config.camera.save(); + this->config.mdns.save(); + this->config.txpower.save(); + this->config.ap_network.save(); - auto const networks_count = static_cast(this->config.networks.size()); - for (int i = 0; i < networks_count; i++) - { - this->config.networks[i].save(); - } + auto const networks_count = static_cast(this->config.networks.size()); + for (int i = 0; i < networks_count; i++) + { + this->config.networks[i].save(); + } - saveNetworkCount(this->pref, networks_count); - this->pref->end(); // we call end() here to close the connection to the NVS partition, we - // only do this because we call ESP.restart() next. + saveNetworkCount(this->pref, networks_count); + this->pref->end(); // we call end() here to close the connection to the NVS partition, we + // only do this because we call ESP.restart() next. - // TODO add the restart task - // https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/freertos_idf.html - // OpenIrisTasks::ScheduleRestart(2000); + // TODO add the restart task + // https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/freertos_idf.html + // OpenIrisTasks::ScheduleRestart(2000); } void ProjectConfig::load() { - ESP_LOGD(CONFIGURATION_TAG, "Loading project config"); - if (this->_already_loaded) - { - ESP_LOGW(CONFIGURATION_TAG, "Project config already loaded"); - return; - } + ESP_LOGD(CONFIGURATION_TAG, "Loading project config"); + if (this->_already_loaded) + { + ESP_LOGW(CONFIGURATION_TAG, "Project config already loaded"); + return; + } - const bool success = this->pref->begin("openiris"); + const bool success = this->pref->begin("openiris"); - ESP_LOGI(CONFIGURATION_TAG, "Config name: openiris"); - ESP_LOGI(CONFIGURATION_TAG, "Config loaded: %s", success ? "true" : "false"); + ESP_LOGI(CONFIGURATION_TAG, "Config name: openiris"); + ESP_LOGI(CONFIGURATION_TAG, "Config loaded: %s", success ? "true" : "false"); - this->config.device.load(); - this->config.device_mode.load(); - this->config.camera.load(); - this->config.mdns.load(); - this->config.txpower.load(); - this->config.ap_network.load(); + this->config.device.load(); + this->config.device_mode.load(); + this->config.camera.load(); + this->config.mdns.load(); + this->config.txpower.load(); + this->config.ap_network.load(); - const auto networks_count = getNetworkCount(this->pref); - ESP_LOGD(CONFIGURATION_TAG, "Loading networks: %d", networks_count); - for (int i = 0; i < getNetworkCount(this->pref); i++) - { - auto networkConfig = WiFiConfig_t(this->pref); - networkConfig.load(i); - this->config.networks.push_back(networkConfig); - } + const auto networks_count = getNetworkCount(this->pref); + ESP_LOGD(CONFIGURATION_TAG, "Loading networks: %d", networks_count); + for (int i = 0; i < getNetworkCount(this->pref); i++) + { + auto networkConfig = WiFiConfig_t(this->pref); + networkConfig.load(i); + this->config.networks.push_back(networkConfig); + } - this->_already_loaded = true; + this->_already_loaded = true; } bool ProjectConfig::reset() { - ESP_LOGW(CONFIGURATION_TAG, "Resetting project config"); - return this->pref->clear(); + ESP_LOGW(CONFIGURATION_TAG, "Resetting project config"); + return this->pref->clear(); } //********************************************************************************************************************** @@ -93,148 +91,128 @@ bool ProjectConfig::reset() //! DeviceConfig //* //********************************************************************************************************************** -void ProjectConfig::setOTAConfig(const std::string &OTALogin, - const std::string &OTAPassword, - const int OTAPort) +void ProjectConfig::setOTAConfig(const std::string& OTALogin, const std::string& OTAPassword, const int OTAPort) { - ESP_LOGD(CONFIGURATION_TAG, "Updating device config"); - this->config.device.OTALogin.assign(OTALogin); - this->config.device.OTAPassword.assign(OTAPassword); - this->config.device.OTAPort = OTAPort; - this->config.device.save(); + ESP_LOGD(CONFIGURATION_TAG, "Updating device config"); + this->config.device.OTALogin.assign(OTALogin); + this->config.device.OTAPassword.assign(OTAPassword); + this->config.device.OTAPort = OTAPort; + this->config.device.save(); } void ProjectConfig::setLEDDUtyCycleConfig(int led_external_pwm_duty_cycle) { - this->config.device.led_external_pwm_duty_cycle = led_external_pwm_duty_cycle; - ESP_LOGI(CONFIGURATION_TAG, "Setting duty cycle to %d", led_external_pwm_duty_cycle); - this->config.device.save(); + this->config.device.led_external_pwm_duty_cycle = led_external_pwm_duty_cycle; + ESP_LOGI(CONFIGURATION_TAG, "Setting duty cycle to %d", led_external_pwm_duty_cycle); + this->config.device.save(); } -void ProjectConfig::setMDNSConfig(const std::string &hostname) +void ProjectConfig::setMDNSConfig(const std::string& hostname) { - ESP_LOGD(CONFIGURATION_TAG, "Updating MDNS config"); - this->config.mdns.hostname.assign(hostname); - this->config.mdns.save(); + ESP_LOGD(CONFIGURATION_TAG, "Updating MDNS config"); + this->config.mdns.hostname.assign(hostname); + this->config.mdns.save(); } -void ProjectConfig::setCameraConfig(const uint8_t vflip, - const uint8_t framesize, - const uint8_t href, - const uint8_t quality, - const uint8_t brightness) +void ProjectConfig::setCameraConfig(const uint8_t vflip, const uint8_t framesize, const uint8_t href, const uint8_t quality, const uint8_t brightness) { - ESP_LOGD(CONFIGURATION_TAG, "Updating camera config"); - this->config.camera.vflip = vflip; - this->config.camera.href = href; - this->config.camera.framesize = framesize; - this->config.camera.quality = quality; - this->config.camera.brightness = brightness; - this->config.camera.save(); + ESP_LOGD(CONFIGURATION_TAG, "Updating camera config"); + this->config.camera.vflip = vflip; + this->config.camera.href = href; + this->config.camera.framesize = framesize; + this->config.camera.quality = quality; + this->config.camera.brightness = brightness; + this->config.camera.save(); - ESP_LOGD(CONFIGURATION_TAG, "Updating Camera config"); + ESP_LOGD(CONFIGURATION_TAG, "Updating Camera config"); } -void ProjectConfig::setWifiConfig(const std::string &networkName, - const std::string &ssid, - const std::string &password, - uint8_t channel, - uint8_t power) +void ProjectConfig::setWifiConfig(const std::string& networkName, const std::string& ssid, const std::string& password, uint8_t channel, uint8_t power) { - const auto size = this->config.networks.size(); + const auto size = this->config.networks.size(); - const auto it = std::ranges::find_if(this->config.networks, - [&](const WiFiConfig_t &network) - { return network.name == networkName; }); + const auto it = std::ranges::find_if(this->config.networks, [&](const WiFiConfig_t& network) { return network.name == networkName; }); - if (it != this->config.networks.end()) - { + if (it != this->config.networks.end()) + { + ESP_LOGI(CONFIGURATION_TAG, "Found network %s, updating it ...", it->name.c_str()); - ESP_LOGI(CONFIGURATION_TAG, "Found network %s, updating it ...", - it->name.c_str()); + it->name = networkName; + it->ssid = ssid; + it->password = password; + it->channel = channel; + it->power = power; + // Save the updated network immediately + it->save(); + return; + } - it->name = networkName; - it->ssid = ssid; - it->password = password; - it->channel = channel; - it->power = power; - // Save the updated network immediately - it->save(); - return; - } + if (size == 0) + { + ESP_LOGI(CONFIGURATION_TAG, "No networks, We're adding a new network"); + this->config.networks.emplace_back(this->pref, static_cast(0), networkName, ssid, password, channel, power); + // Save the new network immediately + this->config.networks.back().save(); + saveNetworkCount(this->pref, 1); + return; + } - if (size == 0) - { - ESP_LOGI(CONFIGURATION_TAG, "No networks, We're adding a new network"); - this->config.networks.emplace_back(this->pref, static_cast(0), networkName, ssid, password, channel, - power); - // Save the new network immediately - this->config.networks.back().save(); - saveNetworkCount(this->pref, 1); - return; - } - - // we're allowing to store up to three additional networks - if (size < 3) - { - ESP_LOGI(CONFIGURATION_TAG, "We're adding a new network"); - // we don't have that network yet, we can add it as we still have some - // space we're using emplace_back as push_back will create a copy of it, - // we want to avoid that - uint8_t last_index = getNetworkCount(this->pref); - this->config.networks.emplace_back(this->pref, last_index, networkName, ssid, password, channel, - power); - // Save the new network immediately - this->config.networks.back().save(); - saveNetworkCount(this->pref, static_cast(this->config.networks.size())); - } - else - { - ESP_LOGE(CONFIGURATION_TAG, "No more space for additional networks"); - } + // we're allowing to store up to three additional networks + if (size < 3) + { + ESP_LOGI(CONFIGURATION_TAG, "We're adding a new network"); + // we don't have that network yet, we can add it as we still have some + // space we're using emplace_back as push_back will create a copy of it, + // we want to avoid that + uint8_t last_index = getNetworkCount(this->pref); + this->config.networks.emplace_back(this->pref, last_index, networkName, ssid, password, channel, power); + // Save the new network immediately + this->config.networks.back().save(); + saveNetworkCount(this->pref, static_cast(this->config.networks.size())); + } + else + { + ESP_LOGE(CONFIGURATION_TAG, "No more space for additional networks"); + } } -void ProjectConfig::deleteWifiConfig(const std::string &networkName) +void ProjectConfig::deleteWifiConfig(const std::string& networkName) { - if (const auto size = this->config.networks.size(); size == 0) - { - ESP_LOGI(CONFIGURATION_TAG, "No networks, nothing to delete"); - } + if (const auto size = this->config.networks.size(); size == 0) + { + ESP_LOGI(CONFIGURATION_TAG, "No networks, nothing to delete"); + } - const auto it = std::ranges::find_if(this->config.networks, - [&](const WiFiConfig_t &network) - { return network.name == networkName; }); + const auto it = std::ranges::find_if(this->config.networks, [&](const WiFiConfig_t& network) { return network.name == networkName; }); - if (it != this->config.networks.end()) - { - ESP_LOGI(CONFIGURATION_TAG, "Found network %s", it->name.c_str()); - this->config.networks.erase(it); - ESP_LOGI(CONFIGURATION_TAG, "Deleted network %s", networkName.c_str()); - } + if (it != this->config.networks.end()) + { + ESP_LOGI(CONFIGURATION_TAG, "Found network %s", it->name.c_str()); + this->config.networks.erase(it); + ESP_LOGI(CONFIGURATION_TAG, "Deleted network %s", networkName.c_str()); + } } void ProjectConfig::setWiFiTxPower(uint8_t power) { - this->config.txpower.power = power; - this->config.txpower.save(); - ESP_LOGD(CONFIGURATION_TAG, "Updating wifi tx power"); + this->config.txpower.power = power; + this->config.txpower.save(); + ESP_LOGD(CONFIGURATION_TAG, "Updating wifi tx power"); } -void ProjectConfig::setAPWifiConfig(const std::string &ssid, - const std::string &password, - const uint8_t channel) +void ProjectConfig::setAPWifiConfig(const std::string& ssid, const std::string& password, const uint8_t channel) { - this->config.ap_network.ssid.assign(ssid); - this->config.ap_network.password.assign(password); - this->config.ap_network.channel = channel; - this->config.ap_network.save(); - ESP_LOGD(CONFIGURATION_TAG, "Updating access point config"); + this->config.ap_network.ssid.assign(ssid); + this->config.ap_network.password.assign(password); + this->config.ap_network.channel = channel; + this->config.ap_network.save(); + ESP_LOGD(CONFIGURATION_TAG, "Updating access point config"); } void ProjectConfig::setDeviceMode(const StreamingMode deviceMode) { - this->config.device_mode.mode = deviceMode; - this->config.device_mode.save(); // Save immediately + this->config.device_mode.mode = deviceMode; + this->config.device_mode.save(); // Save immediately } //********************************************************************************************************************** @@ -243,41 +221,41 @@ void ProjectConfig::setDeviceMode(const StreamingMode deviceMode) //* //********************************************************************************************************************** -DeviceConfig_t &ProjectConfig::getDeviceConfig() +DeviceConfig_t& ProjectConfig::getDeviceConfig() { - return this->config.device; + return this->config.device; } -CameraConfig_t &ProjectConfig::getCameraConfig() +CameraConfig_t& ProjectConfig::getCameraConfig() { - return this->config.camera; + return this->config.camera; } -std::vector &ProjectConfig::getWifiConfigs() +std::vector& ProjectConfig::getWifiConfigs() { - return this->config.networks; + return this->config.networks; } -AP_WiFiConfig_t &ProjectConfig::getAPWifiConfig() +AP_WiFiConfig_t& ProjectConfig::getAPWifiConfig() { - return this->config.ap_network; + return this->config.ap_network; } -MDNSConfig_t &ProjectConfig::getMDNSConfig() +MDNSConfig_t& ProjectConfig::getMDNSConfig() { - return this->config.mdns; + return this->config.mdns; } -WiFiTxPower_t &ProjectConfig::getWiFiTxPowerConfig() +WiFiTxPower_t& ProjectConfig::getWiFiTxPowerConfig() { - return this->config.txpower; + return this->config.txpower; } -TrackerConfig_t &ProjectConfig::getTrackerConfig() +TrackerConfig_t& ProjectConfig::getTrackerConfig() { - return this->config; + return this->config; } -DeviceMode_t &ProjectConfig::getDeviceModeConfig() +DeviceMode_t& ProjectConfig::getDeviceModeConfig() { - return this->config.device_mode; + return this->config.device_mode; } StreamingMode ProjectConfig::getDeviceMode() { - return this->config.device_mode.mode; + return this->config.device_mode.mode; } \ No newline at end of file diff --git a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp index 07d04da..af83ac6 100644 --- a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp +++ b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp @@ -1,67 +1,55 @@ #pragma once #ifndef PROJECT_CONFIG_HPP #define PROJECT_CONFIG_HPP -#include "esp_log.h" -#include -#include -#include -#include -#include "Models.hpp" #include +#include +#include +#include +#include +#include "Models.hpp" +#include "esp_log.h" -int getNetworkCount(Preferences *pref); +int getNetworkCount(Preferences* pref); -void saveNetworkCount(Preferences *pref, int count); +void saveNetworkCount(Preferences* pref, int count); class ProjectConfig { -public: - explicit ProjectConfig(Preferences *pref); - virtual ~ProjectConfig(); + public: + explicit ProjectConfig(Preferences* pref); + virtual ~ProjectConfig(); - void load(); - void save() const; + void load(); + void save() const; - bool reset(); + bool reset(); - DeviceConfig_t &getDeviceConfig(); - DeviceMode_t &getDeviceModeConfig(); - CameraConfig_t &getCameraConfig(); - std::vector &getWifiConfigs(); - AP_WiFiConfig_t &getAPWifiConfig(); - MDNSConfig_t &getMDNSConfig(); - WiFiTxPower_t &getWiFiTxPowerConfig(); - TrackerConfig_t &getTrackerConfig(); + DeviceConfig_t& getDeviceConfig(); + DeviceMode_t& getDeviceModeConfig(); + CameraConfig_t& getCameraConfig(); + std::vector& getWifiConfigs(); + AP_WiFiConfig_t& getAPWifiConfig(); + MDNSConfig_t& getMDNSConfig(); + WiFiTxPower_t& getWiFiTxPowerConfig(); + TrackerConfig_t& getTrackerConfig(); - void setOTAConfig(const std::string &OTALogin, - const std::string &OTAPassword, - int OTAPort); - void setLEDDUtyCycleConfig(int led_external_pwm_duty_cycle); - void setMDNSConfig(const std::string &hostname); - void setCameraConfig(uint8_t vflip, - uint8_t framesize, - uint8_t href, - uint8_t quality, - uint8_t brightness); - void setWifiConfig(const std::string &networkName, - const std::string &ssid, - const std::string &password, - uint8_t channel, - uint8_t power); + void setOTAConfig(const std::string& OTALogin, const std::string& OTAPassword, int OTAPort); + void setLEDDUtyCycleConfig(int led_external_pwm_duty_cycle); + void setMDNSConfig(const std::string& hostname); + void setCameraConfig(uint8_t vflip, uint8_t framesize, uint8_t href, uint8_t quality, uint8_t brightness); + void setWifiConfig(const std::string& networkName, const std::string& ssid, const std::string& password, uint8_t channel, uint8_t power); - void deleteWifiConfig(const std::string &networkName); + void deleteWifiConfig(const std::string& networkName); - void setAPWifiConfig(const std::string &ssid, - const std::string &password, - uint8_t channel); - void setWiFiTxPower(uint8_t power); - void setDeviceMode(StreamingMode deviceMode); - StreamingMode getDeviceMode(); + void setAPWifiConfig(const std::string& ssid, const std::string& password, uint8_t channel); + void setWiFiTxPower(uint8_t power); + void setDeviceMode(StreamingMode deviceMode); + StreamingMode getDeviceMode(); -private: - Preferences *pref; - bool _already_loaded; - TrackerConfig_t config; + private: + Preferences* pref; + bool _already_loaded; + TrackerConfig_t config; }; #endif \ No newline at end of file diff --git a/components/RestAPI/RestAPI/RestAPI.cpp b/components/RestAPI/RestAPI/RestAPI.cpp index e1655f2..992a762 100644 --- a/components/RestAPI/RestAPI/RestAPI.cpp +++ b/components/RestAPI/RestAPI/RestAPI.cpp @@ -7,140 +7,136 @@ #define GET_METHOD "GET" #define DELETE_METHOD "DELETE" -bool getIsSuccess(const nlohmann::json &response) +bool getIsSuccess(const nlohmann::json& response) { - // since the commandManager will be returning CommandManagerResponse to simplify parsing on the clients end - // we can slightly its json representation, and extract the status from there - // note: This will only work for commands executed with CommandManager::executeFromType(). - if (!response.contains("result")) - { - return false; - } + // since the commandManager will be returning CommandManagerResponse to simplify parsing on the clients end + // we can slightly its json representation, and extract the status from there + // note: This will only work for commands executed with CommandManager::executeFromType(). + if (!response.contains("result")) + { + return false; + } - return response.at("result").at("status").get() == "success"; + return response.at("result").at("status").get() == "success"; } RestAPI::RestAPI(std::string url, std::shared_ptr commandManager) : command_manager(commandManager) { - // until we stumble on a simpler way to handle the commands over the rest api - // the formula will be like this: - // each command gets its own endpoint - // each endpoint must include the action it performs in its path - // for example - // /get/ for getters - // /set/ for posts - // /delete/ for deletes - // /update/ for updates - // additional actions on the resource should be appended after the resource name - // like for example /api/set/config/save/ - // - // one endpoint must not contain more than one action + // until we stumble on a simpler way to handle the commands over the rest api + // the formula will be like this: + // each command gets its own endpoint + // each endpoint must include the action it performs in its path + // for example + // /get/ for getters + // /set/ for posts + // /delete/ for deletes + // /update/ for updates + // additional actions on the resource should be appended after the resource name + // like for example /api/set/config/save/ + // + // one endpoint must not contain more than one action - this->url = std::move(url); - // updates via PATCH - routes.emplace("/api/update/wifi/", RequestBaseData(PATCH_METHOD, CommandType::UPDATE_WIFI, 200, 400)); - routes.emplace("/api/update/device/mode/", RequestBaseData(PATCH_METHOD, CommandType::SWITCH_MODE, 200, 400)); - routes.emplace("/api/update/camera/", RequestBaseData(PATCH_METHOD, CommandType::UPDATE_CAMERA, 200, 400)); - routes.emplace("/api/update/ota/credentials", RequestBaseData(PATCH_METHOD, CommandType::UPDATE_OTA_CREDENTIALS, 200, 400)); - routes.emplace("/api/update/ap/", RequestBaseData(PATCH_METHOD, CommandType::UPDATE_AP_WIFI, 200, 400)); - routes.emplace("/api/update/led_duty_cycle/", RequestBaseData(PATCH_METHOD, CommandType::SET_LED_DUTY_CYCLE, 200, 400)); + this->url = std::move(url); + // updates via PATCH + routes.emplace("/api/update/wifi/", RequestBaseData(PATCH_METHOD, CommandType::UPDATE_WIFI, 200, 400)); + routes.emplace("/api/update/device/mode/", RequestBaseData(PATCH_METHOD, CommandType::SWITCH_MODE, 200, 400)); + routes.emplace("/api/update/camera/", RequestBaseData(PATCH_METHOD, CommandType::UPDATE_CAMERA, 200, 400)); + routes.emplace("/api/update/ota/credentials", RequestBaseData(PATCH_METHOD, CommandType::UPDATE_OTA_CREDENTIALS, 200, 400)); + routes.emplace("/api/update/ap/", RequestBaseData(PATCH_METHOD, CommandType::UPDATE_AP_WIFI, 200, 400)); + routes.emplace("/api/update/led_duty_cycle/", RequestBaseData(PATCH_METHOD, CommandType::SET_LED_DUTY_CYCLE, 200, 400)); - // POST will set the data - routes.emplace("/api/set/pause/", RequestBaseData(POST_METHOD, CommandType::PAUSE, 200, 400)); - routes.emplace("/api/set/wifi/", RequestBaseData(POST_METHOD, CommandType::SET_WIFI, 200, 400)); - routes.emplace("/api/set/mdns/", RequestBaseData(POST_METHOD, CommandType::SET_MDNS, 200, 400)); - routes.emplace("/api/set/config/save/", RequestBaseData(POST_METHOD, CommandType::SAVE_CONFIG, 200, 400)); - routes.emplace("/api/set/wifi/connect/", RequestBaseData(POST_METHOD, CommandType::CONNECT_WIFI, 200, 400)); + // POST will set the data + routes.emplace("/api/set/pause/", RequestBaseData(POST_METHOD, CommandType::PAUSE, 200, 400)); + routes.emplace("/api/set/wifi/", RequestBaseData(POST_METHOD, CommandType::SET_WIFI, 200, 400)); + routes.emplace("/api/set/mdns/", RequestBaseData(POST_METHOD, CommandType::SET_MDNS, 200, 400)); + routes.emplace("/api/set/config/save/", RequestBaseData(POST_METHOD, CommandType::SAVE_CONFIG, 200, 400)); + routes.emplace("/api/set/wifi/connect/", RequestBaseData(POST_METHOD, CommandType::CONNECT_WIFI, 200, 400)); - // resets via POST as well - routes.emplace("/api/reset/config/", RequestBaseData(POST_METHOD, CommandType::RESET_CONFIG, 200, 400)); + // resets via POST as well + routes.emplace("/api/reset/config/", RequestBaseData(POST_METHOD, CommandType::RESET_CONFIG, 200, 400)); - // gets via GET - routes.emplace("/api/get/config/", RequestBaseData(GET_METHOD, CommandType::GET_CONFIG, 200, 400)); - routes.emplace("/api/get/mdns/", RequestBaseData(GET_METHOD, CommandType::GET_MDNS_NAME, 200, 400)); - routes.emplace("/api/get/led_duty_cycle/", RequestBaseData(GET_METHOD, CommandType::GET_LED_DUTY_CYCLE, 200, 400)); - routes.emplace("/api/get/serial_number/", RequestBaseData(GET_METHOD, CommandType::GET_SERIAL, 200, 400)); - routes.emplace("/api/get/led_current/", RequestBaseData(GET_METHOD, CommandType::GET_LED_CURRENT, 200, 400)); - routes.emplace("/api/get/who_am_i/", RequestBaseData(GET_METHOD, CommandType::GET_WHO_AM_I, 200, 400)); + // gets via GET + routes.emplace("/api/get/config/", RequestBaseData(GET_METHOD, CommandType::GET_CONFIG, 200, 400)); + routes.emplace("/api/get/mdns/", RequestBaseData(GET_METHOD, CommandType::GET_MDNS_NAME, 200, 400)); + routes.emplace("/api/get/led_duty_cycle/", RequestBaseData(GET_METHOD, CommandType::GET_LED_DUTY_CYCLE, 200, 400)); + routes.emplace("/api/get/serial_number/", RequestBaseData(GET_METHOD, CommandType::GET_SERIAL, 200, 400)); + routes.emplace("/api/get/led_current/", RequestBaseData(GET_METHOD, CommandType::GET_LED_CURRENT, 200, 400)); + routes.emplace("/api/get/who_am_i/", RequestBaseData(GET_METHOD, CommandType::GET_WHO_AM_I, 200, 400)); - // deletes via DELETE - routes.emplace("/api/delete/wifi", RequestBaseData(DELETE_METHOD, CommandType::DELETE_NETWORK, 200, 400)); + // deletes via DELETE + routes.emplace("/api/delete/wifi", RequestBaseData(DELETE_METHOD, CommandType::DELETE_NETWORK, 200, 400)); - // reboots via POST - routes.emplace("/api/reboot/device/", RequestBaseData(GET_METHOD, CommandType::RESTART_DEVICE, 200, 500)); + // reboots via POST + routes.emplace("/api/reboot/device/", RequestBaseData(GET_METHOD, CommandType::RESTART_DEVICE, 200, 500)); - // heartbeat via GET - routes.emplace("/api/ping/", RequestBaseData(GET_METHOD, CommandType::PING, 200, 400)); + // heartbeat via GET + routes.emplace("/api/ping/", RequestBaseData(GET_METHOD, CommandType::PING, 200, 400)); } void RestAPI::begin() { - mg_log_set(MG_LL_DEBUG); - mg_mgr_init(&mgr); - // every route is handled through this class, with commands themselves by a command manager - // hence we pass a pointer to this in mg_http_listen - mg_http_listen(&mgr, this->url.c_str(), (mg_event_handler_t)RestAPIHelpers::event_handler, this); + mg_log_set(MG_LL_DEBUG); + mg_mgr_init(&mgr); + // every route is handled through this class, with commands themselves by a command manager + // hence we pass a pointer to this in mg_http_listen + mg_http_listen(&mgr, this->url.c_str(), (mg_event_handler_t)RestAPIHelpers::event_handler, this); } -void RestAPI::handle_request(struct mg_connection *connection, int event, void *event_data) +void RestAPI::handle_request(struct mg_connection* connection, int event, void* event_data) { - if (event == MG_EV_HTTP_MSG) - { - auto const *message = static_cast(event_data); - auto const uri = std::string(message->uri.buf, message->uri.len); - - if (this->routes.find(uri) == this->routes.end()) + if (event == MG_EV_HTTP_MSG) { - mg_http_reply(connection, 404, "", "Wrong URL"); - return; + auto const* message = static_cast(event_data); + auto const uri = std::string(message->uri.buf, message->uri.len); + + if (this->routes.find(uri) == this->routes.end()) + { + mg_http_reply(connection, 404, "", "Wrong URL"); + return; + } + + auto const base_request_params = this->routes.at(uri); + + auto* context = new RequestContext{ + .connection = connection, + .method = std::string(message->method.buf, message->method.len), + .body = std::string(message->body.buf, message->body.len), + }; + this->handle_endpoint_command(context, base_request_params.allowed_method, base_request_params.command_type, base_request_params.success_code, + base_request_params.error_code); } - - auto const base_request_params = this->routes.at(uri); - - auto *context = new RequestContext{ - .connection = connection, - .method = std::string(message->method.buf, message->method.len), - .body = std::string(message->body.buf, message->body.len), - }; - this->handle_endpoint_command(context, - base_request_params.allowed_method, - base_request_params.command_type, - base_request_params.success_code, - base_request_params.error_code); - } } -void RestAPIHelpers::event_handler(struct mg_connection *connection, int event, void *event_data) +void RestAPIHelpers::event_handler(struct mg_connection* connection, int event, void* event_data) { - auto *rest_api_handler = static_cast(connection->fn_data); - rest_api_handler->handle_request(connection, event, event_data); + auto* rest_api_handler = static_cast(connection->fn_data); + rest_api_handler->handle_request(connection, event, event_data); } void RestAPI::poll() { - mg_mgr_poll(&mgr, 100); + mg_mgr_poll(&mgr, 100); } -void HandleRestAPIPollTask(void *pvParameter) +void HandleRestAPIPollTask(void* pvParameter) { - auto *rest_api_handler = static_cast(pvParameter); - while (true) - { - rest_api_handler->poll(); - vTaskDelay(1000); - } + auto* rest_api_handler = static_cast(pvParameter); + while (true) + { + rest_api_handler->poll(); + vTaskDelay(1000); + } } -void RestAPI::handle_endpoint_command(RequestContext *context, std::string allowed_method, CommandType command_type, int success_code, int error_code) +void RestAPI::handle_endpoint_command(RequestContext* context, std::string allowed_method, CommandType command_type, int success_code, int error_code) { + if (context->method != allowed_method) + { + mg_http_reply(context->connection, 401, JSON_RESPONSE, "{%m:%m}", MG_ESC("error"), "Method not allowed"); + return; + } - if (context->method != allowed_method) - { - mg_http_reply(context->connection, 401, JSON_RESPONSE, "{%m:%m}", MG_ESC("error"), "Method not allowed"); - return; - } - - const nlohmann::json result = command_manager->executeFromType(command_type, context->body); - const auto code = getIsSuccess(result) ? success_code : error_code; - mg_http_reply(context->connection, code, JSON_RESPONSE, result.dump().c_str()); + const nlohmann::json result = command_manager->executeFromType(command_type, context->body); + const auto code = getIsSuccess(result) ? success_code : error_code; + mg_http_reply(context->connection, code, JSON_RESPONSE, result.dump().c_str()); } \ No newline at end of file diff --git a/components/RestAPI/RestAPI/RestAPI.hpp b/components/RestAPI/RestAPI/RestAPI.hpp index 0768b83..9ef93dd 100644 --- a/components/RestAPI/RestAPI/RestAPI.hpp +++ b/components/RestAPI/RestAPI/RestAPI.hpp @@ -1,11 +1,11 @@ #pragma once #ifndef RESTAPI_HPP #define RESTAPI_HPP -#include -#include -#include #include #include +#include +#include +#include #include "esp_log.h" @@ -13,45 +13,46 @@ struct RequestContext { - mg_connection *connection; - std::string method; - std::string body; + mg_connection* connection; + std::string method; + std::string body; }; struct RequestBaseData { - std::string allowed_method; - CommandType command_type; - int success_code; - int error_code; - RequestBaseData(std::string allowed_method, CommandType command_type, int success_code, int error_code) : allowed_method(allowed_method), command_type(command_type), success_code(success_code), error_code(error_code) {}; + std::string allowed_method; + CommandType command_type; + int success_code; + int error_code; + RequestBaseData(std::string allowed_method, CommandType command_type, int success_code, int error_code) + : allowed_method(allowed_method), command_type(command_type), success_code(success_code), error_code(error_code) {}; }; class RestAPI { - typedef std::unordered_map route_map; - std::string url; - route_map routes; + typedef std::unordered_map route_map; + std::string url; + route_map routes; - mg_mgr mgr; - std::shared_ptr command_manager; + mg_mgr mgr; + std::shared_ptr command_manager; -private: - void handle_endpoint_command(RequestContext *context, std::string allowed_method, CommandType command_type, int success_code, int error_code); + private: + void handle_endpoint_command(RequestContext* context, std::string allowed_method, CommandType command_type, int success_code, int error_code); -public: - // this will also need command manager - RestAPI(std::string url, std::shared_ptr command_manager); - void begin(); - void handle_request(struct mg_connection *connection, int event, void *event_data); - void poll(); + public: + // this will also need command manager + RestAPI(std::string url, std::shared_ptr command_manager); + void begin(); + void handle_request(struct mg_connection* connection, int event, void* event_data); + void poll(); }; namespace RestAPIHelpers { - void event_handler(struct mg_connection *connection, int event, void *event_data); +void event_handler(struct mg_connection* connection, int event, void* event_data); }; -void HandleRestAPIPollTask(void *pvParameter); +void HandleRestAPIPollTask(void* pvParameter); #endif \ No newline at end of file diff --git a/components/SerialManager/SerialManager/SerialManager.cpp b/components/SerialManager/SerialManager/SerialManager.cpp index adc1a19..55beeed 100644 --- a/components/SerialManager/SerialManager/SerialManager.cpp +++ b/components/SerialManager/SerialManager/SerialManager.cpp @@ -2,34 +2,34 @@ #include "esp_log.h" #include "main_globals.hpp" -SerialManager::SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle) +SerialManager::SerialManager(std::shared_ptr commandManager, esp_timer_handle_t* timerHandle) : commandManager(commandManager), timerHandle(timerHandle) { - this->data = static_cast(malloc(BUF_SIZE)); - this->temp_data = static_cast(malloc(256)); + this->data = static_cast(malloc(BUF_SIZE)); + this->temp_data = static_cast(malloc(256)); } // Function to notify that a command was received during startup void SerialManager::notify_startup_command_received() { - setStartupCommandReceived(true); + setStartupCommandReceived(true); - // Cancel the startup timer if it's still running - if (timerHandle != nullptr && *timerHandle != nullptr) - { - esp_timer_stop(*timerHandle); - esp_timer_delete(*timerHandle); - *timerHandle = nullptr; - ESP_LOGI("[MAIN]", "Startup timer cancelled, staying in heartbeat mode"); - } + // Cancel the startup timer if it's still running + if (timerHandle != nullptr && *timerHandle != nullptr) + { + esp_timer_stop(*timerHandle); + esp_timer_delete(*timerHandle); + *timerHandle = nullptr; + ESP_LOGI("[MAIN]", "Startup timer cancelled, staying in heartbeat mode"); + } } // we can cancel this task once we're in cdc -void HandleSerialManagerTask(void *pvParameters) +void HandleSerialManagerTask(void* pvParameters) { - auto const serialManager = static_cast(pvParameters); - while (true) - { - serialManager->try_receive(); - } + auto const serialManager = static_cast(pvParameters); + while (true) + { + serialManager->try_receive(); + } } diff --git a/components/SerialManager/SerialManager/SerialManager.hpp b/components/SerialManager/SerialManager/SerialManager.hpp index f48e6b8..cf08d53 100644 --- a/components/SerialManager/SerialManager/SerialManager.hpp +++ b/components/SerialManager/SerialManager/SerialManager.hpp @@ -3,18 +3,18 @@ #define SERIALMANAGER_HPP #include -#include -#include #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "sdkconfig.h" -#include "esp_log.h" +#include +#include #include "driver/gpio.h" -#include "esp_vfs_dev.h" +#include "esp_log.h" #include "esp_mac.h" +#include "esp_vfs_dev.h" +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "sdkconfig.h" #ifndef BUF_SIZE #define BUF_SIZE (1024) @@ -27,26 +27,26 @@ extern QueueHandle_t cdcMessageQueue; struct cdc_command_packet_t { - uint8_t len; - uint8_t data[64]; + uint8_t len; + uint8_t data[64]; }; class SerialManager { -public: - explicit SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle); - void setup(); - void try_receive(); - void notify_startup_command_received(); - void shutdown(); + public: + explicit SerialManager(std::shared_ptr commandManager, esp_timer_handle_t* timerHandle); + void setup(); + void try_receive(); + void notify_startup_command_received(); + void shutdown(); -private: - std::shared_ptr commandManager; - esp_timer_handle_t *timerHandle; - uint8_t *data; - uint8_t *temp_data; + private: + std::shared_ptr commandManager; + esp_timer_handle_t* timerHandle; + uint8_t* data; + uint8_t* temp_data; }; -void HandleSerialManagerTask(void *pvParameters); -void HandleCDCSerialManagerTask(void *pvParameters); +void HandleSerialManagerTask(void* pvParameters); +void HandleCDCSerialManagerTask(void* pvParameters); #endif \ No newline at end of file diff --git a/components/SerialManager/SerialManager/SerialManager_esp32.cpp b/components/SerialManager/SerialManager/SerialManager_esp32.cpp index 4ec64c3..6b2b33f 100644 --- a/components/SerialManager/SerialManager/SerialManager_esp32.cpp +++ b/components/SerialManager/SerialManager/SerialManager_esp32.cpp @@ -1,102 +1,98 @@ #include "SerialManager.hpp" +#include "driver/uart.h" #include "esp_log.h" #include "main_globals.hpp" -#include "driver/uart.h" void SerialManager::setup() { - uart_config_t uart_config = { - .baud_rate = 115200, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - }; + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + }; - const auto uart_num = static_cast(CONFIG_UART_PORT_NUMBER); + const auto uart_num = static_cast(CONFIG_UART_PORT_NUMBER); - uart_driver_install(uart_num, BUF_SIZE, BUF_SIZE, 0, NULL, 0); - uart_param_config(uart_num, &uart_config); + uart_driver_install(uart_num, BUF_SIZE, BUF_SIZE, 0, NULL, 0); + uart_param_config(uart_num, &uart_config); - uart_set_pin(uart_num, - CONFIG_UART_TX_PIN, - CONFIG_UART_RX_PIN, - UART_PIN_NO_CHANGE, - UART_PIN_NO_CHANGE); + uart_set_pin(uart_num, CONFIG_UART_TX_PIN, CONFIG_UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); - gpio_set_pull_mode(static_cast(CONFIG_UART_RX_PIN), GPIO_PULLDOWN_ONLY); + gpio_set_pull_mode(static_cast(CONFIG_UART_RX_PIN), GPIO_PULLDOWN_ONLY); - // ----- Startup Flush ----- - uart_flush(uart_num); + // ----- Startup Flush ----- + uart_flush(uart_num); - uint8_t dump_buf[256]; - // clean up initial onslaught of logs - while (uart_read_bytes(uart_num, dump_buf, sizeof(dump_buf), 10 / portTICK_PERIOD_MS) > 0) - { - } + uint8_t dump_buf[256]; + // clean up initial onslaught of logs + while (uart_read_bytes(uart_num, dump_buf, sizeof(dump_buf), 10 / portTICK_PERIOD_MS) > 0) + { + } } -void uart_write_bytes_chunked(uart_port_t uart_num, const void *src, size_t size) +void uart_write_bytes_chunked(uart_port_t uart_num, const void* src, size_t size) { - while (size > 0) - { - auto to_write = size > BUF_SIZE ? BUF_SIZE : size; - auto written = uart_write_bytes(uart_num, src, to_write); - src += written; - size -= written; - } + while (size > 0) + { + auto to_write = size > BUF_SIZE ? BUF_SIZE : size; + auto written = uart_write_bytes(uart_num, src, to_write); + src += written; + size -= written; + } } void SerialManager::try_receive() { - static auto current_position = 0; - const auto uart_num = static_cast(CONFIG_UART_PORT_NUMBER); - int len = uart_read_bytes(uart_num, this->temp_data, BUF_SIZE, 1000 / 20); + static auto current_position = 0; + const auto uart_num = static_cast(CONFIG_UART_PORT_NUMBER); + int len = uart_read_bytes(uart_num, this->temp_data, BUF_SIZE, 1000 / 20); - // If driver is uninstalled or an error occurs, abort read gracefully - if (len <= 0) - { - return; - } - - if (len > 0) - { - notify_startup_command_received(); - } - - // since we've got something on the serial port - // we gotta keep reading until we've got the whole message - // we will submit the command once we get a newline, a return or the buffer is full - for (auto i = 0; i < len; i++) - { - this->data[current_position++] = this->temp_data[i]; - // if we're at the end of the buffer, try to process the command anyway - // if we've got a new line, we've finished sending the commands, process them - if (current_position >= BUF_SIZE || this->data[current_position - 1] == '\n' || this->data[current_position - 1] == '\r') + // If driver is uninstalled or an error occurs, abort read gracefully + if (len <= 0) { - data[current_position] = '\0'; - current_position = 0; - - const nlohmann::json result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast(this->data))); - const auto resultMessage = result.dump(); - // todo check if this works - // uart_write_bytes_chunked(uart_num, resultMessage.c_str(), resultMessage.length())s - uart_write_bytes(uart_num, resultMessage.c_str(), resultMessage.length()); + return; + } + + if (len > 0) + { + notify_startup_command_received(); + } + + // since we've got something on the serial port + // we gotta keep reading until we've got the whole message + // we will submit the command once we get a newline, a return or the buffer is full + for (auto i = 0; i < len; i++) + { + this->data[current_position++] = this->temp_data[i]; + // if we're at the end of the buffer, try to process the command anyway + // if we've got a new line, we've finished sending the commands, process them + if (current_position >= BUF_SIZE || this->data[current_position - 1] == '\n' || this->data[current_position - 1] == '\r') + { + data[current_position] = '\0'; + current_position = 0; + + const nlohmann::json result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast(this->data))); + const auto resultMessage = result.dump(); + // todo check if this works + // uart_write_bytes_chunked(uart_num, resultMessage.c_str(), resultMessage.length())s + uart_write_bytes(uart_num, resultMessage.c_str(), resultMessage.length()); + } } - } } void SerialManager::shutdown() { - // Uninstall the UART driver to free the internal to keep compatibility with JTAG implementation. - const auto uart_num = static_cast(CONFIG_UART_PORT_NUMBER); - esp_err_t err = uart_driver_delete(uart_num); - if (err == ESP_OK) - { - ESP_LOGI("[SERIAL]", "usb_serial_jtag driver uninstalled"); - } - else if (err != ESP_ERR_INVALID_STATE) - { - ESP_LOGW("[SERIAL]", "usb_serial_jtag_driver_uninstall returned %s", esp_err_to_name(err)); - } + // Uninstall the UART driver to free the internal to keep compatibility with JTAG implementation. + const auto uart_num = static_cast(CONFIG_UART_PORT_NUMBER); + esp_err_t err = uart_driver_delete(uart_num); + if (err == ESP_OK) + { + ESP_LOGI("[SERIAL]", "usb_serial_jtag driver uninstalled"); + } + else if (err != ESP_ERR_INVALID_STATE) + { + ESP_LOGW("[SERIAL]", "usb_serial_jtag_driver_uninstall returned %s", esp_err_to_name(err)); + } } diff --git a/components/SerialManager/SerialManager/SerialManager_esp32s3.cpp b/components/SerialManager/SerialManager/SerialManager_esp32s3.cpp index 4e66f99..3a3a8a9 100644 --- a/components/SerialManager/SerialManager/SerialManager_esp32s3.cpp +++ b/components/SerialManager/SerialManager/SerialManager_esp32s3.cpp @@ -1,114 +1,114 @@ #include "SerialManager.hpp" -#include "esp_log.h" -#include "main_globals.hpp" #include "driver/usb_serial_jtag.h" +#include "esp_log.h" #include "esp_vfs_usb_serial_jtag.h" +#include "main_globals.hpp" #include "tusb.h" void SerialManager::setup() { #ifndef CONFIG_USE_UART_FOR_COMMUNICATION - usb_serial_jtag_driver_config_t usb_serial_jtag_config; - usb_serial_jtag_config.rx_buffer_size = BUF_SIZE; - usb_serial_jtag_config.tx_buffer_size = BUF_SIZE; - usb_serial_jtag_driver_install(&usb_serial_jtag_config); + usb_serial_jtag_driver_config_t usb_serial_jtag_config; + usb_serial_jtag_config.rx_buffer_size = BUF_SIZE; + usb_serial_jtag_config.tx_buffer_size = BUF_SIZE; + usb_serial_jtag_driver_install(&usb_serial_jtag_config); #endif } -void usb_serial_jtag_write_bytes_chunked(const char *data, size_t len, size_t timeout) +void usb_serial_jtag_write_bytes_chunked(const char* data, size_t len, size_t timeout) { #ifndef CONFIG_USE_UART_FOR_COMMUNICATION - while (len > 0) - { - auto to_write = len > BUF_SIZE ? BUF_SIZE : len; - auto written = usb_serial_jtag_write_bytes(data, to_write, timeout); - data += written; - len -= written; - } + while (len > 0) + { + auto to_write = len > BUF_SIZE ? BUF_SIZE : len; + auto written = usb_serial_jtag_write_bytes(data, to_write, timeout); + data += written; + len -= written; + } #endif } void SerialManager::try_receive() { - static auto current_position = 0; - int len = usb_serial_jtag_read_bytes(this->temp_data, 256, 1000 / 20); + static auto current_position = 0; + int len = usb_serial_jtag_read_bytes(this->temp_data, 256, 1000 / 20); - // If driver is uninstalled or an error occurs, abort read gracefully - if (len < 0) - { - return; - } - - if (len > 0) - { - // Notify main that a command was received during startup - notify_startup_command_received(); - } - - // since we've got something on the serial port - // we gotta keep reading until we've got the whole message - // we will submit the command once we get a newline, a return or the buffer is full - for (auto i = 0; i < len; i++) - { - this->data[current_position++] = this->temp_data[i]; - // if we're at the end of the buffer, try to process the command anyway - // if we've got a new line, we've finished sending the commands, process them - if (current_position >= BUF_SIZE || this->data[current_position - 1] == '\n' || this->data[current_position - 1] == '\r') + // If driver is uninstalled or an error occurs, abort read gracefully + if (len < 0) { - data[current_position] = '\0'; - current_position = 0; - - const nlohmann::json result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast(this->data))); - const auto resultMessage = result.dump(); - usb_serial_jtag_write_bytes_chunked(resultMessage.c_str(), resultMessage.length(), 1000 / 20); + return; + } + + if (len > 0) + { + // Notify main that a command was received during startup + notify_startup_command_received(); + } + + // since we've got something on the serial port + // we gotta keep reading until we've got the whole message + // we will submit the command once we get a newline, a return or the buffer is full + for (auto i = 0; i < len; i++) + { + this->data[current_position++] = this->temp_data[i]; + // if we're at the end of the buffer, try to process the command anyway + // if we've got a new line, we've finished sending the commands, process them + if (current_position >= BUF_SIZE || this->data[current_position - 1] == '\n' || this->data[current_position - 1] == '\r') + { + data[current_position] = '\0'; + current_position = 0; + + const nlohmann::json result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast(this->data))); + const auto resultMessage = result.dump(); + usb_serial_jtag_write_bytes_chunked(resultMessage.c_str(), resultMessage.length(), 1000 / 20); + } } - } } void SerialManager::shutdown() { - // Uninstall the USB Serial JTAG driver to free the internal USB for TinyUSB. - esp_err_t err = usb_serial_jtag_driver_uninstall(); - if (err == ESP_OK) - { - ESP_LOGI("[SERIAL]", "usb_serial_jtag driver uninstalled"); - } - else if (err != ESP_ERR_INVALID_STATE) - { - ESP_LOGW("[SERIAL]", "usb_serial_jtag_driver_uninstall returned %s", esp_err_to_name(err)); - } + // Uninstall the USB Serial JTAG driver to free the internal USB for TinyUSB. + esp_err_t err = usb_serial_jtag_driver_uninstall(); + if (err == ESP_OK) + { + ESP_LOGI("[SERIAL]", "usb_serial_jtag driver uninstalled"); + } + else if (err != ESP_ERR_INVALID_STATE) + { + ESP_LOGW("[SERIAL]", "usb_serial_jtag_driver_uninstall returned %s", esp_err_to_name(err)); + } } -void HandleCDCSerialManagerTask(void *pvParameters) +void HandleCDCSerialManagerTask(void* pvParameters) { #ifndef CONFIG_USE_UART_FOR_COMMUNICATION - auto const commandManager = static_cast(pvParameters); - static char buffer[BUF_SIZE]; - auto idx = 0; + auto const commandManager = static_cast(pvParameters); + static char buffer[BUF_SIZE]; + auto idx = 0; - cdc_command_packet_t packet; - while (true) - { - if (xQueueReceive(cdcMessageQueue, &packet, portMAX_DELAY) == pdTRUE) + cdc_command_packet_t packet; + while (true) { - for (auto i = 0; i < packet.len; i++) - { - buffer[idx++] = packet.data[i]; - // if we're at the end of the buffer, try to process the command anyway - // if we've got a new line, we've finished sending the commands, process them - if (idx >= BUF_SIZE || buffer[idx - 1] == '\n' || buffer[idx - 1] == '\r') + if (xQueueReceive(cdcMessageQueue, &packet, portMAX_DELAY) == pdTRUE) { - buffer[idx - 1] = '\0'; - const nlohmann::json result = commandManager->executeFromJson(std::string_view(reinterpret_cast(buffer))); - const auto resultMessage = result.dump(); - tud_cdc_write(resultMessage.c_str(), resultMessage.length()); - tud_cdc_write_flush(); - idx = 0; + for (auto i = 0; i < packet.len; i++) + { + buffer[idx++] = packet.data[i]; + // if we're at the end of the buffer, try to process the command anyway + // if we've got a new line, we've finished sending the commands, process them + if (idx >= BUF_SIZE || buffer[idx - 1] == '\n' || buffer[idx - 1] == '\r') + { + buffer[idx - 1] = '\0'; + const nlohmann::json result = commandManager->executeFromJson(std::string_view(reinterpret_cast(buffer))); + const auto resultMessage = result.dump(); + tud_cdc_write(resultMessage.c_str(), resultMessage.length()); + tud_cdc_write_flush(); + idx = 0; + } + } } - } } - } #endif } @@ -117,36 +117,35 @@ void HandleCDCSerialManagerTask(void *pvParameters) // grab the data and send it to a queue, a special task will process it and handle with the command manager extern "C" void tud_cdc_rx_cb(uint8_t itf) { - // we can void the interface number - (void)itf; - cdc_command_packet_t packet; - auto len = tud_cdc_available(); + // we can void the interface number + (void)itf; + cdc_command_packet_t packet; + auto len = tud_cdc_available(); - if (len > 0) - { - auto read = tud_cdc_read(packet.data, sizeof(packet.data)); - if (read > 0) + if (len > 0) { - // we should be safe here, given that the max buffer size is 64 - packet.len = static_cast(read); - xQueueSend(cdcMessageQueue, &packet, 1); + auto read = tud_cdc_read(packet.data, sizeof(packet.data)); + if (read > 0) + { + // we should be safe here, given that the max buffer size is 64 + packet.len = static_cast(read); + xQueueSend(cdcMessageQueue, &packet, 1); + } } - } } extern "C" void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { - (void)itf; - (void)dtr; - (void)rts; + (void)itf; + (void)dtr; + (void)rts; - ESP_LOGI("[SERIAL]", "CDC line state changed: DTR=%d, RTS=%d", dtr, rts); + ESP_LOGI("[SERIAL]", "CDC line state changed: DTR=%d, RTS=%d", dtr, rts); } -void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const *p_line_coding) +void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding) { - (void)itf; - ESP_LOGI("[SERIAL]", "CDC line coding: %" PRIu32 " bps, %d stop bits, %d parity, %d data bits", - p_line_coding->bit_rate, p_line_coding->stop_bits, - p_line_coding->parity, p_line_coding->data_bits); + (void)itf; + ESP_LOGI("[SERIAL]", "CDC line coding: %" PRIu32 " bps, %d stop bits, %d parity, %d data bits", p_line_coding->bit_rate, p_line_coding->stop_bits, + p_line_coding->parity, p_line_coding->data_bits); } \ No newline at end of file diff --git a/components/StateManager/StateManager/StateManager.cpp b/components/StateManager/StateManager/StateManager.cpp index a7567b5..a25814f 100644 --- a/components/StateManager/StateManager/StateManager.cpp +++ b/components/StateManager/StateManager/StateManager.cpp @@ -4,100 +4,99 @@ StateManager::StateManager(QueueHandle_t eventQueue, QueueHandle_t ledStateQueue void StateManager::HandleUpdateState() { - SystemEvent eventBuffer; - auto ledStreamState = LEDStates_e::LedStateNone; + SystemEvent eventBuffer; + auto ledStreamState = LEDStates_e::LedStateNone; - if (xQueueReceive(this->eventQueue, &eventBuffer, portMAX_DELAY)) - { - switch (eventBuffer.source) + if (xQueueReceive(this->eventQueue, &eventBuffer, portMAX_DELAY)) { + switch (eventBuffer.source) + { + case EventSource::WIFI: + { + this->wifi_state = std::get(eventBuffer.value); - case EventSource::WIFI: - { - this->wifi_state = std::get(eventBuffer.value); + if (this->wifi_state == WiFiState_e::WiFiState_Connecting) + { + ledStreamState = LEDStates_e::WiFiStateConnecting; + xQueueSend(this->ledStateQueue, &ledStreamState, 10); + } + if (this->wifi_state == WiFiState_e::WiFiState_Connected) + { + ledStreamState = LEDStates_e::WiFiStateConnected; + xQueueSend(this->ledStateQueue, &ledStreamState, 10); + } + if (this->wifi_state == WiFiState_e::WiFiState_Error) + { + ledStreamState = LEDStates_e::WiFiStateError; + xQueueSend(this->ledStateQueue, &ledStreamState, 10); + } - if (this->wifi_state == WiFiState_e::WiFiState_Connecting) - { - ledStreamState = LEDStates_e::WiFiStateConnecting; - xQueueSend(this->ledStateQueue, &ledStreamState, 10); - } - if (this->wifi_state == WiFiState_e::WiFiState_Connected) - { - ledStreamState = LEDStates_e::WiFiStateConnected; - xQueueSend(this->ledStateQueue, &ledStreamState, 10); - } - if (this->wifi_state == WiFiState_e::WiFiState_Error) - { - ledStreamState = LEDStates_e::WiFiStateError; - xQueueSend(this->ledStateQueue, &ledStreamState, 10); - } + break; + } - break; + case EventSource::MDNS: + { + this->mdns_state = std::get(eventBuffer.value); + break; + } + + case EventSource::CAMERA: + { + this->camera_state = std::get(eventBuffer.value); + + if (this->camera_state == CameraState_e::Camera_Error) + { + ledStreamState = LEDStates_e::CameraError; + xQueueSend(this->ledStateQueue, &ledStreamState, 10); + } + + break; + } + + case EventSource::STREAM: + { + this->stream_state = std::get(eventBuffer.value); + + if (this->stream_state == StreamState_e::Stream_ON) + { + ledStreamState = LEDStates_e::LedStateStreaming; + xQueueSend(this->ledStateQueue, &ledStreamState, 10); + } + else if (this->stream_state == StreamState_e::Stream_OFF) + { + ledStreamState = LEDStates_e::LedStateStoppedStreaming; + xQueueSend(this->ledStateQueue, &ledStreamState, 10); + } + break; + } + + default: + break; + } } - - case EventSource::MDNS: - { - this->mdns_state = std::get(eventBuffer.value); - break; - } - - case EventSource::CAMERA: - { - this->camera_state = std::get(eventBuffer.value); - - if (this->camera_state == CameraState_e::Camera_Error) - { - ledStreamState = LEDStates_e::CameraError; - xQueueSend(this->ledStateQueue, &ledStreamState, 10); - } - - break; - } - - case EventSource::STREAM: - { - this->stream_state = std::get(eventBuffer.value); - - if (this->stream_state == StreamState_e::Stream_ON) - { - ledStreamState = LEDStates_e::LedStateStreaming; - xQueueSend(this->ledStateQueue, &ledStreamState, 10); - } - else if (this->stream_state == StreamState_e::Stream_OFF) - { - ledStreamState = LEDStates_e::LedStateStoppedStreaming; - xQueueSend(this->ledStateQueue, &ledStreamState, 10); - } - break; - } - - default: - break; - } - } } WiFiState_e StateManager::GetWifiState() { - return this->wifi_state; + return this->wifi_state; } CameraState_e StateManager::GetCameraState() { - return this->camera_state; + return this->camera_state; } QueueHandle_t StateManager::GetEventQueue() const { - return this->eventQueue; + return this->eventQueue; } -void HandleStateManagerTask(void *pvParameters) +void HandleStateManagerTask(void* pvParameters) { - auto *stateManager = static_cast(pvParameters); + auto* stateManager = static_cast(pvParameters); - while (true) - { - stateManager->HandleUpdateState(); - } + while (true) + { + stateManager->HandleUpdateState(); + } } \ No newline at end of file diff --git a/components/StateManager/StateManager/StateManager.hpp b/components/StateManager/StateManager/StateManager.hpp index ed49e60..85328cf 100644 --- a/components/StateManager/StateManager/StateManager.hpp +++ b/components/StateManager/StateManager/StateManager.hpp @@ -10,93 +10,93 @@ // Naming kept stable for existing queues; documented meanings added. enum class LEDStates_e { - LedStateNone, // Idle / no indication (LED off) - LedStateStreaming, // Active streaming (UVC or WiFi) – steady ON - LedStateStoppedStreaming, // Streaming stopped intentionally – steady OFF (could differentiate later) - CameraError, // Camera init / runtime failure – double blink pattern - WiFiStateError, // WiFi connection error – distinctive blink sequence - WiFiStateConnecting, // WiFi association / DHCP pending – slow blink - WiFiStateConnected // WiFi connected (momentary confirmation burst) + LedStateNone, // Idle / no indication (LED off) + LedStateStreaming, // Active streaming (UVC or WiFi) - steady ON + LedStateStoppedStreaming, // Streaming stopped intentionally - steady OFF (could differentiate later) + CameraError, // Camera init / runtime failure - double blink pattern + WiFiStateError, // WiFi connection error - distinctive blink sequence + WiFiStateConnecting, // WiFi association / DHCP pending - slow blink + WiFiStateConnected // WiFi connected (momentary confirmation burst) }; enum class WiFiState_e { - WiFiState_NotInitialized, - WiFiState_Initialized, - WiFiState_ReadyToConnect, - WiFiState_Connecting, - WiFiState_WaitingForIp, - WiFiState_Connected, - WiFiState_Disconnected, - WiFiState_Error + WiFiState_NotInitialized, + WiFiState_Initialized, + WiFiState_ReadyToConnect, + WiFiState_Connecting, + WiFiState_WaitingForIp, + WiFiState_Connected, + WiFiState_Disconnected, + WiFiState_Error }; enum class MDNSState_e { - MDNSState_Stopped, - MDNSState_Starting, - MDNSState_Started, - MDNSState_Stopping, - MDNSState_Error, - MDNSState_QueryStarted, - MDNSState_QueryComplete + MDNSState_Stopped, + MDNSState_Starting, + MDNSState_Started, + MDNSState_Stopping, + MDNSState_Error, + MDNSState_QueryStarted, + MDNSState_QueryComplete }; enum class CameraState_e { - Camera_Disconnected, - Camera_Success, - Camera_Error + Camera_Disconnected, + Camera_Success, + Camera_Error }; enum class StreamState_e { - Stream_OFF, - Stream_ON, + Stream_OFF, + Stream_ON, }; enum class EventSource { - WIFI, - MDNS, - CAMERA, - STREAM + WIFI, + MDNS, + CAMERA, + STREAM }; struct SystemEvent { - EventSource source; - std::variant value; + EventSource source; + std::variant value; }; class StateManager { -public: - StateManager(QueueHandle_t eventQueue, QueueHandle_t ledStateQueue); - void HandleUpdateState(); - WiFiState_e GetWifiState(); - CameraState_e GetCameraState(); - QueueHandle_t GetEventQueue() const; + public: + StateManager(QueueHandle_t eventQueue, QueueHandle_t ledStateQueue); + void HandleUpdateState(); + WiFiState_e GetWifiState(); + CameraState_e GetCameraState(); + QueueHandle_t GetEventQueue() const; -private: - QueueHandle_t eventQueue; - QueueHandle_t ledStateQueue; + private: + QueueHandle_t eventQueue; + QueueHandle_t ledStateQueue; - WiFiState_e wifi_state; - MDNSState_e mdns_state; - CameraState_e camera_state; - StreamState_e stream_state; + WiFiState_e wifi_state; + MDNSState_e mdns_state; + CameraState_e camera_state; + StreamState_e stream_state; }; // Lightweight helper to publish stream state changes to the shared event queue. static inline bool SendStreamEvent(QueueHandle_t queue, StreamState_e state) { - if (!queue) - return false; - SystemEvent evt{EventSource::STREAM, state}; - return xQueueSend(queue, &evt, 0) == pdTRUE; + if (!queue) + return false; + SystemEvent evt{EventSource::STREAM, state}; + return xQueueSend(queue, &evt, 0) == pdTRUE; } -void HandleStateManagerTask(void *pvParameters); +void HandleStateManagerTask(void* pvParameters); -#endif // STATEMANAGER_HPP +#endif // STATEMANAGER_HPP diff --git a/components/StreamServer/StreamServer/StreamServer.cpp b/components/StreamServer/StreamServer/StreamServer.cpp index 3d876f3..efc0372 100644 --- a/components/StreamServer/StreamServer/StreamServer.cpp +++ b/components/StreamServer/StreamServer/StreamServer.cpp @@ -1,174 +1,172 @@ #include "StreamServer.hpp" -constexpr static const char *STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; -constexpr static const char *STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; -constexpr static const char *STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\nX-Timestamp: %lli.%06li\r\n\r\n"; +constexpr static const char* STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; +constexpr static const char* STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; +constexpr static const char* STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\nX-Timestamp: %lli.%06li\r\n\r\n"; -static const char *STREAM_SERVER_TAG = "[STREAM_SERVER]"; +static const char* STREAM_SERVER_TAG = "[STREAM_SERVER]"; -StreamServer::StreamServer(const int STREAM_PORT, StateManager *stateManager) : STREAM_SERVER_PORT(STREAM_PORT), stateManager(stateManager) +StreamServer::StreamServer(const int STREAM_PORT, StateManager* stateManager) : STREAM_SERVER_PORT(STREAM_PORT), stateManager(stateManager) {} + +esp_err_t StreamHelpers::stream(httpd_req_t* req) { -} + camera_fb_t* fb = nullptr; + struct timeval _timestamp; -esp_err_t StreamHelpers::stream(httpd_req_t *req) -{ - camera_fb_t *fb = nullptr; - struct timeval _timestamp; + esp_err_t response = ESP_OK; + size_t _jpg_buf_len = 0; + uint8_t* _jpg_buf = nullptr; - esp_err_t response = ESP_OK; - size_t _jpg_buf_len = 0; - uint8_t *_jpg_buf = nullptr; + // Buffer for multipart header + char part_buf[256]; + static int64_t last_frame = 0; + if (!last_frame) + last_frame = esp_timer_get_time(); - // Buffer for multipart header; was mistakenly declared as array of pointers - char part_buf[256]; - static int64_t last_frame = 0; - if (!last_frame) - last_frame = esp_timer_get_time(); + // Pull event queue from user_ctx to send STREAM on/off notifications + auto* stateManager = static_cast(req->user_ctx); + QueueHandle_t eventQueue = stateManager ? stateManager->GetEventQueue() : nullptr; + bool stream_on_sent = false; - // Pull event queue from user_ctx to send STREAM on/off notifications - auto *stateManager = static_cast(req->user_ctx); - QueueHandle_t eventQueue = stateManager ? stateManager->GetEventQueue() : nullptr; - bool stream_on_sent = false; - - response = httpd_resp_set_type(req, STREAM_CONTENT_TYPE); - if (response != ESP_OK) - return response; - - httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - httpd_resp_set_hdr(req, "X-Framerate", "60"); - - if (SendStreamEvent(eventQueue, StreamState_e::Stream_ON)) - stream_on_sent = true; - - while (true) - { - fb = esp_camera_fb_get(); - - if (!fb) - { - ESP_LOGE(STREAM_SERVER_TAG, "Camera capture failed"); - response = ESP_FAIL; - // Don't break immediately, try to recover - vTaskDelay(pdMS_TO_TICKS(10)); - continue; - } - else - { - _timestamp.tv_sec = fb->timestamp.tv_sec; - _timestamp.tv_usec = fb->timestamp.tv_usec; - _jpg_buf_len = fb->len; - _jpg_buf = fb->buf; - } - if (response == ESP_OK) - response = httpd_resp_send_chunk(req, STREAM_BOUNDARY, strlen(STREAM_BOUNDARY)); - if (response == ESP_OK) - { - size_t hlen = snprintf((char *)part_buf, sizeof(part_buf), STREAM_PART, _jpg_buf_len, _timestamp.tv_sec, _timestamp.tv_usec); - response = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); - } - if (response == ESP_OK) - response = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); - if (fb) - { - esp_camera_fb_return(fb); - fb = NULL; - _jpg_buf = NULL; - } - else if (_jpg_buf) - { - free(_jpg_buf); - _jpg_buf = NULL; - } + response = httpd_resp_set_type(req, STREAM_CONTENT_TYPE); if (response != ESP_OK) - break; + return response; - if (esp_log_level_get(STREAM_SERVER_TAG) >= ESP_LOG_INFO) + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + httpd_resp_set_hdr(req, "X-Framerate", "60"); + + if (SendStreamEvent(eventQueue, StreamState_e::Stream_ON)) + stream_on_sent = true; + + while (true) { - static long last_request_time = 0; - if (last_request_time == 0) - { - last_request_time = Helpers::getTimeInMillis(); - } + fb = esp_camera_fb_get(); - // Only log every 100 frames to reduce overhead - const int frame_window = 100; - static int frame_count = 0; - if (++frame_count % frame_window == 0) - { - long request_end = Helpers::getTimeInMillis(); - long window_ms = request_end - last_request_time; - last_request_time = request_end; - long fps = 0; - if (window_ms > 0) + if (!fb) { - fps = (frame_window * 1000) / window_ms; + ESP_LOGE(STREAM_SERVER_TAG, "Camera capture failed"); + response = ESP_FAIL; + // Don't break immediately, try to recover + vTaskDelay(pdMS_TO_TICKS(10)); + continue; + } + else + { + _timestamp.tv_sec = fb->timestamp.tv_sec; + _timestamp.tv_usec = fb->timestamp.tv_usec; + _jpg_buf_len = fb->len; + _jpg_buf = fb->buf; + } + if (response == ESP_OK) + response = httpd_resp_send_chunk(req, STREAM_BOUNDARY, strlen(STREAM_BOUNDARY)); + if (response == ESP_OK) + { + size_t hlen = snprintf((char*)part_buf, sizeof(part_buf), STREAM_PART, _jpg_buf_len, _timestamp.tv_sec, _timestamp.tv_usec); + response = httpd_resp_send_chunk(req, (const char*)part_buf, hlen); + } + if (response == ESP_OK) + response = httpd_resp_send_chunk(req, (const char*)_jpg_buf, _jpg_buf_len); + if (fb) + { + esp_camera_fb_return(fb); + fb = NULL; + _jpg_buf = NULL; + } + else if (_jpg_buf) + { + free(_jpg_buf); + _jpg_buf = NULL; + } + if (response != ESP_OK) + break; + + if (esp_log_level_get(STREAM_SERVER_TAG) >= ESP_LOG_INFO) + { + static long last_request_time = 0; + if (last_request_time == 0) + { + last_request_time = Helpers::getTimeInMillis(); + } + + // Only log every 100 frames to reduce overhead + const int frame_window = 100; + static int frame_count = 0; + if (++frame_count % frame_window == 0) + { + long request_end = Helpers::getTimeInMillis(); + long window_ms = request_end - last_request_time; + last_request_time = request_end; + long fps = 0; + if (window_ms > 0) + { + fps = (frame_window * 1000) / window_ms; + } + ESP_LOGI(STREAM_SERVER_TAG, "%i Frames Size: %uKB, Time: %lims (%lifps)", frame_window, _jpg_buf_len / 1024, window_ms, fps); + } } - ESP_LOGI(STREAM_SERVER_TAG, "%i Frames Size: %uKB, Time: %lims (%lifps)",frame_window, _jpg_buf_len / 1024, window_ms, fps); - } } - } - last_frame = 0; + last_frame = 0; - if (stream_on_sent) - SendStreamEvent(eventQueue, StreamState_e::Stream_OFF); + if (stream_on_sent) + SendStreamEvent(eventQueue, StreamState_e::Stream_OFF); - return response; + return response; } -esp_err_t StreamHelpers::ws_logs_handle(httpd_req_t *req) +esp_err_t StreamHelpers::ws_logs_handle(httpd_req_t* req) { - auto ret = webSocketLogger.register_socket_client(req); - return ret; + auto ret = webSocketLogger.register_socket_client(req); + return ret; } esp_err_t StreamServer::startStreamServer() { - httpd_config_t config = HTTPD_DEFAULT_CONFIG(); - config.stack_size = 20480; - config.max_uri_handlers = 10; - config.server_port = STREAM_SERVER_PORT; - config.ctrl_port = STREAM_SERVER_PORT; - config.recv_wait_timeout = 5; // 5 seconds for receiving - config.send_wait_timeout = 5; // 5 seconds for sending - config.lru_purge_enable = true; // Enable LRU purge for better connection handling + httpd_config_t config = HTTPD_DEFAULT_CONFIG(); + config.stack_size = 20480; + config.max_uri_handlers = 10; + config.server_port = STREAM_SERVER_PORT; + config.ctrl_port = STREAM_SERVER_PORT; + config.recv_wait_timeout = 5; // 5 seconds for receiving + config.send_wait_timeout = 5; // 5 seconds for sending + config.lru_purge_enable = true; // Enable LRU purge for better connection handling - httpd_uri_t stream_page = { - .uri = "/", - .method = HTTP_GET, - .handler = &StreamHelpers::stream, - .user_ctx = this->stateManager, - }; + httpd_uri_t stream_page = { + .uri = "/", + .method = HTTP_GET, + .handler = &StreamHelpers::stream, + .user_ctx = this->stateManager, + }; - httpd_uri_t logs_ws = { - .uri = "/ws", - .method = HTTP_GET, - .handler = &StreamHelpers::ws_logs_handle, - .user_ctx = nullptr, - .is_websocket = true, - }; + httpd_uri_t logs_ws = { + .uri = "/ws", + .method = HTTP_GET, + .handler = &StreamHelpers::ws_logs_handle, + .user_ctx = nullptr, + .is_websocket = true, + }; - int status = httpd_start(&camera_stream, &config); + int status = httpd_start(&camera_stream, &config); - if (status != ESP_OK) - { - ESP_LOGE(STREAM_SERVER_TAG, "Cannot start stream server."); - return status; - } + if (status != ESP_OK) + { + ESP_LOGE(STREAM_SERVER_TAG, "Cannot start stream server."); + return status; + } - httpd_register_uri_handler(camera_stream, &logs_ws); - if (this->stateManager->GetCameraState() != CameraState_e::Camera_Success) - { - ESP_LOGE(STREAM_SERVER_TAG, "Camera not initialized. Cannot start stream server. Logs server will be running."); - return ESP_FAIL; - } + httpd_register_uri_handler(camera_stream, &logs_ws); + if (this->stateManager->GetCameraState() != CameraState_e::Camera_Success) + { + ESP_LOGE(STREAM_SERVER_TAG, "Camera not initialized. Cannot start stream server. Logs server will be running."); + return ESP_FAIL; + } - httpd_register_uri_handler(camera_stream, &stream_page); + httpd_register_uri_handler(camera_stream, &stream_page); - // Initial state is OFF - if (this->stateManager) - SendStreamEvent(this->stateManager->GetEventQueue(), StreamState_e::Stream_OFF); + // Initial state is OFF + if (this->stateManager) + SendStreamEvent(this->stateManager->GetEventQueue(), StreamState_e::Stream_OFF); - ESP_LOGI(STREAM_SERVER_TAG, "Stream server started on port %d", STREAM_SERVER_PORT); + ESP_LOGI(STREAM_SERVER_TAG, "Stream server started on port %d", STREAM_SERVER_PORT); - return ESP_OK; + return ESP_OK; } \ No newline at end of file diff --git a/components/StreamServer/StreamServer/StreamServer.hpp b/components/StreamServer/StreamServer/StreamServer.hpp index 26ed412..8161a3e 100644 --- a/components/StreamServer/StreamServer/StreamServer.hpp +++ b/components/StreamServer/StreamServer/StreamServer.hpp @@ -4,35 +4,35 @@ #define PART_BOUNDARY "123456789000000000000987654321" -#include "esp_log.h" -#include "esp_camera.h" -#include "esp_http_server.h" -#include "esp_timer.h" #include #include #include +#include "esp_camera.h" +#include "esp_http_server.h" +#include "esp_log.h" +#include "esp_timer.h" extern WebSocketLogger webSocketLogger; namespace StreamHelpers { - esp_err_t stream(httpd_req_t *req); - esp_err_t ws_logs_handle(httpd_req_t *req); -} +esp_err_t stream(httpd_req_t* req); +esp_err_t ws_logs_handle(httpd_req_t* req); +} // namespace StreamHelpers class StreamServer { -private: - int STREAM_SERVER_PORT; - StateManager *stateManager; - httpd_handle_t camera_stream = nullptr; + private: + int STREAM_SERVER_PORT; + StateManager* stateManager; + httpd_handle_t camera_stream = nullptr; -public: - StreamServer(const int STREAM_PORT, StateManager *StateManager); - esp_err_t startStreamServer(); + public: + StreamServer(const int STREAM_PORT, StateManager* StateManager); + esp_err_t startStreamServer(); - esp_err_t stream(httpd_req_t *req); - esp_err_t ws_logs_handle(httpd_req_t *req); + esp_err_t stream(httpd_req_t* req); + esp_err_t ws_logs_handle(httpd_req_t* req); }; #endif \ No newline at end of file diff --git a/components/UVCStream/UVCStream/UVCStream.cpp b/components/UVCStream/UVCStream/UVCStream.cpp index 2967057..5f5601f 100644 --- a/components/UVCStream/UVCStream/UVCStream.cpp +++ b/components/UVCStream/UVCStream/UVCStream.cpp @@ -1,11 +1,11 @@ #include "UVCStream.hpp" #ifdef CONFIG_GENERAL_INCLUDE_UVC_MODE -#include // for snprintf +#include // for snprintf #include "freertos/FreeRTOS.h" #include "freertos/task.h" -static const char *UVC_STREAM_TAG = "[UVC DEVICE]"; +static const char* UVC_STREAM_TAG = "[UVC DEVICE]"; // Tracks whether a frame has been handed to TinyUSB and not yet returned. // File scope so both get_cb and return_cb can access it safely. @@ -13,207 +13,207 @@ static bool s_frame_inflight = false; extern "C" { - static char serial_number_str[13]; + static char serial_number_str[13]; - const char *get_uvc_device_name() - { - return deviceConfig->getMDNSConfig().hostname.c_str(); - } - - const char *get_serial_number(void) - { - if (serial_number_str[0] == '\0') + const char* get_uvc_device_name() { - uint8_t mac_address[6]; - esp_err_t result = esp_efuse_mac_get_default(mac_address); - if (result != ESP_OK) - { - ESP_LOGE(UVC_STREAM_TAG, "Failed to get MAC address of the board, returning default serial number"); - return CONFIG_TUSB_SERIAL_NUM; - } - - // 12 hex chars without separators - snprintf(serial_number_str, sizeof(serial_number_str), "%02X%02X%02X%02X%02X%02X", - mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]); + return deviceConfig->getMDNSConfig().hostname.c_str(); + } + + const char* get_serial_number(void) + { + if (serial_number_str[0] == '\0') + { + uint8_t mac_address[6]; + esp_err_t result = esp_efuse_mac_get_default(mac_address); + if (result != ESP_OK) + { + ESP_LOGE(UVC_STREAM_TAG, "Failed to get MAC address of the board, returning default serial number"); + return CONFIG_TUSB_SERIAL_NUM; + } + + // 12 hex chars without separators + snprintf(serial_number_str, sizeof(serial_number_str), "%02X%02X%02X%02X%02X%02X", mac_address[0], mac_address[1], mac_address[2], mac_address[3], + mac_address[4], mac_address[5]); + } + return serial_number_str; } - return serial_number_str; - } } // single definition of shared framebuffer storage UVCStreamHelpers::fb_t UVCStreamHelpers::s_fb = {}; -static esp_err_t UVCStreamHelpers::camera_start_cb(uvc_format_t format, int width, int height, int rate, void *cb_ctx) +static esp_err_t UVCStreamHelpers::camera_start_cb(uvc_format_t format, int width, int height, int rate, void* cb_ctx) { - ESP_LOGI(UVC_STREAM_TAG, "Camera Start"); - ESP_LOGI(UVC_STREAM_TAG, "Format: %d, width: %d, height: %d, rate: %d", format, width, height, rate); - framesize_t frame_size = FRAMESIZE_QVGA; + ESP_LOGI(UVC_STREAM_TAG, "Camera Start"); + ESP_LOGI(UVC_STREAM_TAG, "Format: %d, width: %d, height: %d, rate: %d", format, width, height, rate); + framesize_t frame_size = FRAMESIZE_QVGA; - if (format != UVC_FORMAT_JPEG) - { - ESP_LOGE(UVC_STREAM_TAG, "Only support MJPEG format"); - return ESP_ERR_NOT_SUPPORTED; - } + if (format != UVC_FORMAT_JPEG) + { + ESP_LOGE(UVC_STREAM_TAG, "Only support MJPEG format"); + return ESP_ERR_NOT_SUPPORTED; + } - if (width == 240 && height == 240) - { - frame_size = FRAMESIZE_240X240; - } - else - { - ESP_LOGE(UVC_STREAM_TAG, "Unsupported frame size %dx%d", width, height); - return ESP_ERR_NOT_SUPPORTED; - } + if (width == 240 && height == 240) + { + frame_size = FRAMESIZE_240X240; + } + else + { + ESP_LOGE(UVC_STREAM_TAG, "Unsupported frame size %dx%d", width, height); + return ESP_ERR_NOT_SUPPORTED; + } - cameraHandler->setCameraResolution(frame_size); + cameraHandler->setCameraResolution(frame_size); - SendStreamEvent(eventQueue, StreamState_e::Stream_ON); + SendStreamEvent(eventQueue, StreamState_e::Stream_ON); - return ESP_OK; + return ESP_OK; } -static void UVCStreamHelpers::camera_stop_cb(void *cb_ctx) +static void UVCStreamHelpers::camera_stop_cb(void* cb_ctx) { - (void)cb_ctx; - if (s_fb.cam_fb_p) - { - esp_camera_fb_return(s_fb.cam_fb_p); - s_fb.cam_fb_p = nullptr; - } + (void)cb_ctx; + if (s_fb.cam_fb_p) + { + esp_camera_fb_return(s_fb.cam_fb_p); + s_fb.cam_fb_p = nullptr; + } - SendStreamEvent(eventQueue, StreamState_e::Stream_OFF); + SendStreamEvent(eventQueue, StreamState_e::Stream_OFF); } -static uvc_fb_t *UVCStreamHelpers::camera_fb_get_cb(void *cb_ctx) +static uvc_fb_t* UVCStreamHelpers::camera_fb_get_cb(void* cb_ctx) { - auto *mgr = static_cast(cb_ctx); + auto* mgr = static_cast(cb_ctx); - // Guard against requesting a new frame while previous is still in flight. - // This was causing intermittent corruption/glitches because the pointer - // to the underlying camera buffer was overwritten before TinyUSB returned it. + // Guard against requesting a new frame while previous is still in flight. + // This was causing intermittent corruption/glitches because the pointer + // to the underlying camera buffer was overwritten before TinyUSB returned it. - // --- Frame pacing BEFORE grabbing a new camera frame --- - static int64_t next_deadline_us = 0; // next permitted capture time - static int rem_acc = 0; // fractional remainder accumulator - static const int target_fps = 60; // desired FPS - static const int64_t us_per_sec = 1000000; // 1e6 microseconds - static const int base_interval_us = us_per_sec / target_fps; // 16666 - static const int rem_us = us_per_sec % target_fps; // 40 (distributed) + // --- Frame pacing BEFORE grabbing a new camera frame --- + static int64_t next_deadline_us = 0; // next permitted capture time + static int rem_acc = 0; // fractional remainder accumulator + static const int target_fps = 60; // desired FPS + static const int64_t us_per_sec = 1000000; // 1e6 microseconds + static const int base_interval_us = us_per_sec / target_fps; // 16666 + static const int rem_us = us_per_sec % target_fps; // 40 (distributed) - const int64_t now_us = esp_timer_get_time(); - if (next_deadline_us == 0) - { - // First allowed capture immediately - next_deadline_us = now_us; - } + const int64_t now_us = esp_timer_get_time(); + if (next_deadline_us == 0) + { + // First allowed capture immediately + next_deadline_us = now_us; + } - // If a frame is still being transmitted or we are too early, just signal no frame - if (s_frame_inflight || now_us < next_deadline_us) - { - return nullptr; // host will poll again - } + // If a frame is still being transmitted or we are too early, just signal no frame + if (s_frame_inflight || now_us < next_deadline_us) + { + return nullptr; // host will poll again + } - // Acquire a fresh frame only when allowed and no frame in flight - camera_fb_t *cam_fb = esp_camera_fb_get(); - if (!cam_fb) - { - return nullptr; - } + // Acquire a fresh frame only when allowed and no frame in flight + camera_fb_t* cam_fb = esp_camera_fb_get(); + if (!cam_fb) + { + return nullptr; + } - s_fb.cam_fb_p = cam_fb; - s_fb.uvc_fb.buf = cam_fb->buf; - s_fb.uvc_fb.len = cam_fb->len; - s_fb.uvc_fb.width = cam_fb->width; - s_fb.uvc_fb.height = cam_fb->height; - s_fb.uvc_fb.format = UVC_FORMAT_JPEG; - s_fb.uvc_fb.timestamp = cam_fb->timestamp; + s_fb.cam_fb_p = cam_fb; + s_fb.uvc_fb.buf = cam_fb->buf; + s_fb.uvc_fb.len = cam_fb->len; + s_fb.uvc_fb.width = cam_fb->width; + s_fb.uvc_fb.height = cam_fb->height; + s_fb.uvc_fb.format = UVC_FORMAT_JPEG; + s_fb.uvc_fb.timestamp = cam_fb->timestamp; - // Validate size fits into transfer buffer - if (mgr && s_fb.uvc_fb.len > mgr->getUvcBufferSize()) - { - ESP_LOGE(UVC_STREAM_TAG, "Frame size %d exceeds UVC buffer size %u", (int)s_fb.uvc_fb.len, (unsigned)mgr->getUvcBufferSize()); - esp_camera_fb_return(cam_fb); - s_fb.cam_fb_p = nullptr; - return nullptr; - } + // Validate size fits into transfer buffer + if (mgr && s_fb.uvc_fb.len > mgr->getUvcBufferSize()) + { + ESP_LOGE(UVC_STREAM_TAG, "Frame size %d exceeds UVC buffer size %u", (int)s_fb.uvc_fb.len, (unsigned)mgr->getUvcBufferSize()); + esp_camera_fb_return(cam_fb); + s_fb.cam_fb_p = nullptr; + return nullptr; + } - // Schedule next frame time (distribute remainder for exact long‑term 60.000 fps) - rem_acc += rem_us; - int extra_us = 0; - if (rem_acc >= target_fps) - { - rem_acc -= target_fps; - extra_us = 1; - } - const int64_t candidate_next = next_deadline_us + base_interval_us + extra_us; - next_deadline_us = (candidate_next < now_us) ? now_us : candidate_next; + // Schedule next frame time (distribute remainder for exact long‑term 60.000 fps) + rem_acc += rem_us; + int extra_us = 0; + if (rem_acc >= target_fps) + { + rem_acc -= target_fps; + extra_us = 1; + } + const int64_t candidate_next = next_deadline_us + base_interval_us + extra_us; + next_deadline_us = (candidate_next < now_us) ? now_us : candidate_next; - s_frame_inflight = true; - return &s_fb.uvc_fb; + s_frame_inflight = true; + return &s_fb.uvc_fb; } -static void UVCStreamHelpers::camera_fb_return_cb(uvc_fb_t *fb, void *cb_ctx) +static void UVCStreamHelpers::camera_fb_return_cb(uvc_fb_t* fb, void* cb_ctx) { - (void)cb_ctx; - assert(fb == &s_fb.uvc_fb); - if (s_fb.cam_fb_p) - { - esp_camera_fb_return(s_fb.cam_fb_p); - s_fb.cam_fb_p = nullptr; - } - s_frame_inflight = false; + (void)cb_ctx; + assert(fb == &s_fb.uvc_fb); + if (s_fb.cam_fb_p) + { + esp_camera_fb_return(s_fb.cam_fb_p); + s_fb.cam_fb_p = nullptr; + } + s_frame_inflight = false; } esp_err_t UVCStreamManager::setup() { - ESP_LOGI(UVC_STREAM_TAG, "Setting up UVC Stream"); - // Allocate a fixed-size transfer buffer (compile-time constant) - uvc_buffer_size = UVCStreamManager::UVC_MAX_FRAMESIZE_SIZE; - uvc_buffer = static_cast(malloc(uvc_buffer_size)); - if (uvc_buffer == nullptr) - { - ESP_LOGE(UVC_STREAM_TAG, "Allocating buffer for UVC Device failed"); - return ESP_FAIL; - } + ESP_LOGI(UVC_STREAM_TAG, "Setting up UVC Stream"); + // Allocate a fixed-size transfer buffer (compile-time constant) + uvc_buffer_size = UVCStreamManager::UVC_MAX_FRAMESIZE_SIZE; + uvc_buffer = static_cast(malloc(uvc_buffer_size)); + if (uvc_buffer == nullptr) + { + ESP_LOGE(UVC_STREAM_TAG, "Allocating buffer for UVC Device failed"); + return ESP_FAIL; + } - uvc_device_config_t config = { - .uvc_buffer = uvc_buffer, - .uvc_buffer_size = UVCStreamManager::UVC_MAX_FRAMESIZE_SIZE, - .start_cb = UVCStreamHelpers::camera_start_cb, - .fb_get_cb = UVCStreamHelpers::camera_fb_get_cb, - .fb_return_cb = UVCStreamHelpers::camera_fb_return_cb, - .stop_cb = UVCStreamHelpers::camera_stop_cb, - .cb_ctx = this, - }; + uvc_device_config_t config = { + .uvc_buffer = uvc_buffer, + .uvc_buffer_size = UVCStreamManager::UVC_MAX_FRAMESIZE_SIZE, + .start_cb = UVCStreamHelpers::camera_start_cb, + .fb_get_cb = UVCStreamHelpers::camera_fb_get_cb, + .fb_return_cb = UVCStreamHelpers::camera_fb_return_cb, + .stop_cb = UVCStreamHelpers::camera_stop_cb, + .cb_ctx = this, + }; - esp_err_t ret = uvc_device_config(0, &config); - if (ret != ESP_OK) - { - ESP_LOGE(UVC_STREAM_TAG, "Configuring UVC Device failed: %s", esp_err_to_name(ret)); - return ret; - } - ESP_LOGI(UVC_STREAM_TAG, "Configured UVC Device"); + esp_err_t ret = uvc_device_config(0, &config); + if (ret != ESP_OK) + { + ESP_LOGE(UVC_STREAM_TAG, "Configuring UVC Device failed: %s", esp_err_to_name(ret)); + return ret; + } + ESP_LOGI(UVC_STREAM_TAG, "Configured UVC Device"); - ESP_LOGI(UVC_STREAM_TAG, "Initializing UVC Device"); - ret = uvc_device_init(); - if (ret != ESP_OK) - { - ESP_LOGE(UVC_STREAM_TAG, "Initializing UVC Device failed: %s", esp_err_to_name(ret)); - return ret; - } - ESP_LOGI(UVC_STREAM_TAG, "Initialized UVC Device"); + ESP_LOGI(UVC_STREAM_TAG, "Initializing UVC Device"); + ret = uvc_device_init(); + if (ret != ESP_OK) + { + ESP_LOGE(UVC_STREAM_TAG, "Initializing UVC Device failed: %s", esp_err_to_name(ret)); + return ret; + } + ESP_LOGI(UVC_STREAM_TAG, "Initialized UVC Device"); - // Initial state is OFF - SendStreamEvent(eventQueue, StreamState_e::Stream_OFF); + // Initial state is OFF + SendStreamEvent(eventQueue, StreamState_e::Stream_OFF); - return ESP_OK; + return ESP_OK; } esp_err_t UVCStreamManager::start() { - ESP_LOGI(UVC_STREAM_TAG, "Starting UVC streaming"); - // UVC device is already initialized in setup(), just log that we're starting - return ESP_OK; + ESP_LOGI(UVC_STREAM_TAG, "Starting UVC streaming"); + // UVC device is already initialized in setup(), just log that we're starting + return ESP_OK; } #endif \ No newline at end of file diff --git a/components/UVCStream/UVCStream/UVCStream.hpp b/components/UVCStream/UVCStream/UVCStream.hpp index 46f3068..ab72387 100644 --- a/components/UVCStream/UVCStream/UVCStream.hpp +++ b/components/UVCStream/UVCStream/UVCStream.hpp @@ -5,15 +5,15 @@ #include "sdkconfig.h" #ifdef CONFIG_GENERAL_INCLUDE_UVC_MODE -#include "esp_timer.h" -#include "esp_mac.h" -#include "esp_camera.h" #include #include +#include "esp_camera.h" #include "esp_log.h" -#include "usb_device_uvc.h" +#include "esp_mac.h" +#include "esp_timer.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" +#include "usb_device_uvc.h" // we need access to the camera manager // in order to update the frame settings @@ -25,8 +25,8 @@ extern "C" { #endif - const char *get_uvc_device_name(); - const char *get_serial_number(void); + const char* get_uvc_device_name(); + const char* get_serial_number(void); #ifdef __cplusplus } @@ -37,33 +37,36 @@ extern QueueHandle_t eventQueue; namespace UVCStreamHelpers { - typedef struct - { - camera_fb_t *cam_fb_p; +typedef struct +{ + camera_fb_t* cam_fb_p; uvc_fb_t uvc_fb; - } fb_t; +} fb_t; - // single storage is defined in UVCStream.cpp - extern fb_t s_fb; +// single storage is defined in UVCStream.cpp +extern fb_t s_fb; - static esp_err_t camera_start_cb(uvc_format_t format, int width, int height, int rate, void *cb_ctx); - static void camera_stop_cb(void *cb_ctx); - static uvc_fb_t *camera_fb_get_cb(void *cb_ctx); - static void camera_fb_return_cb(uvc_fb_t *fb, void *cb_ctx); -} +static esp_err_t camera_start_cb(uvc_format_t format, int width, int height, int rate, void* cb_ctx); +static void camera_stop_cb(void* cb_ctx); +static uvc_fb_t* camera_fb_get_cb(void* cb_ctx); +static void camera_fb_return_cb(uvc_fb_t* fb, void* cb_ctx); +} // namespace UVCStreamHelpers class UVCStreamManager { - uint8_t *uvc_buffer = nullptr; - uint32_t uvc_buffer_size = 0; + uint8_t* uvc_buffer = nullptr; + uint32_t uvc_buffer_size = 0; -public: - // Compile-time buffer size; keep conservative headroom for MJPEG QVGA - static constexpr uint32_t UVC_MAX_FRAMESIZE_SIZE = 75 * 1024; - esp_err_t setup(); - esp_err_t start(); - uint32_t getUvcBufferSize() const { return uvc_buffer_size; } + public: + // Compile-time buffer size; keep conservative headroom for MJPEG QVGA + static constexpr uint32_t UVC_MAX_FRAMESIZE_SIZE = 75 * 1024; + esp_err_t setup(); + esp_err_t start(); + uint32_t getUvcBufferSize() const + { + return uvc_buffer_size; + } }; -#endif // UVCSTREAM_HPP +#endif // UVCSTREAM_HPP #endif \ No newline at end of file diff --git a/components/WebSocketLogger/WebSocketLogger/WebSocketLogger.cpp b/components/WebSocketLogger/WebSocketLogger/WebSocketLogger.cpp index 22e0b84..bff94ad 100644 --- a/components/WebSocketLogger/WebSocketLogger/WebSocketLogger.cpp +++ b/components/WebSocketLogger/WebSocketLogger/WebSocketLogger.cpp @@ -2,70 +2,70 @@ WebSocketLogger::WebSocketLogger() { - this->connected_socket_client = async_resp_arg{ - .hd = nullptr, - .fd = -1, - }; + this->connected_socket_client = async_resp_arg{ + .hd = nullptr, + .fd = -1, + }; - this->ws_log_buffer[0] = '\0'; + this->ws_log_buffer[0] = '\0'; } -void LoggerHelpers::ws_async_send(void *arg) +void LoggerHelpers::ws_async_send(void* arg) { - char *log_buffer = webSocketLogger.get_websocket_log_buffer(); + char* log_buffer = webSocketLogger.get_websocket_log_buffer(); - const auto *resp_arg = static_cast(arg); - const auto hd = resp_arg->hd; - const auto fd = resp_arg->fd; + const auto* resp_arg = static_cast(arg); + const auto hd = resp_arg->hd; + const auto fd = resp_arg->fd; - auto websocket_packet = httpd_ws_frame_t{}; + auto websocket_packet = httpd_ws_frame_t{}; - websocket_packet.payload = reinterpret_cast(log_buffer); - websocket_packet.len = strlen(log_buffer); - websocket_packet.type = HTTPD_WS_TYPE_TEXT; + websocket_packet.payload = reinterpret_cast(log_buffer); + websocket_packet.len = strlen(log_buffer); + websocket_packet.type = HTTPD_WS_TYPE_TEXT; - httpd_ws_send_frame_async(hd, fd, &websocket_packet); + httpd_ws_send_frame_async(hd, fd, &websocket_packet); } -esp_err_t WebSocketLogger::log_message(const char *format, va_list args) +esp_err_t WebSocketLogger::log_message(const char* format, va_list args) { - vsnprintf(this->ws_log_buffer, 100, format, args); + vsnprintf(this->ws_log_buffer, 100, format, args); - if (connected_socket_client.fd == -1 || connected_socket_client.hd == nullptr) - { - return ESP_FAIL; - } + if (connected_socket_client.fd == -1 || connected_socket_client.hd == nullptr) + { + return ESP_FAIL; + } - esp_err_t ret = httpd_queue_work(connected_socket_client.hd, LoggerHelpers::ws_async_send, &connected_socket_client); - if (ret != ESP_OK) - { - connected_socket_client.fd = -1; - connected_socket_client.hd = nullptr; - } + esp_err_t ret = httpd_queue_work(connected_socket_client.hd, LoggerHelpers::ws_async_send, &connected_socket_client); + if (ret != ESP_OK) + { + connected_socket_client.fd = -1; + connected_socket_client.hd = nullptr; + } - return ret; + return ret; } -esp_err_t WebSocketLogger::register_socket_client(httpd_req_t *req) +esp_err_t WebSocketLogger::register_socket_client(httpd_req_t* req) { - if (connected_socket_client.fd != -1 && connected_socket_client.hd != nullptr) - { - // we're already connected + if (connected_socket_client.fd != -1 && connected_socket_client.hd != nullptr) + { + // we're already connected + return ESP_OK; + } + + connected_socket_client.hd = req->handle; + connected_socket_client.fd = httpd_req_to_sockfd(req); return ESP_OK; - } - - connected_socket_client.hd = req->handle; - connected_socket_client.fd = httpd_req_to_sockfd(req); - return ESP_OK; } void WebSocketLogger::unregister_socket_client() { - connected_socket_client.fd = -1; - connected_socket_client.hd = nullptr; + connected_socket_client.fd = -1; + connected_socket_client.hd = nullptr; } -char *WebSocketLogger::get_websocket_log_buffer() +char* WebSocketLogger::get_websocket_log_buffer() { - return this->ws_log_buffer; + return this->ws_log_buffer; } \ No newline at end of file diff --git a/components/WebSocketLogger/WebSocketLogger/WebSocketLogger.hpp b/components/WebSocketLogger/WebSocketLogger/WebSocketLogger.hpp index 60c4348..812a98b 100644 --- a/components/WebSocketLogger/WebSocketLogger/WebSocketLogger.hpp +++ b/components/WebSocketLogger/WebSocketLogger/WebSocketLogger.hpp @@ -9,28 +9,28 @@ struct async_resp_arg { - httpd_handle_t hd; - int fd; + httpd_handle_t hd; + int fd; }; namespace LoggerHelpers { - void ws_async_send(void *arg); +void ws_async_send(void* arg); } class WebSocketLogger { - async_resp_arg connected_socket_client{}; - char ws_log_buffer[WS_LOG_BUFFER_LEN]{}; + async_resp_arg connected_socket_client{}; + char ws_log_buffer[WS_LOG_BUFFER_LEN]{}; -public: - WebSocketLogger(); + public: + WebSocketLogger(); - esp_err_t log_message(const char *format, va_list args); - esp_err_t register_socket_client(httpd_req_t *req); - void unregister_socket_client(); - bool is_client_connected(); - char *get_websocket_log_buffer(); + esp_err_t log_message(const char* format, va_list args); + esp_err_t register_socket_client(httpd_req_t* req); + void unregister_socket_client(); + bool is_client_connected(); + char* get_websocket_log_buffer(); }; extern WebSocketLogger webSocketLogger; diff --git a/components/openiris_logo/openiris_logo/openiris_logo.hpp b/components/openiris_logo/openiris_logo/openiris_logo.hpp index e926d95..b32a6ab 100644 --- a/components/openiris_logo/openiris_logo/openiris_logo.hpp +++ b/components/openiris_logo/openiris_logo/openiris_logo.hpp @@ -6,10 +6,10 @@ namespace Logo { - static const char *LOGO_TAG = "[LOGO]"; +static const char* LOGO_TAG = "[LOGO]"; - inline static void printASCII() - { +inline static void printASCII() +{ ESP_LOGI(LOGO_TAG, " : === WELCOME === TO === : "); ESP_LOGI(LOGO_TAG, " <===========================================================================================================================> "); ESP_LOGI(LOGO_TAG, " ██████╗ ██████╗ ███████╗███╗ ██╗██╗██████╗ ██╗███████╗ "); @@ -70,7 +70,7 @@ namespace Logo ESP_LOGI(LOGO_TAG, " ████████ "); ESP_LOGI(LOGO_TAG, " "); ESP_LOGI(LOGO_TAG, " <============================================================================================================================> "); - } -}; +} +}; // namespace Logo #endif \ No newline at end of file diff --git a/components/wifiManager/wifiManager/WiFiScanner.cpp b/components/wifiManager/wifiManager/WiFiScanner.cpp index 509b9a2..6e15663 100644 --- a/components/wifiManager/wifiManager/WiFiScanner.cpp +++ b/components/wifiManager/wifiManager/WiFiScanner.cpp @@ -2,14 +2,13 @@ #include #include "esp_timer.h" -static const char *TAG = "WiFiScanner"; +static const char* TAG = "WiFiScanner"; WiFiScanner::WiFiScanner() {} -void WiFiScanner::scanResultCallback(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) +void WiFiScanner::scanResultCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - auto *scanner = static_cast(arg); + auto* scanner = static_cast(arg); if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) { uint16_t ap_count = 0; @@ -21,14 +20,14 @@ void WiFiScanner::scanResultCallback(void *arg, esp_event_base_t event_base, return; } - wifi_ap_record_t *ap_records = new wifi_ap_record_t[ap_count]; + wifi_ap_record_t* ap_records = new wifi_ap_record_t[ap_count]; ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_count, ap_records)); scanner->networks.clear(); for (uint16_t i = 0; i < ap_count; i++) { WiFiNetwork network; - network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); + network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); network.channel = ap_records[i].primary; network.rssi = ap_records[i].rssi; memcpy(network.mac, ap_records[i].bssid, 6); @@ -63,7 +62,7 @@ std::vector WiFiScanner::scanNetworks(int timeout_ms) esp_wifi_scan_stop(); // Try sequential channel scanning as a workaround - bool try_sequential_scan = true; // Enable sequential scan + bool try_sequential_scan = true; // Enable sequential scan if (!try_sequential_scan) { @@ -71,17 +70,17 @@ std::vector WiFiScanner::scanNetworks(int timeout_ms) wifi_scan_config_t scan_config = { .ssid = nullptr, .bssid = nullptr, - .channel = 0, // 0 means scan all channels + .channel = 0, // 0 means scan all channels .show_hidden = true, - .scan_type = WIFI_SCAN_TYPE_ACTIVE, // Active scan - .scan_time = { - .active = { - .min = 120, // Min per channel - .max = 300 // Max per channel - }, - .passive = 360}, - .home_chan_dwell_time = 0, // 0 for default - .channel_bitmap = 0 // 0 for all channels + .scan_type = WIFI_SCAN_TYPE_ACTIVE, // Active scan + .scan_time = {.active = + { + .min = 120, // Min per channel + .max = 300 // Max per channel + }, + .passive = 360}, + .home_chan_dwell_time = 0, // 0 for default + .channel_bitmap = 0 // 0 for all channels }; err = esp_wifi_scan_start(&scan_config, false); @@ -95,7 +94,7 @@ std::vector WiFiScanner::scanNetworks(int timeout_ms) { // Sequential channel scan - scan each channel individually with timeout tracking std::vector all_records; - int64_t start_time = esp_timer_get_time() / 1000; // Convert to ms + int64_t start_time = esp_timer_get_time() / 1000; // Convert to ms for (uint8_t ch = 1; ch <= 13; ch++) { @@ -109,28 +108,23 @@ std::vector WiFiScanner::scanNetworks(int timeout_ms) break; } - wifi_scan_config_t scan_config = { - .ssid = nullptr, - .bssid = nullptr, - .channel = ch, - .show_hidden = true, - .scan_type = WIFI_SCAN_TYPE_ACTIVE, - .scan_time = { - .active = { - .min = 100, - .max = 200}, - .passive = 300}, - .home_chan_dwell_time = 0, - .channel_bitmap = 0}; + wifi_scan_config_t scan_config = {.ssid = nullptr, + .bssid = nullptr, + .channel = ch, + .show_hidden = true, + .scan_type = WIFI_SCAN_TYPE_ACTIVE, + .scan_time = {.active = {.min = 100, .max = 200}, .passive = 300}, + .home_chan_dwell_time = 0, + .channel_bitmap = 0}; - err = esp_wifi_scan_start(&scan_config, true); // Blocking scan + err = esp_wifi_scan_start(&scan_config, true); // Blocking scan if (err == ESP_OK) { uint16_t ch_count = 0; esp_wifi_scan_get_ap_num(&ch_count); if (ch_count > 0) { - wifi_ap_record_t *ch_records = new wifi_ap_record_t[ch_count]; + wifi_ap_record_t* ch_records = new wifi_ap_record_t[ch_count]; if (esp_wifi_scan_get_ap_records(&ch_count, ch_records) == ESP_OK) { for (uint16_t i = 0; i < ch_count; i++) @@ -145,10 +139,10 @@ std::vector WiFiScanner::scanNetworks(int timeout_ms) } // Process all collected records - for (const auto &record : all_records) + for (const auto& record : all_records) { WiFiNetwork network; - network.ssid = std::string(reinterpret_cast(record.ssid)); + network.ssid = std::string(reinterpret_cast(record.ssid)); network.channel = record.primary; network.rssi = record.rssi; memcpy(network.mac, record.bssid, 6); @@ -164,7 +158,7 @@ std::vector WiFiScanner::scanNetworks(int timeout_ms) } // Wait for scan completion with timeout - int64_t start_time = esp_timer_get_time() / 1000; // Convert to ms + int64_t start_time = esp_timer_get_time() / 1000; // Convert to ms int64_t elapsed_ms = 0; bool scan_done = false; @@ -206,7 +200,7 @@ std::vector WiFiScanner::scanNetworks(int timeout_ms) return scan_results; } - wifi_ap_record_t *ap_records = new wifi_ap_record_t[ap_count]; + wifi_ap_record_t* ap_records = new wifi_ap_record_t[ap_count]; err = esp_wifi_scan_get_ap_records(&ap_count, ap_records); if (err != ESP_OK) { @@ -216,12 +210,12 @@ std::vector WiFiScanner::scanNetworks(int timeout_ms) } // Build the results vector and track channels found - bool channels_found[15] = {false}; // Track channels 0-14 + bool channels_found[15] = {false}; // Track channels 0-14 for (uint16_t i = 0; i < ap_count; i++) { WiFiNetwork network; - network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); + network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); network.channel = ap_records[i].primary; network.rssi = ap_records[i].rssi; memcpy(network.mac, ap_records[i].bssid, 6); diff --git a/components/wifiManager/wifiManager/WiFiScanner.hpp b/components/wifiManager/wifiManager/WiFiScanner.hpp index 16902a7..837c551 100644 --- a/components/wifiManager/wifiManager/WiFiScanner.hpp +++ b/components/wifiManager/wifiManager/WiFiScanner.hpp @@ -2,10 +2,10 @@ #ifndef WIFI_SCANNER_HPP #define WIFI_SCANNER_HPP -#include #include -#include "esp_wifi.h" +#include #include "esp_log.h" +#include "esp_wifi.h" struct WiFiNetwork { @@ -18,12 +18,12 @@ struct WiFiNetwork class WiFiScanner { -public: + public: WiFiScanner(); std::vector scanNetworks(int timeout_ms = 15000); - static void scanResultCallback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); + static void scanResultCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); -private: + private: std::vector networks; }; diff --git a/components/wifiManager/wifiManager/wifiManager.cpp b/components/wifiManager/wifiManager/wifiManager.cpp index b5ceb6c..8886a93 100644 --- a/components/wifiManager/wifiManager/wifiManager.cpp +++ b/components/wifiManager/wifiManager/wifiManager.cpp @@ -5,409 +5,392 @@ static auto WIFI_MANAGER_TAG = "[WIFI_MANAGER]"; int s_retry_num = 0; EventGroupHandle_t s_wifi_event_group; -void WiFiManagerHelpers::event_handler(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) +void WiFiManagerHelpers::event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - ESP_LOGI(WIFI_MANAGER_TAG, "Trying to connect, got event: %d", (int)event_id); - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) - { - if (const auto err = esp_wifi_connect(); err != ESP_OK) + ESP_LOGI(WIFI_MANAGER_TAG, "Trying to connect, got event: %d", (int)event_id); + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - ESP_LOGI(WIFI_MANAGER_TAG, "esp_wifi_connect() failed: %s", esp_err_to_name(err)); + if (const auto err = esp_wifi_connect(); err != ESP_OK) + { + ESP_LOGI(WIFI_MANAGER_TAG, "esp_wifi_connect() failed: %s", esp_err_to_name(err)); + } } - } - else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) - { - const auto *disconnected = static_cast(event_data); - ESP_LOGI(WIFI_MANAGER_TAG, "Disconnect reason: %d", disconnected->reason); - - if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) + else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - esp_wifi_connect(); - s_retry_num++; - ESP_LOGI(WIFI_MANAGER_TAG, "retry to connect to the AP"); + const auto* disconnected = static_cast(event_data); + ESP_LOGI(WIFI_MANAGER_TAG, "Disconnect reason: %d", disconnected->reason); + + if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) + { + esp_wifi_connect(); + s_retry_num++; + ESP_LOGI(WIFI_MANAGER_TAG, "retry to connect to the AP"); + } + else + { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + ESP_LOGI(WIFI_MANAGER_TAG, "connect to the AP fail"); + } + + else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) + { + const auto* event = static_cast(event_data); + ESP_LOGI(WIFI_MANAGER_TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } +} + +WiFiManager::WiFiManager(std::shared_ptr deviceConfig, QueueHandle_t eventQueue, StateManager* stateManager) + : deviceConfig(deviceConfig), eventQueue(eventQueue), stateManager(stateManager), wifiScanner(std::make_unique()) +{ +} + +void WiFiManager::SetCredentials(const char* ssid, const char* password) +{ + // Clear the config first + memset(&_wifi_cfg, 0, sizeof(_wifi_cfg)); + + // Copy SSID with null termination + size_t ssid_len = std::min(strlen(ssid), sizeof(_wifi_cfg.sta.ssid) - 1); + memcpy(_wifi_cfg.sta.ssid, ssid, ssid_len); + _wifi_cfg.sta.ssid[ssid_len] = '\0'; + + // Copy password with null termination + size_t pass_len = std::min(strlen(password), sizeof(_wifi_cfg.sta.password) - 1); + memcpy(_wifi_cfg.sta.password, password, pass_len); + _wifi_cfg.sta.password[pass_len] = '\0'; + + // Set other required fields + // Use open auth if no password, otherwise allow any WPA variant + if (strlen(password) == 0) + { + _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; } else { - xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + // IMPORTANT: Set threshold to WEP to accept ANY security mode >= WEP + // This allows WPA, WPA2, WPA3, etc. The driver will negotiate the highest common mode + _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WEP; } - ESP_LOGI(WIFI_MANAGER_TAG, "connect to the AP fail"); - } - else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) - { - const auto *event = static_cast(event_data); - ESP_LOGI(WIFI_MANAGER_TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); - s_retry_num = 0; - xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); - } -} + // CRITICAL: Disable PMF completely - this often causes handshake timeouts + _wifi_cfg.sta.pmf_cfg.capable = false; + _wifi_cfg.sta.pmf_cfg.required = false; -WiFiManager::WiFiManager(std::shared_ptr deviceConfig, QueueHandle_t eventQueue, StateManager *stateManager) - : deviceConfig(deviceConfig), eventQueue(eventQueue), stateManager(stateManager), wifiScanner(std::make_unique()) {} + // OPTIMIZATION: Use fast scan instead of all channel scan for quicker connection + _wifi_cfg.sta.scan_method = WIFI_FAST_SCAN; + _wifi_cfg.sta.bssid_set = 0; // Don't use specific BSSID + _wifi_cfg.sta.channel = 0; // Auto channel detection -void WiFiManager::SetCredentials(const char *ssid, const char *password) -{ - // Clear the config first - memset(&_wifi_cfg, 0, sizeof(_wifi_cfg)); + // Additional settings that might help with compatibility + _wifi_cfg.sta.listen_interval = 0; // Default listen interval + _wifi_cfg.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL; // Connect to strongest signal - // Copy SSID with null termination - size_t ssid_len = std::min(strlen(ssid), sizeof(_wifi_cfg.sta.ssid) - 1); - memcpy(_wifi_cfg.sta.ssid, ssid, ssid_len); - _wifi_cfg.sta.ssid[ssid_len] = '\0'; + // IMPORTANT: For WPA/WPA2 Personal networks + _wifi_cfg.sta.threshold.rssi = -127; // Accept any signal strength + _wifi_cfg.sta.sae_pwe_h2e = WPA3_SAE_PWE_UNSPECIFIED; // Let driver decide SAE mode - // Copy password with null termination - size_t pass_len = std::min(strlen(password), sizeof(_wifi_cfg.sta.password) - 1); - memcpy(_wifi_cfg.sta.password, password, pass_len); - _wifi_cfg.sta.password[pass_len] = '\0'; - - // Set other required fields - // Use open auth if no password, otherwise allow any WPA variant - if (strlen(password) == 0) - { - _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; - } - else - { - // IMPORTANT: Set threshold to WEP to accept ANY security mode >= WEP - // This allows WPA, WPA2, WPA3, etc. The driver will negotiate the highest common mode - _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WEP; - } - - // CRITICAL: Disable PMF completely - this often causes handshake timeouts - _wifi_cfg.sta.pmf_cfg.capable = false; - _wifi_cfg.sta.pmf_cfg.required = false; - - // OPTIMIZATION: Use fast scan instead of all channel scan for quicker connection - _wifi_cfg.sta.scan_method = WIFI_FAST_SCAN; - _wifi_cfg.sta.bssid_set = 0; // Don't use specific BSSID - _wifi_cfg.sta.channel = 0; // Auto channel detection - - // Additional settings that might help with compatibility - _wifi_cfg.sta.listen_interval = 0; // Default listen interval - _wifi_cfg.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL; // Connect to strongest signal - - // IMPORTANT: For WPA/WPA2 Personal networks - _wifi_cfg.sta.threshold.rssi = -127; // Accept any signal strength - _wifi_cfg.sta.sae_pwe_h2e = WPA3_SAE_PWE_UNSPECIFIED; // Let driver decide SAE mode - - // Log what we're trying to connect to with detailed debugging - ESP_LOGI(WIFI_MANAGER_TAG, "Setting credentials for SSID: '%s' (length: %d)", ssid, (int)strlen(ssid)); - ESP_LOGI(WIFI_MANAGER_TAG, "Password: '%s' (length: %d)", password, (int)strlen(password)); - ESP_LOGI(WIFI_MANAGER_TAG, "Auth mode: %d, PMF capable: %d", - _wifi_cfg.sta.threshold.authmode, _wifi_cfg.sta.pmf_cfg.capable); + // Log what we're trying to connect to with detailed debugging + ESP_LOGI(WIFI_MANAGER_TAG, "Setting credentials for SSID: '%s' (length: %d)", ssid, (int)strlen(ssid)); + ESP_LOGI(WIFI_MANAGER_TAG, "Password: '%s' (length: %d)", password, (int)strlen(password)); + ESP_LOGI(WIFI_MANAGER_TAG, "Auth mode: %d, PMF capable: %d", _wifi_cfg.sta.threshold.authmode, _wifi_cfg.sta.pmf_cfg.capable); } void WiFiManager::ConnectWithHardcodedCredentials() { - SystemEvent event = {EventSource::WIFI, WiFiState_e::WiFiState_ReadyToConnect}; - this->SetCredentials(CONFIG_WIFI_SSID, CONFIG_WIFI_PASSWORD); + SystemEvent event = {EventSource::WIFI, WiFiState_e::WiFiState_ReadyToConnect}; + this->SetCredentials(CONFIG_WIFI_SSID, CONFIG_WIFI_PASSWORD); - wifi_mode_t mode; - if (esp_wifi_get_mode(&mode) == ESP_OK) { - esp_wifi_stop(); - } - - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &_wifi_cfg)); - - xQueueSend(this->eventQueue, &event, 10); - esp_wifi_start(); - - event.value = WiFiState_e::WiFiState_Connecting; - xQueueSend(this->eventQueue, &event, 10); - - // Use shorter timeout for faster startup - 8 seconds should be enough for most networks - EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, - WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, - pdFALSE, - pdFALSE, - pdMS_TO_TICKS(8000)); - - /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually - * happened. */ - if (bits & WIFI_CONNECTED_BIT) - { - ESP_LOGI(WIFI_MANAGER_TAG, "connected to ap SSID:%p password:%p", - _wifi_cfg.sta.ssid, _wifi_cfg.sta.password); - - event.value = WiFiState_e::WiFiState_Connected; - xQueueSend(this->eventQueue, &event, 10); - } - - else if (bits & WIFI_FAIL_BIT) - { - ESP_LOGE(WIFI_MANAGER_TAG, "Failed to connect to SSID:%p, password:%p", - _wifi_cfg.sta.ssid, _wifi_cfg.sta.password); - - event.value = WiFiState_e::WiFiState_Error; - xQueueSend(this->eventQueue, &event, 10); - } - else - { - ESP_LOGE(WIFI_MANAGER_TAG, "UNEXPECTED EVENT"); - } -} - -void WiFiManager::ConnectWithStoredCredentials() -{ - SystemEvent event = {EventSource::WIFI, WiFiState_e::WiFiState_ReadyToConnect}; - - auto const networks = this->deviceConfig->getWifiConfigs(); - - if (networks.empty()) - { - event.value = WiFiState_e::WiFiState_Disconnected; - xQueueSend(this->eventQueue, &event, 10); - ESP_LOGE(WIFI_MANAGER_TAG, "No networks stored, cannot connect"); - return; - } - - // Stop WiFi once before the loop - esp_wifi_stop(); - vTaskDelay(pdMS_TO_TICKS(100)); - - // Ensure we're in STA mode - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - - for (const auto &network : networks) - { - // Reset retry counter for each network attempt - s_retry_num = 0; - xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_CONNECTED_BIT); - this->SetCredentials(network.ssid.c_str(), network.password.c_str()); - - // Update config without stopping WiFi again - ESP_LOGI(WIFI_MANAGER_TAG, "Attempting to connect to SSID: '%s'", network.ssid.c_str()); - - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &_wifi_cfg)); - xQueueSend(this->eventQueue, &event, 10); - - // Start WiFi if not already started - esp_err_t start_err = esp_wifi_start(); - if (start_err != ESP_OK && start_err != ESP_ERR_WIFI_STATE) + wifi_mode_t mode; + if (esp_wifi_get_mode(&mode) == ESP_OK) { - ESP_LOGE(WIFI_MANAGER_TAG, "Failed to start WiFi: %s", esp_err_to_name(start_err)); - continue; + esp_wifi_stop(); } + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &_wifi_cfg)); + + xQueueSend(this->eventQueue, &event, 10); + esp_wifi_start(); + event.value = WiFiState_e::WiFiState_Connecting; xQueueSend(this->eventQueue, &event, 10); - EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, - WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, - pdFALSE, - pdFALSE, - pdMS_TO_TICKS(10000)); // 10 second timeout for faster failover + // Use shorter timeout for faster startup - 8 seconds should be enough for most networks + EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, pdMS_TO_TICKS(8000)); + + /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually + * happened. */ if (bits & WIFI_CONNECTED_BIT) { - ESP_LOGI(WIFI_MANAGER_TAG, "connected to ap SSID:%s", - network.ssid.c_str()); + ESP_LOGI(WIFI_MANAGER_TAG, "connected to ap SSID:%p password:%p", _wifi_cfg.sta.ssid, _wifi_cfg.sta.password); - event.value = WiFiState_e::WiFiState_Connected; - xQueueSend(this->eventQueue, &event, 10); - - return; + event.value = WiFiState_e::WiFiState_Connected; + xQueueSend(this->eventQueue, &event, 10); } - ESP_LOGE(WIFI_MANAGER_TAG, "Failed to connect to SSID:%s, trying next stored network", - network.ssid.c_str()); - // Disconnect before trying next network - esp_wifi_disconnect(); + else if (bits & WIFI_FAIL_BIT) + { + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to connect to SSID:%p, password:%p", _wifi_cfg.sta.ssid, _wifi_cfg.sta.password); + + event.value = WiFiState_e::WiFiState_Error; + xQueueSend(this->eventQueue, &event, 10); + } + else + { + ESP_LOGE(WIFI_MANAGER_TAG, "UNEXPECTED EVENT"); + } +} + +void WiFiManager::ConnectWithStoredCredentials() +{ + SystemEvent event = {EventSource::WIFI, WiFiState_e::WiFiState_ReadyToConnect}; + + auto const networks = this->deviceConfig->getWifiConfigs(); + + if (networks.empty()) + { + event.value = WiFiState_e::WiFiState_Disconnected; + xQueueSend(this->eventQueue, &event, 10); + ESP_LOGE(WIFI_MANAGER_TAG, "No networks stored, cannot connect"); + return; + } + + // Stop WiFi once before the loop + esp_wifi_stop(); vTaskDelay(pdMS_TO_TICKS(100)); - } - event.value = WiFiState_e::WiFiState_Error; - xQueueSend(this->eventQueue, &event, 10); - ESP_LOGE(WIFI_MANAGER_TAG, "Failed to connect to all saved networks"); + // Ensure we're in STA mode + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + + for (const auto& network : networks) + { + // Reset retry counter for each network attempt + s_retry_num = 0; + xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_CONNECTED_BIT); + this->SetCredentials(network.ssid.c_str(), network.password.c_str()); + + // Update config without stopping WiFi again + ESP_LOGI(WIFI_MANAGER_TAG, "Attempting to connect to SSID: '%s'", network.ssid.c_str()); + + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &_wifi_cfg)); + xQueueSend(this->eventQueue, &event, 10); + + // Start WiFi if not already started + esp_err_t start_err = esp_wifi_start(); + if (start_err != ESP_OK && start_err != ESP_ERR_WIFI_STATE) + { + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to start WiFi: %s", esp_err_to_name(start_err)); + continue; + } + + event.value = WiFiState_e::WiFiState_Connecting; + xQueueSend(this->eventQueue, &event, 10); + + EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, + pdMS_TO_TICKS(10000)); // 10 second timeout for faster failover + if (bits & WIFI_CONNECTED_BIT) + { + ESP_LOGI(WIFI_MANAGER_TAG, "connected to ap SSID:%s", network.ssid.c_str()); + + event.value = WiFiState_e::WiFiState_Connected; + xQueueSend(this->eventQueue, &event, 10); + + return; + } + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to connect to SSID:%s, trying next stored network", network.ssid.c_str()); + + // Disconnect before trying next network + esp_wifi_disconnect(); + vTaskDelay(pdMS_TO_TICKS(100)); + } + + event.value = WiFiState_e::WiFiState_Error; + xQueueSend(this->eventQueue, &event, 10); + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to connect to all saved networks"); } void WiFiManager::SetupAccessPoint() { - ESP_LOGI(WIFI_MANAGER_TAG, "Connection to stored credentials failed, starting AP"); + ESP_LOGI(WIFI_MANAGER_TAG, "Connection to stored credentials failed, starting AP"); - esp_netif_create_default_wifi_ap(); - wifi_init_config_t esp_wifi_ap_init_config = WIFI_INIT_CONFIG_DEFAULT(); + esp_netif_create_default_wifi_ap(); + wifi_init_config_t esp_wifi_ap_init_config = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&esp_wifi_ap_init_config)); + ESP_ERROR_CHECK(esp_wifi_init(&esp_wifi_ap_init_config)); - wifi_config_t ap_wifi_config = { - .ap = { - .ssid = CONFIG_WIFI_AP_SSID, - .password = CONFIG_WIFI_AP_PASSWORD, - .max_connection = 1, + wifi_config_t ap_wifi_config = { + .ap = + { + .ssid = CONFIG_WIFI_AP_SSID, + .password = CONFIG_WIFI_AP_PASSWORD, + .max_connection = 1, - }, - }; + }, + }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(WIFI_MANAGER_TAG, "AP started."); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + ESP_LOGI(WIFI_MANAGER_TAG, "AP started."); } std::vector WiFiManager::ScanNetworks(int timeout_ms) { - wifi_mode_t current_mode; - esp_err_t err = esp_wifi_get_mode(¤t_mode); + wifi_mode_t current_mode; + esp_err_t err = esp_wifi_get_mode(¤t_mode); - if (err == ESP_ERR_WIFI_NOT_INIT) - { - ESP_LOGE(WIFI_MANAGER_TAG, "WiFi not initialized for scanning"); - return std::vector(); - } - - // If we're in AP-only mode, we need STA interface for scanning - if (current_mode == WIFI_MODE_AP) - { - ESP_LOGI(WIFI_MANAGER_TAG, "AP mode detected, checking for STA interface"); - - // Check if STA netif already exists - esp_netif_t *sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); - bool sta_netif_exists = (sta_netif != nullptr); - - if (!sta_netif_exists) + if (err == ESP_ERR_WIFI_NOT_INIT) { - ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface for scanning"); - sta_netif = esp_netif_create_default_wifi_sta(); + ESP_LOGE(WIFI_MANAGER_TAG, "WiFi not initialized for scanning"); + return std::vector(); } - ESP_LOGI(WIFI_MANAGER_TAG, "Switching to APSTA mode for scanning"); - err = esp_wifi_set_mode(WIFI_MODE_APSTA); - if (err != ESP_OK) + // If we're in AP-only mode, we need STA interface for scanning + if (current_mode == WIFI_MODE_AP) { - ESP_LOGE(WIFI_MANAGER_TAG, "Failed to set APSTA mode: %s", esp_err_to_name(err)); - if (!sta_netif_exists && sta_netif) - { - esp_netif_destroy(sta_netif); - } - return std::vector(); + ESP_LOGI(WIFI_MANAGER_TAG, "AP mode detected, checking for STA interface"); + + // Check if STA netif already exists + esp_netif_t* sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + bool sta_netif_exists = (sta_netif != nullptr); + + if (!sta_netif_exists) + { + ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface for scanning"); + sta_netif = esp_netif_create_default_wifi_sta(); + } + + ESP_LOGI(WIFI_MANAGER_TAG, "Switching to APSTA mode for scanning"); + err = esp_wifi_set_mode(WIFI_MODE_APSTA); + if (err != ESP_OK) + { + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to set APSTA mode: %s", esp_err_to_name(err)); + if (!sta_netif_exists && sta_netif) + { + esp_netif_destroy(sta_netif); + } + return std::vector(); + } + + // Configure STA with empty config to prevent auto-connect + wifi_config_t empty_config = {}; + esp_wifi_set_config(WIFI_IF_STA, &empty_config); + + // Ensure STA is disconnected and not trying to connect + esp_wifi_disconnect(); + // Longer delay for mode to stabilize and enable all channels + vTaskDelay(pdMS_TO_TICKS(2000)); + + // Perform scan + auto networks = wifiScanner->scanNetworks(timeout_ms); + + // Restore AP-only mode + ESP_LOGI(WIFI_MANAGER_TAG, "Restoring AP-only mode"); + esp_wifi_set_mode(WIFI_MODE_AP); + + // Clean up STA interface if we created it + if (!sta_netif_exists && sta_netif) + { + esp_netif_destroy(sta_netif); + } + + return networks; } - // Configure STA with empty config to prevent auto-connect - wifi_config_t empty_config = {}; - esp_wifi_set_config(WIFI_IF_STA, &empty_config); - - // Ensure STA is disconnected and not trying to connect - esp_wifi_disconnect(); - // Longer delay for mode to stabilize and enable all channels - vTaskDelay(pdMS_TO_TICKS(2000)); - - // Perform scan - auto networks = wifiScanner->scanNetworks(timeout_ms); - - // Restore AP-only mode - ESP_LOGI(WIFI_MANAGER_TAG, "Restoring AP-only mode"); - esp_wifi_set_mode(WIFI_MODE_AP); - - // Clean up STA interface if we created it - if (!sta_netif_exists && sta_netif) - { - esp_netif_destroy(sta_netif); - } - - return networks; - } - - // If already in STA or APSTA mode, scan directly - return wifiScanner->scanNetworks(timeout_ms); + // If already in STA or APSTA mode, scan directly + return wifiScanner->scanNetworks(timeout_ms); } WiFiState_e WiFiManager::GetCurrentWiFiState() { - return this->stateManager->GetWifiState(); + return this->stateManager->GetWifiState(); } void WiFiManager::TryConnectToStoredNetworks() { - ESP_LOGI(WIFI_MANAGER_TAG, "Manual WiFi connection attempt requested"); + ESP_LOGI(WIFI_MANAGER_TAG, "Manual WiFi connection attempt requested"); - // Check current WiFi mode - wifi_mode_t current_mode; - esp_err_t err = esp_wifi_get_mode(¤t_mode); - if (err != ESP_OK) - { - ESP_LOGE(WIFI_MANAGER_TAG, "Failed to get WiFi mode: %s", esp_err_to_name(err)); - return; - } - - // If in AP mode, we need to properly transition to STA mode - if (current_mode == WIFI_MODE_AP || current_mode == WIFI_MODE_APSTA) - { - ESP_LOGI(WIFI_MANAGER_TAG, "Currently in AP mode, transitioning to STA mode"); - - // Stop WiFi first - esp_wifi_stop(); - vTaskDelay(pdMS_TO_TICKS(100)); - - // Check if STA interface exists, create if needed - esp_netif_t *sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); - if (sta_netif == nullptr) + // Check current WiFi mode + wifi_mode_t current_mode; + esp_err_t err = esp_wifi_get_mode(¤t_mode); + if (err != ESP_OK) { - ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface"); - sta_netif = esp_netif_create_default_wifi_sta(); + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to get WiFi mode: %s", esp_err_to_name(err)); + return; } - // Set to STA mode - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - vTaskDelay(pdMS_TO_TICKS(100)); - } + // If in AP mode, we need to properly transition to STA mode + if (current_mode == WIFI_MODE_AP || current_mode == WIFI_MODE_APSTA) + { + ESP_LOGI(WIFI_MANAGER_TAG, "Currently in AP mode, transitioning to STA mode"); - // Reset retry counter and clear all event bits - s_retry_num = 0; - xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_CONNECTED_BIT); - this->ConnectWithStoredCredentials(); + // Stop WiFi first + esp_wifi_stop(); + vTaskDelay(pdMS_TO_TICKS(100)); + + // Check if STA interface exists, create if needed + esp_netif_t* sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + if (sta_netif == nullptr) + { + ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface"); + sta_netif = esp_netif_create_default_wifi_sta(); + } + + // Set to STA mode + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + vTaskDelay(pdMS_TO_TICKS(100)); + } + + // Reset retry counter and clear all event bits + s_retry_num = 0; + xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_CONNECTED_BIT); + this->ConnectWithStoredCredentials(); } void WiFiManager::Begin() { - s_wifi_event_group = xEventGroupCreate(); + s_wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_netif_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - auto netif = esp_netif_create_default_wifi_sta(); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + auto netif = esp_netif_create_default_wifi_sta(); - wifi_init_config_t esp_wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&esp_wifi_init_config)); + wifi_init_config_t esp_wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&esp_wifi_init_config)); - ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, - ESP_EVENT_ANY_ID, - &WiFiManagerHelpers::event_handler, - nullptr, - &instance_any_id)); - ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, - IP_EVENT_STA_GOT_IP, - &WiFiManagerHelpers::event_handler, - nullptr, - &instance_got_ip)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &WiFiManagerHelpers::event_handler, nullptr, &instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &WiFiManagerHelpers::event_handler, nullptr, &instance_got_ip)); - _wifi_cfg = {}; - _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; // Start with open, will be set properly by SetCredentials - _wifi_cfg.sta.pmf_cfg.capable = false; // Disable PMF by default - _wifi_cfg.sta.pmf_cfg.required = false; + _wifi_cfg = {}; + _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; // Start with open, will be set properly by SetCredentials + _wifi_cfg.sta.pmf_cfg.capable = false; // Disable PMF by default + _wifi_cfg.sta.pmf_cfg.required = false; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_LOGI(WIFI_MANAGER_TAG, "Beginning setup"); - const auto hasHardcodedCredentials = strlen(CONFIG_WIFI_SSID) > 0; - if (hasHardcodedCredentials) - { - ESP_LOGI(WIFI_MANAGER_TAG, "Detected hardcoded credentials, trying them out"); - this->ConnectWithHardcodedCredentials(); - } + ESP_LOGI(WIFI_MANAGER_TAG, "Beginning setup"); + const auto hasHardcodedCredentials = strlen(CONFIG_WIFI_SSID) > 0; + if (hasHardcodedCredentials) + { + ESP_LOGI(WIFI_MANAGER_TAG, "Detected hardcoded credentials, trying them out"); + this->ConnectWithHardcodedCredentials(); + } - if (this->stateManager->GetWifiState() != WiFiState_e::WiFiState_Connected || !hasHardcodedCredentials) - { - ESP_LOGI(WIFI_MANAGER_TAG, "Hardcoded credentials failed or missing, trying stored credentials"); - xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT); - this->ConnectWithStoredCredentials(); - } + if (this->stateManager->GetWifiState() != WiFiState_e::WiFiState_Connected || !hasHardcodedCredentials) + { + ESP_LOGI(WIFI_MANAGER_TAG, "Hardcoded credentials failed or missing, trying stored credentials"); + xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT); + this->ConnectWithStoredCredentials(); + } - if (this->stateManager->GetWifiState() != WiFiState_e::WiFiState_Connected) - { - ESP_LOGI(WIFI_MANAGER_TAG, "Stored netoworks failed or hardcoded credentials missing, starting AP"); - xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT); - esp_netif_destroy(netif); - this->SetupAccessPoint(); - } + if (this->stateManager->GetWifiState() != WiFiState_e::WiFiState_Connected) + { + ESP_LOGI(WIFI_MANAGER_TAG, "Stored netoworks failed or hardcoded credentials missing, starting AP"); + xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT); + esp_netif_destroy(netif); + this->SetupAccessPoint(); + } } diff --git a/components/wifiManager/wifiManager/wifiManager.hpp b/components/wifiManager/wifiManager/wifiManager.hpp index 6fef805..d819364 100644 --- a/components/wifiManager/wifiManager/wifiManager.hpp +++ b/components/wifiManager/wifiManager/wifiManager.hpp @@ -2,16 +2,16 @@ #ifndef WIFIHANDLER_HPP #define WIFIHANDLER_HPP -#include -#include -#include -#include #include +#include +#include +#include +#include #include "WiFiScanner.hpp" #include "esp_event.h" -#include "esp_wifi.h" #include "esp_log.h" +#include "esp_wifi.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -21,37 +21,36 @@ namespace WiFiManagerHelpers { - void event_handler(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data); +void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); } class WiFiManager { -private: - uint8_t channel; - std::shared_ptr deviceConfig; - QueueHandle_t eventQueue; - StateManager *stateManager; - wifi_init_config_t _wifi_init_cfg = WIFI_INIT_CONFIG_DEFAULT(); - wifi_config_t _wifi_cfg = {}; - std::unique_ptr wifiScanner; + private: + uint8_t channel; + std::shared_ptr deviceConfig; + QueueHandle_t eventQueue; + StateManager* stateManager; + wifi_init_config_t _wifi_init_cfg = WIFI_INIT_CONFIG_DEFAULT(); + wifi_config_t _wifi_cfg = {}; + std::unique_ptr wifiScanner; - esp_event_handler_instance_t instance_any_id; - esp_event_handler_instance_t instance_got_ip; + esp_event_handler_instance_t instance_any_id; + esp_event_handler_instance_t instance_got_ip; - int8_t power; + int8_t power; - void SetCredentials(const char *ssid, const char *password); - void ConnectWithHardcodedCredentials(); - void ConnectWithStoredCredentials(); - void SetupAccessPoint(); + void SetCredentials(const char* ssid, const char* password); + void ConnectWithHardcodedCredentials(); + void ConnectWithStoredCredentials(); + void SetupAccessPoint(); -public: - WiFiManager(std::shared_ptr deviceConfig, QueueHandle_t eventQueue, StateManager *stateManager); - void Begin(); - std::vector ScanNetworks(int timeout_ms = 15000); - WiFiState_e GetCurrentWiFiState(); - void TryConnectToStoredNetworks(); + public: + WiFiManager(std::shared_ptr deviceConfig, QueueHandle_t eventQueue, StateManager* stateManager); + void Begin(); + std::vector ScanNetworks(int timeout_ms = 15000); + WiFiState_e GetCurrentWiFiState(); + void TryConnectToStoredNetworks(); }; #endif \ No newline at end of file diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index fb9a945..8975d1d 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -1,27 +1,27 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" #include "driver/gpio.h" #include "esp_log.h" #include "esp_timer.h" -#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" #include "nvs_flash.h" +#include "sdkconfig.h" -#include -#include -#include -#include +#include +#include #include #include -#include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include #include +#include +#include #if CONFIG_MONITORING_LED_CURRENT || CONFIG_MONITORING_BATTERY_ENABLE #include @@ -50,7 +50,7 @@ QueueHandle_t eventQueue = xQueueCreate(10, sizeof(SystemEvent)); QueueHandle_t ledStateQueue = xQueueCreate(10, sizeof(uint32_t)); QueueHandle_t cdcMessageQueue = xQueueCreate(3, sizeof(cdc_command_packet_t)); -auto *stateManager = new StateManager(eventQueue, ledStateQueue); +auto* stateManager = new StateManager(eventQueue, ledStateQueue); auto dependencyRegistry = std::make_shared(); auto commandManager = std::make_shared(dependencyRegistry); @@ -76,7 +76,7 @@ auto ledManager = std::make_shared(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO std::shared_ptr monitoringManager = std::make_shared(); #endif -auto *serialManager = new SerialManager(commandManager, &timerHandle); +auto* serialManager = new SerialManager(commandManager, &timerHandle); void startWiFiMode(); void startWiredMode(bool shouldCloseSerialManager); @@ -92,7 +92,7 @@ static void initNVSStorage() ESP_ERROR_CHECK(ret); } -int websocket_logger(const char *format, va_list args) +int websocket_logger(const char* format, va_list args) { webSocketLogger.log_message(format, args); return vprintf(format, args); @@ -129,10 +129,9 @@ void launch_streaming() } // Callback for automatic startup after delay -void startup_timer_callback(void *arg) +void startup_timer_callback(void* arg) { - ESP_LOGI("[MAIN]", "Startup timer fired, startupCommandReceived=%s, startupPaused=%s", - getStartupCommandReceived() ? "true" : "false", + ESP_LOGI("[MAIN]", "Startup timer fired, startupCommandReceived=%s, startupPaused=%s", getStartupCommandReceived() ? "true" : "false", getStartupPaused() ? "true" : "false"); if (!getStartupCommandReceived() && !getStartupPaused()) @@ -199,13 +198,7 @@ void startWiredMode(bool shouldCloseSerialManager) } ESP_LOGI("[MAIN]", "Starting CDC Serial Manager Task"); - xTaskCreate( - HandleCDCSerialManagerTask, - "HandleCDCSerialManagerTask", - 1024 * 6, - commandManager.get(), - 1, - nullptr); + xTaskCreate(HandleCDCSerialManagerTask, "HandleCDCSerialManagerTask", 1024 * 6, commandManager.get(), 1, nullptr); ESP_LOGI("[MAIN]", "Starting UVC streaming"); @@ -227,13 +220,9 @@ void startWiFiMode() { streamServer.startStreamServer(); } - xTaskCreate( - HandleRestAPIPollTask, - "HandleRestAPIPollTask", - 2024 * 2, - restAPI.get(), - 1, // it's the rest API, we only serve commands over it so we don't really need a higher priority - nullptr); + xTaskCreate(HandleRestAPIPollTask, "HandleRestAPIPollTask", 2024 * 2, restAPI.get(), + 1, // it's the rest API, we only serve commands over it so we don't really need a higher priority + nullptr); #else ESP_LOGW("[MAIN]", "Wireless is disabled by configuration; skipping WiFi/mDNS/REST startup."); #endif @@ -251,11 +240,7 @@ void startSetupMode() // Create a one-shot timer for 20 seconds const esp_timer_create_args_t startup_timer_args = { - .callback = &startup_timer_callback, - .arg = nullptr, - .dispatch_method = ESP_TIMER_TASK, - .name = "startup_timer", - .skip_unhandled_events = false}; + .callback = &startup_timer_callback, .arg = nullptr, .dispatch_method = ESP_TIMER_TASK, .name = "startup_timer", .skip_unhandled_events = false}; ESP_ERROR_CHECK(esp_timer_create(&startup_timer_args, &timerHandle)); ESP_ERROR_CHECK(esp_timer_start_once(timerHandle, startup_delay_s * 1000000)); @@ -290,35 +275,18 @@ extern "C" void app_main(void) monitoringManager->start(); #endif - xTaskCreate( - HandleStateManagerTask, - "HandleStateManagerTask", - 1024 * 2, - stateManager, - 3, - nullptr // it's fine for us not get a handle back, we don't need it + xTaskCreate(HandleStateManagerTask, "HandleStateManagerTask", 1024 * 2, stateManager, 3, + nullptr // it's fine for us not get a handle back, we don't need it ); - xTaskCreate( - HandleLEDDisplayTask, - "HandleLEDDisplayTask", - 1024 * 2, - ledManager.get(), - 3, - nullptr); + xTaskCreate(HandleLEDDisplayTask, "HandleLEDDisplayTask", 1024 * 2, ledManager.get(), 3, nullptr); cameraHandler->setupCamera(); // let's keep the serial manager running for the duration of the setup // we'll clean it up later if need be serialManager->setup(); - xTaskCreate( - HandleSerialManagerTask, - "HandleSerialManagerTask", - 1024 * 6, - serialManager, - 1, - &serialManagerHandle); + xTaskCreate(HandleSerialManagerTask, "HandleSerialManagerTask", 1024 * 6, serialManager, 1, &serialManagerHandle); StreamingMode mode = deviceConfig->getDeviceMode(); if (mode == StreamingMode::UVC)