diff --git a/arduino/libraries/WiFi/src/RGBled.c b/arduino/libraries/WiFi/src/RGBled.c new file mode 100644 index 00000000..5fe3f10b --- /dev/null +++ b/arduino/libraries/WiFi/src/RGBled.c @@ -0,0 +1,174 @@ +#include "esp_log.h" +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "RGBled.h" +#include "esp_event_base.h" +#include "../private_include/esp_event_internal.h" + +#include "wiring_digital.h" + +// Event loop +static esp_event_loop_handle_t RGB_event_loop; + +bool rgb_stop = false; +bool ap_connected = true; +int blink_time = 0; + +ESP_EVENT_DEFINE_BASE(RGB_LED_EVENT) + + +void RGBmode(uint32_t mode) +{ + pinMode(25, mode); + pinMode(26, mode); + pinMode(27, mode); +} + +void clearLed(void) +{ + analogWrite(25, 0); //GREEN + analogWrite(26, 0); //RED + analogWrite(27, 0); //BLU +} + +void RGBcolor(uint8_t red, uint8_t green, uint8_t blue) +{ + if (rgb_stop == true) { + clearLed(); + } + else { + analogWrite(25, green); + analogWrite(26, red); + analogWrite(27, blue); + } +} + +void APconnection(void) +{ + wifi_sta_list_t stadevList; + esp_wifi_ap_get_sta_list(&stadevList); + + uint8_t num_dev = stadevList.num; + int blink_time = 1000 - 250*(num_dev-1); + + RGBcolor(127, 0, 255); //VIOLET + delay(blink_time); + RGBcolor(0, 255, 0); //GREEN + delay(blink_time); + if (uxQueueMessagesWaiting(((esp_event_loop_instance_t*) RGB_event_loop)->queue) == 0) { + esp_event_post_to(RGB_event_loop, RGB_LED_EVENT, RGB_EVENT_AP_STACONNECTED, NULL, 0, 0); + } +} + +void APdisconnection(void) +{ + wifi_sta_list_t stadevList; + esp_wifi_ap_get_sta_list(&stadevList); + + uint8_t num_dev = stadevList.num; + int blink_time = 1000 - 250*num_dev; + + RGBcolor(127, 0, 255); //VIOLET + delay(blink_time); + RGBcolor(255, 0, 0); //GREEN + delay(blink_time); + if (uxQueueMessagesWaiting(((esp_event_loop_instance_t*) RGB_event_loop)->queue) == 0) { + esp_event_post_to(RGB_event_loop, RGB_LED_EVENT, RGB_EVENT_AP_STADISCONNECTED, NULL, 0, 0); + } +} + +static void run_on_rgb_event(void* handler_args, esp_event_base_t base, int32_t id, void* event_data) +{ + switch (id) + { + case RGB_EVENT_STA_CONNECTED: + ESP_EARLY_LOGI(TAG, "State: RGB_EVENT_STA_CONNECTED"); + + RGBcolor(0, 255, 0); + break; + + case RGB_EVENT_STA_DISCONNECTED: + ESP_EARLY_LOGI(TAG, "State: RGB_EVENT_STA_DISCONNECTED"); + + RGBcolor(255, 0, 0); + break; + + case RGB_EVENT_AP_START: + ESP_EARLY_LOGI(TAG, "State: RGB_EVENT_AP_START"); + + RGBcolor(255, 255, 0); + break; + + case RGB_EVENT_AP_STACONNECTED: + ESP_EARLY_LOGI(TAG, "State: RGB_EVENT_AP_STACONNECTED"); + + ap_connected = true; + + if (uxQueueMessagesWaiting(((esp_event_loop_instance_t*) RGB_event_loop)->queue) == 0) { + APconnection(); + } + break; + + case RGB_EVENT_AP_STADISCONNECTED: + ESP_EARLY_LOGI(TAG, "State: RGB_EVENT_AP_STADISCONNECTED"); + + ap_connected = false; + + if (uxQueueMessagesWaiting(((esp_event_loop_instance_t*) RGB_event_loop)->queue) == 0) { + APdisconnection(); + } + break; + + case RGB_EVENT_LED_STOP: + ESP_EARLY_LOGI(TAG, "State: RGB_EVENT_LED_STOP"); + + rgb_stop = true; + + clearLed(); + + break; + + case RGB_EVENT_LED_RESTART: + ESP_EARLY_LOGI(TAG, "State: RGB_EVENT_LED_RESTART"); + + rgb_stop = false; + break; + + default: + break; + } +} + +void ledRGBEventSource(int32_t event_id) +{ + if (event_id == SYSTEM_EVENT_STA_CONNECTED || event_id == RGB_EVENT_STA_DISCONNECTED || event_id == RGB_EVENT_AP_START || event_id == RGB_EVENT_AP_STACONNECTED || event_id == RGB_EVENT_AP_STADISCONNECTED || event_id == RGB_EVENT_LED_STOP || event_id == RGB_EVENT_LED_RESTART) { + esp_event_post_to(RGB_event_loop, RGB_LED_EVENT, event_id, NULL, 0, 0); + } +} + +void rgb_init() +{ + RGBmode(OUTPUT); + + esp_event_loop_args_t loop_args = { + .queue_size = 5, + .task_name = "RGB_loop_task", + .task_priority = uxTaskPriorityGet(NULL), + .task_stack_size = 2048, + .task_core_id = tskNO_AFFINITY + }; + + esp_event_loop_create(&loop_args, &RGB_event_loop); + + esp_event_handler_register_with(RGB_event_loop, RGB_LED_EVENT, RGB_EVENT_STA_CONNECTED, run_on_rgb_event, NULL); + esp_event_handler_register_with(RGB_event_loop, RGB_LED_EVENT, RGB_EVENT_STA_DISCONNECTED, run_on_rgb_event, NULL); + esp_event_handler_register_with(RGB_event_loop, RGB_LED_EVENT, RGB_EVENT_AP_START, run_on_rgb_event, NULL); + esp_event_handler_register_with(RGB_event_loop, RGB_LED_EVENT, RGB_EVENT_AP_STACONNECTED, run_on_rgb_event, NULL); + esp_event_handler_register_with(RGB_event_loop, RGB_LED_EVENT, RGB_EVENT_AP_STADISCONNECTED, run_on_rgb_event, NULL); + esp_event_handler_register_with(RGB_event_loop, RGB_LED_EVENT, RGB_EVENT_LED_STOP, run_on_rgb_event, NULL); + esp_event_handler_register_with(RGB_event_loop, RGB_LED_EVENT, RGB_EVENT_LED_RESTART, run_on_rgb_event, NULL); + +} \ No newline at end of file diff --git a/arduino/libraries/WiFi/src/RGBled.cpp b/arduino/libraries/WiFi/src/RGBled.cpp new file mode 100644 index 00000000..30be0367 --- /dev/null +++ b/arduino/libraries/WiFi/src/RGBled.cpp @@ -0,0 +1,176 @@ +#include "wiring_digital.h" + +#include "WiFi.h" +#include +#include "esp_log.h" + +#include "RGBled.h" + +#define TAG "RGBled" + +RGBClass::RGBClass() +{ +} + +void RGBClass::init(void) +{ + RGBmode(OUTPUT); +} + +void RGBClass::RGBmode(uint32_t mode) +{ + pinMode(25, mode); + pinMode(26, mode); + pinMode(27, mode); +} + +void RGBClass::RGBcolor(uint8_t red, uint8_t green, uint8_t blue) +{ + analogWrite(25, green); + analogWrite(26, red); + analogWrite(27, blue); +} + +void RGBClass::clearLed(void) +{ + analogWrite(25, 0); //GREEN + analogWrite(26, 0); //RED + analogWrite(27, 0); //BLU +} + +void RGBClass::ledRGBEvent(system_event_t* event) +{ + switch (event->event_id) { + case SYSTEM_EVENT_SCAN_DONE: + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_SCAN_DONE"); + break; + + case SYSTEM_EVENT_STA_START: + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_STA_START"); + break; + + case SYSTEM_EVENT_STA_STOP: + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_STA_STOP"); + break; + + case SYSTEM_EVENT_STA_CONNECTED: + + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_STA_CONNECTED"); + + RGBcolor(0, 255, 0); //GREEN + break; + + case SYSTEM_EVENT_STA_GOT_IP: + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_STA_GOT_IP"); + break; + + case SYSTEM_EVENT_STA_DISCONNECTED: { + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_STA_DISCONNECTED"); + uint8_t status; + status = WiFi.status(); + + if (status == WL_CONNECT_FAILED) { + RGBcolor(0, 127, 255); //LIGHT BLUE + } + else { + RGBcolor(255, 0, 0); //RED + } + break; + } + + case SYSTEM_EVENT_STA_LOST_IP: + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_STA_LOST_IP"); + break; + + case SYSTEM_EVENT_AP_START: + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_AP_START"); + + RGBcolor(255, 255, 0); //YELLOW + break; + + case SYSTEM_EVENT_AP_STOP: + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_AP_STOP"); + break; + + case SYSTEM_EVENT_AP_STACONNECTED: + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_AP_STOP. Before asking tasks states"); + if (RGBtask_handle != NULL) { + vTaskSuspend( RGBtask_handle ); + vTaskDelete( RGBtask_handle ); + } + xTaskCreatePinnedToCore(RGBClass::APconnection, "APconnection", 8192, NULL, 1, &RGBtask_handle, 1); + break; + + case SYSTEM_EVENT_AP_STADISCONNECTED: + if (RGBtask_handle != NULL) { + vTaskSuspend( RGBtask_handle ); + vTaskDelete( RGBtask_handle ); + } + xTaskCreatePinnedToCore(RGBClass::APdisconnection, "APdisconnection", 8192, NULL, 1, &RGBtask_handle, 1); + break; + + default: + break; + } +} + +void RGBClass::RGBstop(void*) +{ + ESP_EARLY_LOGI(TAG, "RGBstop thread created"); + while(1) { + if (RGB.RGBtask_handle != NULL) { + vTaskSuspend( RGB.RGBtask_handle ); + vTaskDelete( RGB.RGBtask_handle ); + } + + RGB.clearLed(); + RGB.RGBmode(INPUT); + } +} + + +void RGBClass::APconnection(void*) +{ + wifi_sta_list_t stadevList; + + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_AP_STACONNECTED"); + esp_wifi_ap_get_sta_list(&stadevList); + + uint8_t num_dev = stadevList.num; + int blink_time = 1000 - 250*(num_dev-1); + + for (int i = 0; i < 3; i++) { + RGB.RGBcolor(127, 0, 255); //VIOLET + delay(blink_time); + RGB.RGBcolor(0, 255, 0); //GREEN + delay(blink_time); + } + + RGB.clearLed(); + + vTaskSuspend( NULL ); + vTaskDelete( NULL ); +} + +void RGBClass::APdisconnection(void*) +{ + wifi_sta_list_t stadevList; + + ESP_EARLY_LOGI(TAG, "State: SYSTEM_EVENT_AP_STADISCONNECTED"); + esp_wifi_ap_get_sta_list(&stadevList); + + uint8_t num_dev = stadevList.num; + int blink_time = 1000 - 250*(num_dev-1); + + for (int j = 0; j < 3; j++) { + RGB.RGBcolor(127, 0, 255); //VIOLET + delay(blink_time); + RGB.RGBcolor(255, 0, 0); //GREEN + delay(blink_time); + } + + RGB.clearLed(); + + vTaskSuspend( NULL ); + vTaskDelete( NULL ); +} \ No newline at end of file diff --git a/arduino/libraries/WiFi/src/RGBled.h b/arduino/libraries/WiFi/src/RGBled.h new file mode 100644 index 00000000..6f687685 --- /dev/null +++ b/arduino/libraries/WiFi/src/RGBled.h @@ -0,0 +1,38 @@ +#ifndef RGBLED_H_ +#define RGBLED_H_ + +#include "esp_event.h" +#include "esp_event_loop.h" +#include "esp_timer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Declarations for the event source +#define TASK_ITERATIONS_COUNT 10 // number of times the task iterates +#define TASK_PERIOD 500 // period of the task loop in milliseconds + +ESP_EVENT_DECLARE_BASE(RGB_LED_EVENT); // declaration of the task events family + +static const char* TAG = "RGBled"; + +enum { + RGB_EVENT_STA_CONNECTED = SYSTEM_EVENT_STA_CONNECTED, /* Connected to WiFi */ + RGB_EVENT_STA_DISCONNECTED = SYSTEM_EVENT_STA_DISCONNECTED, /* Disconnected from WiFi */ + RGB_EVENT_AP_START = SYSTEM_EVENT_AP_START, /* Access point created */ + RGB_EVENT_AP_STACONNECTED = SYSTEM_EVENT_AP_STACONNECTED, /* Device connected to Access Point */ + RGB_EVENT_AP_STADISCONNECTED = SYSTEM_EVENT_AP_STADISCONNECTED, /* Device disconnected from Access Point */ + RGB_EVENT_LED_STOP = (SYSTEM_EVENT_MAX + 1), /* Stop RGB led */ + RGB_EVENT_LED_RESTART = (SYSTEM_EVENT_MAX + 2) /* Restart RGB led */ +}; + +void rgb_init(void); + +void ledRGBEventSource(int32_t event_id); //system_event_t* event + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef RGBLED_H_ \ No newline at end of file diff --git a/arduino/libraries/WiFi/src/WiFi.cpp b/arduino/libraries/WiFi/src/WiFi.cpp index e9330555..24b7910b 100644 --- a/arduino/libraries/WiFi/src/WiFi.cpp +++ b/arduino/libraries/WiFi/src/WiFi.cpp @@ -31,6 +31,8 @@ #include #include #include +#include +#include "RGBled.h" #include "WiFi.h" @@ -189,11 +191,25 @@ uint8_t WiFiClass::begin(const char* ssid, const char* key) { wifi_config_t wifiConfig; - memset(&wifiConfig, 0x00, sizeof(wifiConfig)); - strncpy((char*)wifiConfig.sta.ssid, ssid, sizeof(wifiConfig.sta.ssid)); - strncpy((char*)wifiConfig.sta.password, key, sizeof(wifiConfig.sta.password)); - wifiConfig.sta.scan_method = WIFI_FAST_SCAN; - _status = WL_NO_SSID_AVAIL; + status(); + + if (_status == WL_IDLE_STATUS) { + esp_wifi_get_config(ESP_IF_WIFI_STA, &wifiConfig_bkp); + } + + if (strlen(ssid) == 0 || (_status != WL_IDLE_STATUS && _status != WL_CONNECTED)) { + _status = WL_IDLE_STATUS; + memset(&wifiConfig, 0x00, sizeof(wifiConfig_bkp)); + strncpy((char*)wifiConfig.sta.ssid, (char*)wifiConfig_bkp.sta.ssid, sizeof(wifiConfig_bkp.sta.ssid)); + strncpy((char*)wifiConfig.sta.password, (char*)wifiConfig_bkp.sta.password, sizeof(wifiConfig_bkp.sta.password)); + wifiConfig.sta.scan_method = WIFI_FAST_SCAN; + } + else { + memset(&wifiConfig, 0x00, sizeof(wifiConfig)); + strncpy((char*)wifiConfig.sta.ssid, ssid, sizeof(wifiConfig.sta.ssid)); + strncpy((char*)wifiConfig.sta.password, key, sizeof(wifiConfig.sta.password)); + wifiConfig.sta.scan_method = WIFI_FAST_SCAN; + } _interface = ESP_IF_WIFI_STA; @@ -203,8 +219,8 @@ uint8_t WiFiClass::begin(const char* ssid, const char* key) esp_wifi_start(); xEventGroupWaitBits(_eventGroup, BIT0, false, true, portMAX_DELAY); - if (esp_wifi_set_config(ESP_IF_WIFI_STA, &wifiConfig) != ESP_OK) { - _status = WL_CONNECT_FAILED; + if (sizeof(ssid) > 0) { + esp_wifi_set_config(ESP_IF_WIFI_STA, &wifiConfig); } if (_staticIp) { @@ -673,18 +689,20 @@ err_t WiFiClass::handleApNetifInput(struct pbuf* p, struct netif* inp) void WiFiClass::init() { + nvs_flash_init(); tcpip_adapter_init(); esp_event_loop_init(WiFiClass::systemEventHandler, this); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); esp_wifi_init(&cfg); - esp_wifi_set_storage(WIFI_STORAGE_RAM); + esp_wifi_set_storage(WIFI_STORAGE_FLASH); sntp_setoperatingmode(SNTP_OPMODE_POLL); sntp_setservername(0, (char*)"0.pool.ntp.org"); sntp_setservername(1, (char*)"1.pool.ntp.org"); sntp_setservername(2, (char*)"2.pool.ntp.org"); sntp_init(); + _status = WL_IDLE_STATUS; } @@ -832,6 +850,8 @@ void WiFiClass::handleSystemEvent(system_event_t* event) default: break; } + + ledRGBEventSource(event->event_id); } WiFiClass WiFi; diff --git a/arduino/libraries/WiFi/src/WiFi.h b/arduino/libraries/WiFi/src/WiFi.h index 00c4551b..128dd274 100644 --- a/arduino/libraries/WiFi/src/WiFi.h +++ b/arduino/libraries/WiFi/src/WiFi.h @@ -120,6 +120,8 @@ class WiFiClass EventGroupHandle_t _eventGroup; esp_interface_t _interface; + wifi_config_t wifiConfig_bkp; + wifi_ap_record_t _scanResults[MAX_SCAN_RESULTS]; wifi_ap_record_t _apRecord; bool _staticIp; diff --git a/main/CommandHandler.cpp b/main/CommandHandler.cpp index 312ff749..3a677857 100644 --- a/main/CommandHandler.cpp +++ b/main/CommandHandler.cpp @@ -24,9 +24,13 @@ #include #include #include +#include "RGBled.h" #include "CommandHandler.h" +#include "esp_log.h" +#define TAG "CommandHandler" + const char FIRMWARE_VERSION[6] = "1.3.0"; /*IPAddress*/uint32_t resolvedHostname; @@ -1109,6 +1113,216 @@ int setAnalogWrite(const uint8_t command[], uint8_t response[]) return 6; } +int setRGBled(const uint8_t command[], uint8_t response[]) +{ + if (command[4]==1) { + ledRGBEventSource(RGB_EVENT_LED_STOP); + } + else if (command[4]==2) { + ledRGBEventSource(RGB_EVENT_LED_RESTART); + } + + response[2] = 1; // number of parameters + response[3] = 1; // parameter 1 length + response[4] = 1; + + return 6; +} + +int writeFile(const uint8_t command[], uint8_t response[]) { + char filename[32 + 1]; + size_t len; + size_t offset; + + memcpy(&offset, &command[4], command[3]); + memcpy(&len, &command[5 + command[3]], command[4 + command[3]]); + + memset(filename, 0x00, sizeof(filename)); + memcpy(filename, &command[6 + command[3] + command[4 + command[3]]], command[5 + command[3] + command[4 + command[3]]]); + + FILE* f = fopen(filename, "ab+"); + if (f == NULL) { + return -1; + } + + fseek(f, offset, SEEK_SET); + const uint8_t* data = &command[7 + command[3] + command[4 + command[3]] + command[5 + command[3] + command[4 + command[3]]]]; + + int ret = fwrite(data, 1, len, f); + fclose(f); + + return ret; +} + +int readFile(const uint8_t command[], uint8_t response[]) { + char filename[32 + 1]; + size_t len; + size_t offset; + + memcpy(&offset, &command[4], command[3]); + memcpy(&len, &command[5 + command[3]], command[4 + command[3]]); + + memset(filename, 0x00, sizeof(filename)); + memcpy(filename, &command[6 + command[3] + command[4 + command[3]]], command[5 + command[3] + command[4 + command[3]]]); + + FILE* f = fopen(filename, "rb"); + if (f == NULL) { + return -1; + } + fseek(f, offset, SEEK_SET); + int ret = fread(&response[4], len, 1, f); + fclose(f); + + response[2] = 1; // number of parameters + response[3] = len; // parameter 1 length + + return len + 5; +} + +int deleteFile(const uint8_t command[], uint8_t response[]) { + char filename[32 + 1]; + size_t len; + size_t offset; + + memcpy(&offset, &command[4], command[3]); + memcpy(&len, &command[5 + command[3]], command[4 + command[3]]); + + memset(filename, 0x00, sizeof(filename)); + memcpy(filename, &command[6 + command[3] + command[4 + command[3]]], command[5 + command[3] + command[4 + command[3]]]); + + int ret = -1; + struct stat st; + if (stat(filename, &st) == 0) { + // Delete it if it exists + ret = unlink(filename); + } + return 0; +} + +#include + +int applyOTA(const uint8_t command[], uint8_t response[]) { +#ifdef UNO_WIFI_REV2 + + const char* filename = "/fs/UPDATE.BIN"; + FILE* updateFile = fopen(filename, "rb"); + + // init uart and write update to 4809 + uart_config_t uart_config; + + uart_config.baud_rate = 115200; + uart_config.data_bits = UART_DATA_8_BITS; + uart_config.parity = UART_PARITY_DISABLE; + uart_config.stop_bits = UART_STOP_BITS_1; + uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; + uart_config.rx_flow_ctrl_thresh = 122; + uart_config.use_ref_tick = true; + + uart_param_config(UART_NUM_1, &uart_config); + + uart_set_pin(UART_NUM_1, + 1, // tx + 3, // rx + UART_PIN_NO_CHANGE, // rts + UART_PIN_NO_CHANGE); //cts + + uart_driver_install(UART_NUM_1, 1024, 0, 20, NULL, 0); + + struct stat st; + stat(filename, &st); + + int retries = 0; + + size_t remaining = st.st_size % 1024; + for (int i=0; i= 100) { + goto exit; + } + } + // send remaining bytes (to reach page size) as 0xFF + for (int i=0; i 0x5f - setPinMode, setDigitalWrite, setAnalogWrite, + setPinMode, setDigitalWrite, setAnalogWrite, setRGBled, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + // 0x60 -> 0x6f + writeFile, readFile, deleteFile, existsFile, downloadFile, applyOTA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; #define NUM_COMMAND_HANDLERS (sizeof(commandHandlers) / sizeof(commandHandlers[0])) @@ -1154,6 +1371,9 @@ void CommandHandlerClass::begin() xTaskCreatePinnedToCore(CommandHandlerClass::gpio0Updater, "gpio0Updater", 8192, NULL, 1, NULL, 1); } +#define UDIV_UP(a, b) (((a) + (b) - 1) / (b)) +#define ALIGN_UP(a, b) (UDIV_UP(a, b) * (b)) + int CommandHandlerClass::handle(const uint8_t command[], uint8_t response[]) { int responseLength = 0; @@ -1180,7 +1400,7 @@ int CommandHandlerClass::handle(const uint8_t command[], uint8_t response[]) xSemaphoreGive(_updateGpio0PinSemaphore); - return responseLength; + return ALIGN_UP(responseLength, 4); } void CommandHandlerClass::gpio0Updater(void*) diff --git a/main/CommandHandler.h b/main/CommandHandler.h index 28a47a43..9cef4619 100644 --- a/main/CommandHandler.h +++ b/main/CommandHandler.h @@ -45,4 +45,6 @@ class CommandHandlerClass { extern CommandHandlerClass CommandHandler; +extern "C" int downloadAndSaveFile(char* url, char* filename, FILE* f); + #endif diff --git a/main/http_client.c b/main/http_client.c new file mode 100644 index 00000000..002036dc --- /dev/null +++ b/main/http_client.c @@ -0,0 +1,65 @@ +// esp_http_client.c +#include +#include +#include "esp_log.h" +#include + +#include "esp_http_client.h" + +#define MAX_HTTP_RECV_BUFFER 128 + +static const char* TAG = "HTTP_HANDLER"; + +static esp_err_t _http_event_handler(esp_http_client_event_t *evt) +{ + switch(evt->event_id) { + case HTTP_EVENT_ERROR: + case HTTP_EVENT_ON_CONNECTED: + case HTTP_EVENT_HEADER_SENT: + case HTTP_EVENT_ON_FINISH: + case HTTP_EVENT_DISCONNECTED: + case HTTP_EVENT_ON_HEADER: + break; + case HTTP_EVENT_ON_DATA: + if (!esp_http_client_is_chunked_response(evt->client)) { + //fwrite((char*)evt->data, sizeof(uint8_t), evt->data_len, (FILE*)evt->user_data); + } + break; + } + return ESP_OK; +} + +int downloadAndSaveFile(char* url, char* filename, FILE* f) { + + char *buffer = (char*)malloc(MAX_HTTP_RECV_BUFFER); + if (buffer == NULL) { + return -1; + } + esp_http_client_config_t config = { + .url = url, + .event_handler = _http_event_handler, + .user_data = f, + }; + + esp_http_client_handle_t client = esp_http_client_init(&config); + esp_err_t err; + if ((err = esp_http_client_open(client, 0)) != ESP_OK) { + free(buffer); + return -1; + } + int content_length = esp_http_client_fetch_headers(client); + int total_read_len = 0, read_len; + while (total_read_len < content_length) { + read_len = esp_http_client_read(client, buffer, MAX_HTTP_RECV_BUFFER); + fwrite(buffer, sizeof(uint8_t), read_len, f); + if (read_len <= 0) { + break; + } + total_read_len += read_len; + } + esp_http_client_close(client); + esp_http_client_cleanup(client); + free(buffer); + + return 0; +} \ No newline at end of file diff --git a/main/sketch.ino.cpp b/main/sketch.ino.cpp index 17889f8a..26117f03 100644 --- a/main/sketch.ino.cpp +++ b/main/sketch.ino.cpp @@ -21,10 +21,18 @@ extern "C" { #include + #include #include -} + #include "esp_spiffs.h" + #include "esp_log.h" + #include + #include + #include + #include "esp_partition.h" +} +#include "RGBled.h" #include #include @@ -83,13 +91,14 @@ void setupWiFi(); void setupBluetooth(); void setup() { - setDebug(debug); + //setDebug(debug); // put SWD and SWCLK pins connected to SAMD as inputs pinMode(15, INPUT); pinMode(21, INPUT); pinMode(5, INPUT); + rgb_init(); if (digitalRead(5) == LOW) { setupBluetooth(); } else { @@ -135,6 +144,46 @@ void setupWiFi() { esp_bt_controller_mem_release(ESP_BT_MODE_BTDM); SPIS.begin(); + esp_vfs_spiffs_conf_t conf = { + .base_path = "/fs", + .partition_label = "storage", + .max_files = 20, + .format_if_mount_failed = true + }; + + esp_err_t ret = esp_vfs_spiffs_register(&conf); + + uint8_t counter = 0; + + #define TAG "sketch" + + const char* filename = "/fs/bootcounter.bin"; + FILE* counterFile; + counterFile = fopen("/fs/bootcounter.bin", "r"); + if (counterFile == NULL) { + ESP_EARLY_LOGI(TAG, "Counter file didn't exist. It has been created"); + + counterFile = fopen("/fs/bootcounter.bin", "w+"); + counter = 1; + fwrite(&counter, sizeof(uint8_t), 1, counterFile); + fclose(counterFile); + + ESP_EARLY_LOGI(TAG, "Counter written in file: %d", counter); + } + else { + int sizef = fread(&counter, 1, 1, counterFile); + + ESP_EARLY_LOGI(TAG, "Counter file already existed -> opened"); + ESP_EARLY_LOGI(TAG, "Counter read from file: %d", counter); + + counter++; + freopen(filename,"w",counterFile); + ESP_EARLY_LOGI(TAG, "Counter written in file: %d", counter); + ESP_EARLY_LOGI(TAG, "Reboot counter is still in the range. %d more attempts allowed", (4-counter)); + fwrite(&counter, sizeof(uint8_t), 1, counterFile); + fclose(counterFile); + } + if (WiFi.status() == WL_NO_SHIELD) { while (1); // no shield } diff --git a/partitions.csv b/partitions.csv index 2f45debf..a549e0e3 100644 --- a/partitions.csv +++ b/partitions.csv @@ -4,3 +4,4 @@ nvs, data, nvs, 0x9000, 0x6000 phy_init, data, phy, 0xf000, 0x1000 certs, data, 0x04, 0x10000, 0x20000 factory, app, factory, 0x30000, 0x180000 +storage, data, spiffs, 0x1B0000,0x40000