From 33dbf3fc7bab6984f8e11efc1dbc49e366b920fd Mon Sep 17 00:00:00 2001 From: MiroZ Date: Thu, 16 May 2024 17:28:22 -0700 Subject: [PATCH] added isQueueEmpty to async web server socket client, led is using queue --- build.sh | 6 + .../AsyncWebServer/src/AsyncWebSocket.h | 2 + html/provision.html | 61 ++++- main/App.cpp | 18 +- main/App.h | 2 +- main/CMakeLists.txt | 2 +- main/Led.cpp | 49 ++-- main/Led.h | 20 +- main/ProvisionSoftAP.cpp | 232 ++++++++++-------- main/ProvisionSoftAP.h | 23 +- main/ReaderWriter.cpp | 85 +++++++ main/ReaderWriter.h | 157 ++++++++++++ main/Settings.cpp | 12 +- main/Settings.h | 4 +- main/TaskFactory.h | 2 +- main/Wifi.h | 2 +- main/utilities.h | 2 +- 17 files changed, 510 insertions(+), 169 deletions(-) create mode 100755 build.sh create mode 100644 main/ReaderWriter.cpp create mode 100644 main/ReaderWriter.h diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..341aa5c --- /dev/null +++ b/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# first device connected + +idf.py -DROLE=SENDER build + diff --git a/components/AsyncWebServer/src/AsyncWebSocket.h b/components/AsyncWebServer/src/AsyncWebSocket.h index d48289f..444b173 100755 --- a/components/AsyncWebServer/src/AsyncWebSocket.h +++ b/components/AsyncWebServer/src/AsyncWebSocket.h @@ -180,6 +180,8 @@ class AsyncWebSocketClient { public: void *_tempObject; + + bool isQueueEmpty() { return _messageQueue.isEmpty();} AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server); ~AsyncWebSocketClient(); diff --git a/html/provision.html b/html/provision.html index 9d7e928..16121f8 100755 --- a/html/provision.html +++ b/html/provision.html @@ -23,7 +23,44 @@ function OpenSocket() ws.onmessage = function(evt_data) { console.log('Message', evt_data.data); - var msg = JSON.parse(evt_data.data); + + var rcv = evt_data.data.split("|"); + var cmd = rcv[0].split(":"); + + console.log('cmd', cmd); + + switch(cmd[1]) + { + case "scan_wifi": + var table = document.getElementById("wifi_table"); + while(table.rows.length > 1) + table.deleteRow(1); + + var num = rcv[1].split(":")[1]; + for(var n=0; n" + ssid[0] + "" + row.insertCell(1).innerHTML = ssid[1] == 1 ? "secured" : "open"; + row.insertCell(2).innerHTML = ssid[2]; + } + hideAll(); + showWifiTable(true); + showWifiCred(true); + break; + + case "ok": + onSetupOk(); + break; + + case "fail": + onSetupError(); + break; + } + + + /*var msg = JSON.parse(evt_data.data); switch(msg.type) { case "wifi_scan": @@ -55,6 +92,7 @@ function OpenSocket() break; } + */ } } function CloseSocket() @@ -82,17 +120,22 @@ function onSetupOk() { hideAll(); showMsgOk(true); + + // setTimeout(function(){ + // exit(); + // }, 2000); + + } function onSetupError() { hideAll(); showMsgError(true); - StartWifiScan(); + //StartWifiScan(); } function StartWifiScan() { - var v = {command:"wifi_scan"}; - ws.send(JSON.stringify(v)); + ws.send("command:scan_wifi"); } // show/hide elements @@ -130,9 +173,8 @@ function onUseWifi() hideAll(); showWaitVerifyConnection(true); - var v = {command:"wifi_config", ssid:ssid, pwd:pwd}; - ws.send(JSON.stringify(v)); - console.log(ssid+":"+pwd); + var v = "command:verify_wifi|ssid:"+ssid+"|pwd:"+pwd; + ws.send(v); } function onTailgating() { @@ -145,9 +187,6 @@ function onTailgating() } function onButton1() { - var obj = { type: "wifi_scan", data:[["Miro",1,20],["Jake",1,10]] }; - var myJSON = JSON.stringify(obj); - hideAll(); showWifiTable(true); showWifiCred(true); @@ -355,7 +394,7 @@ input {

-

Beat-a-meat has ben successfully configured. It is now ready for normal use.

+

Beat-a-meat has ben successfully configured and it is ready for normal use.
You can now close this window.

Beat-a-meat was not able to connect to selected WiFi. Please check the spelling and password.

diff --git a/main/App.cpp b/main/App.cpp index 6cfb99f..32934c5 100644 --- a/main/App.cpp +++ b/main/App.cpp @@ -4,6 +4,7 @@ #include #include "Settings.h" +#include "errors.h" #include "ProvisionSoftAP.h" @@ -17,14 +18,23 @@ App::App() void App::init() { m_led = new Led(LED_PIN); - m_led->setBrightness(SETTINGS.led.brightness); m_wifi = new Wifi(); - m_led->setPulse(0, 127, 0); + if(SETTINGS.wifi.num > 0) + { + // try connecting + m_led->setPulse(0, 255, 0); + uint32_t status = m_wifi->connect(); + if(status == WH_OK) + { + m_led->setColor(0, 0, 0); + return; + } + } + + m_led->setPulse(0, 0, 255); ProvisionSoftAP p(80); p.init("wellhub", "12345678"); - //m_wifi->connect(); - m_led->setColor(0, 0, 0); } void App::start() diff --git a/main/App.h b/main/App.h index d3d6708..7bf3358 100644 --- a/main/App.h +++ b/main/App.h @@ -23,4 +23,4 @@ public: void reportSensors(); }; -#endif \ No newline at end of file +#endif /* __APP_H__ */ \ No newline at end of file diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 6b10802..2beacbb 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register(SRCS main.cpp App.cpp Settings.cpp Led.cpp TaskFactory.cpp Wifi.cpp utilities.cpp - ProvisionSoftAP.cpp + ProvisionSoftAP.cpp ReaderWriter.cpp INCLUDE_DIRS "." EMBED_TXTFILES ../html/logo.png ../html/provision.html ) diff --git a/main/Led.cpp b/main/Led.cpp index cc7b483..079177f 100644 --- a/main/Led.cpp +++ b/main/Led.cpp @@ -1,5 +1,7 @@ /// © MiroZ 2024 +#include "Settings.h" + #include "Led.h" #if 0 @@ -52,31 +54,43 @@ void Led::steady(uint8_t r, uint8_t g, uint8_t b, uint8_t d) void Led::run() { + struct LED_QUEUE msg; + while(true) { - vTaskSuspend(NULL); +// vTaskSuspend(NULL); + xQueueReceive(m_queue, &msg, portMAX_DELAY); - if(m_program == PROGRAM::STEADY) + if(msg.program == PROGRAM::STEADY) { - steady(m_r, m_g, m_b, 30); + steady(msg.r, msg.g, msg.b, 30); } - else if(m_program == PROGRAM::PULSATING) + else if(msg.program == PROGRAM::PULSATING) { // turn off - steady(0, 0, 0, 10); + steady(0, 0, 0, 5); - while(m_program == PROGRAM::PULSATING) + while(true) { for(int n=0; nsetPixelColor(0, m_r*m/255, m_g*m/255, m_b*m/255); + m_strip->setPixelColor(0, msg.r*m/255, msg.g*m/255, msg.b*m/255); m_strip->show(); delay(30); } + + if(xQueueReceive(m_queue, &msg, 0)) + { + if(msg.program == PROGRAM::STEADY) + { + steady(msg.r, msg.g, msg.b, 30); + break; + } + } + delay(60); } - steady(m_r, m_g, m_b, 30); } } } @@ -89,8 +103,11 @@ Led::Led(uint32_t pin) m_strip->setPixelColor(0, 0, 0, 0); m_strip->show(); + m_brightness = SETTINGS.led.brightness; + assert(m_queue = xQueueCreate(5, sizeof(struct LED_QUEUE))); + // create the led task - m_task = TASK_FACTORY.createTask(std::bind(&Led::run, this), "led task", 4096, 5, 0); + m_task = TASK_FACTORY.createTask(std::bind(&Led::run, this), "led task", 2096, 5, 0); } Led::~Led() @@ -107,16 +124,18 @@ Led::~Led() /// @param brightness brightness 0-100 (%). Default is 100% void Led::setColor(uint8_t r, uint8_t g, uint8_t b) { - m_program = PROGRAM::STEADY; - m_r = (uint8_t)((uint32_t)r*m_brightness/100); m_g = (uint8_t)((uint32_t)g*m_brightness/100); m_b = (uint8_t)((uint32_t)b*m_brightness/100); - vTaskResume(m_task); + struct LED_QUEUE msg; + msg.program = PROGRAM::STEADY; + msg.r = scale(r); msg.g = scale(g); msg.b = scale(b); + xQueueSend(m_queue, &msg, 1000); } void Led::setPulse(uint8_t r, uint8_t g, uint8_t b) { - m_program = PROGRAM::PULSATING; - m_r = (uint8_t)((uint32_t)r*m_brightness/100); m_g = (uint8_t)((uint32_t)g*m_brightness/100); m_b = (uint8_t)((uint32_t)b*m_brightness/100); - vTaskResume(m_task); + struct LED_QUEUE msg; + msg.program = PROGRAM::PULSATING; + msg.r = scale(r); msg.g = scale(g); msg.b = scale(b); + xQueueSend(m_queue, &msg, 1000); } void Led::setBrightness(uint8_t brightness) diff --git a/main/Led.h b/main/Led.h index a716b00..6d49429 100644 --- a/main/Led.h +++ b/main/Led.h @@ -7,10 +7,21 @@ #include #include "TaskFactory.h" - class Led { + struct LED_QUEUE + { + uint8_t program; + struct + { + uint8_t r; + uint8_t g; + uint8_t b; + }; + }; + public: + enum PROGRAM{ STEADY, PULSATING @@ -19,10 +30,11 @@ public: protected: Adafruit_NeoPixel *m_strip; TaskHandle_t m_task = nullptr; - PROGRAM m_program; - uint8_t m_r, m_g, m_b; + QueueHandle_t m_queue = nullptr; uint8_t m_brightness = 100; + uint8_t scale(uint8_t val){ return (uint8_t)((int)val*m_brightness/100); } + protected: void run(); void steady(uint8_t r, uint8_t g, uint8_t b, uint8_t delay); @@ -37,4 +49,4 @@ public: void setPulse(uint8_t r, uint8_t g, uint8_t b); }; -#endif \ No newline at end of file +#endif /* __LED_H__ */ \ No newline at end of file diff --git a/main/ProvisionSoftAP.cpp b/main/ProvisionSoftAP.cpp index ad615fc..f0d48a0 100755 --- a/main/ProvisionSoftAP.cpp +++ b/main/ProvisionSoftAP.cpp @@ -12,7 +12,6 @@ #include #include "Settings.h" #include -#include "freertos/event_groups.h" #include @@ -33,6 +32,7 @@ const uint8_t last_ip[] = {172, 68, 4, 100}; ProvisionSoftAP::ProvisionSoftAP(int port) { + m_rwriter = new ReaderWriter(1024); m_webServer = new AsyncWebServer(port); m_webSocket = new AsyncWebSocket("/provision"); } @@ -62,17 +62,17 @@ void ProvisionSoftAP::websocketEvent(AsyncWebSocket * server, AsyncWebSocketClie if (type == WS_EVT_CONNECT) { - ESP_LOGI(TAG, "Websocket client id:%d connection received", client->id()); + ESP_LOGW(TAG, "Websocket client id:%d connection received", client->id()); m_clients.push_back(client->id()); } else if (type == WS_EVT_DISCONNECT) { - ESP_LOGI(TAG, "Client id:%d disconnected", client->id()); + ESP_LOGW(TAG, "Websocket client id:%d disconnected", client->id()); m_clients.remove(client->id()); } else if (type == WS_EVT_DATA) { - ESP_LOGI(TAG, "Data client %d received: ", client->id()); + ESP_LOGW(TAG, "Websocket cata client %d received: ", client->id()); parseWebsocketCommand((char*) data, len); } } @@ -108,7 +108,7 @@ void ProvisionSoftAP::init(const char * ssid, const char * password) IPAddress apIP(sta_ip); IPAddress netMsk(net_mask); IPAddress firstIp(first_ip); - wifiEventId = WiFi.onEvent(std::bind(&ProvisionSoftAP::wifiEvent, this, _1, _2)); + WiFi.onEvent(std::bind(&ProvisionSoftAP::wifiEvent, this, _1, _2)); WiFi.mode(WIFI_MODE_AP); WiFi.softAPConfig(apIP, apIP, netMsk, firstIp); @@ -133,47 +133,66 @@ void ProvisionSoftAP::init(const char * ssid, const char * password) m_webServer->begin(); + // char buf[64], buf1[32]; + // m_rwriter->copyString("command:verify_wifi|ssid:gumball|pwd:12345688"); + // ESP_LOGI(TAG, "%d", m_rwriter->elementIs(0, "command:verify_wifi")); + + + // uint32_t loc = m_rwriter->getNthDelimiter(0); + // if(m_rwriter->hasMore(loc)) + // ESP_LOGI(TAG, "%d", loc); + // while(m_rwriter->hasMore(loc)) + // { + // loc = m_rwriter->getNextDelimiter(loc); + // ESP_LOGI(TAG, "%d", loc); + // } + + // if(m_rwriter->getElementAt(buf, 64, 3)) + // ESP_LOGI(TAG, "'%s'", buf); + + // bool ret_val = m_rwriter->getAt(buf, 64, 3); + // ESP_LOGI(TAG, "(%d) '%s'", ret_val, buf); + + // Parser p(buf, ":"); + + // while(m_rwriter->getNext(buf, 64)) + // { + // p.reset(); + // while(p.getNext(buf1, 32)) + // ESP_LOGI(TAG, "'%s'", buf1); + // } + while (true) { - vTaskDelay(1); m_dnsServer.processNextRequest(); - // if (m_startWifiScan) - // { - // m_startWifiScan = false; - // ESP_LOGI(TAG, "Starting scan"); - // int num_networks = WiFi.scanNetworks(); + if (m_startWifiScan) + { + m_startWifiScan = false; + ESP_LOGI(TAG, "Starting scan"); + int num_networks = WiFi.scanNetworks(); + ESP_LOGI(TAG, "Found %d networks", num_networks); + m_rwriter->reset(); + m_rwriter->append("command:scan_wifi|"); + m_rwriter->fappend("num:%d|", num_networks); + for (int n = 0; n < num_networks; n++) + { + m_rwriter->fappend("%s,%d,%d", WiFi.SSID(n), WiFi.encryptionType(n) == WIFI_AUTH_OPEN ? 0 : 1, WiFi.RSSI(n)); + if(n != num_networks - 1) + m_rwriter->append('|'); + } + ESP_LOGI(TAG, "Sending '%s'", m_rwriter->getBuffer()); + m_webSocket->textAll(m_rwriter->getBuffer()); + vTaskDelay(550); + } - // ESP_LOGI(TAG, "Found %d networks", num_networks); + if(m_tryConnect) + { + m_tryConnect = false; + tryConnect(); + } - // // m_jsonBuffer.clear(); - // // JsonObject& root = m_jsonBuffer.createObject(); - // // root[TYPE] = WIFI_SCAN; - // // JsonArray& data = root.createNestedArray(DATA); - // // for (int n = 0; n < num_networks; n++) - // // { - // // JsonArray& data_inner = data.createNestedArray(); - // // data_inner.add(WiFi.SSID(n)); - // // data_inner.add(WiFi.encryptionType(n) == WIFI_AUTH_OPEN ? 0 : 1); - // // data_inner.add(WiFi.RSSI(n)); - // // } - // // size_t len = root.printTo(m_buff, sizeof(m_buff)); - // // m_webSocket->textAll(m_buff, len); - // // waitBufferEmpty(); - // } - // if(m_tryConnect) - // { - // m_tryConnect = false; - // tryConnect(m_ssid, m_password); - // } - // if(m_tailgate) - // { - // m_dnsServer.stop(); - // m_webSocket->closeAll(0, "bye"); - // waitBufferEmpty(); - // WiFi.removeEvent(wifiEventId); - // return; - // } + vTaskDelay(50); } for (int i = 200; i >= 0; i--) @@ -183,95 +202,98 @@ void ProvisionSoftAP::init(const char * ssid, const char * password) } } +const char verify_wifi[] = "command:verify_wifi"; + void ProvisionSoftAP::parseWebsocketCommand(char* data, size_t len) { data[len] = 0; ESP_LOGI(TAG, "'%s'", data); - // m_jsonBuffer.clear(); - // if(len<1024) - // data[len] = '\0'; - // JsonObject& root = m_jsonBuffer.parseObject(data); + if(strcmp(data, "command:scan_wifi") == 0) + { + m_startWifiScan = true; + ESP_LOGI(TAG, "Start scan command received"); + } + else if(strncmp(data, verify_wifi, sizeof(verify_wifi) - 1) == 0) + { + char buf[80], buf1[40]; + Parser p(buf, ":"); - // const char * command = root[COMMAND]; - // ESP_LOGI(TAG, "command: %s", command); + m_rwriter->copyString(data); - // if (command && strcmp(command, WIFI_SCAN) == 0) - // { - // m_startWifiScan = true; - // ESP_LOGI(TAG, "Start scan command received"); - // } - // else if (command && strcmp(command, WIFI_CONFIG) == 0) - // { - // const char * ssid = root[SSID]; - // const char * pwd = root[PWD]; - // strcpy(m_ssid, ssid); - // strcpy(m_password, pwd); - // ESP_LOGI(TAG, "ssid/credentials received: '%s'/'%s'", m_ssid, m_password); - // m_tryConnect = true; - // } - // else if (command && strcmp(command, TAILGATE) == 0) - // { - // m_tailgate = true; - // ESP_LOGI(TAG, "tailgate command received"); - // } + if(!m_rwriter->elementIs(1, "ssid")) + return; + + m_rwriter->getElementAt(1, buf, 80); + p.getElementAt(1, buf1, 40); + strcpy(m_ssid, buf1); + ESP_LOGI(TAG, "ssid: '%s'", m_ssid); + + if(!m_rwriter->elementIs(2, "pwd")) + return; + + m_rwriter->getElementAt(2, buf, 80); + p.getElementAt(1, buf1, 40); + strcpy(m_pwd, buf1); + ESP_LOGI(TAG, "pwd: '%s'", m_pwd); + + ESP_LOGI(TAG, "got complete network credentials!"); + m_tryConnect = true; + } } void ProvisionSoftAP::waitBufferEmpty() { -// ESP_LOGI(TAG, "waitBufferEmpty start"); -// bool empty = false; -// while (!empty) -// { -// empty = true; -// for (const auto& c : m_clients) -// { -// if (m_webSocket->client(c) && !m_webSocket->client(c)->isQueueEmpty()) -// { -// empty = false; -// break; -// } -// } -// vTaskDelay(10); -// } -// ESP_LOGI(TAG, "waitBufferEmpty end"); + ESP_LOGI(TAG, "waitBufferEmpty start"); + bool empty = false; + while (!empty) + { + empty = true; + for (const auto& c : m_clients) + { + if (m_webSocket->client(c) && !m_webSocket->client(c)->isQueueEmpty()) + { + empty = false; + break; + } + } + vTaskDelay(10); + } + ESP_LOGI(TAG, "waitBufferEmpty end"); } -void ProvisionSoftAP::tryConnect(const char * ssid, const char * pwd) -{ - ESP_LOGI(TAG, "trying to connect to %s", ssid); +const char wifi_ok[] = "verify_wifi:ok"; +const char wifi_fail[] = "verify_wifi:fail"; - WiFi.begin(ssid, pwd); - int connRes = WiFi.waitForConnectResult(); +void ProvisionSoftAP::tryConnect() +{ + ESP_LOGI(TAG, "trying to connect to %s", m_ssid); + + WiFi.begin(m_ssid, m_pwd); + int connRes = WiFi.waitForConnectResult(5000); if(connRes == WL_CONNECTED) { // all is gud! ESP_LOGI(TAG, "we're connected, sending confirmation"); + m_webSocket->textAll(wifi_ok, sizeof(wifi_ok)-1); - // m_settings.storeSsidPwd(ssid, pwd); + strcpy(SETTINGS.wifi.entry[0].ssid, m_ssid); + strcpy(SETTINGS.wifi.entry[0].pwd, m_pwd); + SETTINGS.wifi.selected = 0; + SETTINGS.wifi.num = 1; + + Settings::getInstance().saveData(); - // m_jsonBuffer.clear(); - // JsonObject& root = m_jsonBuffer.createObject(); - - // root[TYPE] = ERROR; - // root[CODE] = 0; - - // size_t len = root.printTo(m_buff, sizeof(m_buff)); - // m_webSocket->textAll(m_buff, len); - // waitBufferEmpty(); - // vTaskDelay(5000 / portTICK_PERIOD_MS); + vTaskDelay(3000 / portTICK_PERIOD_MS); + waitBufferEmpty(); ESP_LOGI(TAG, "restarting..."); esp_restart(); } - // ESP_LOGE(TAG, "nuh-uh peppernip, error %d", connRes); - // m_jsonBuffer.clear(); - // JsonObject& root = m_jsonBuffer.createObject(); - // root[TYPE] = ERROR; - // root[CODE] = 1; - // size_t len = root.printTo(m_buff, sizeof(m_buff)); - // m_webSocket->textAll(m_buff, len); - // waitBufferEmpty(); + WiFi.mode(WIFI_MODE_AP); + ESP_LOGE(TAG, "nuh-uh peppernip, error %d", connRes); + m_webSocket->textAll(wifi_fail, sizeof(wifi_fail)-1); + waitBufferEmpty(); m_webSocket->closeAll(); } diff --git a/main/ProvisionSoftAP.h b/main/ProvisionSoftAP.h index a2083bf..fcd233d 100755 --- a/main/ProvisionSoftAP.h +++ b/main/ProvisionSoftAP.h @@ -11,7 +11,7 @@ #include #include #include -// #include "ArduinoJson.h" +#include "ReaderWriter.h" #include "Settings.h" class ProvisionSoftAP @@ -20,30 +20,19 @@ private: DNSServer m_dnsServer; AsyncWebServer * m_webServer; AsyncWebSocket * m_webSocket; - wifi_event_id_t wifiEventId = 0; std::list m_clients; bool m_startWifiScan = false; bool m_tryConnect = false; - bool m_tailgate = false; - // StaticJsonBuffer<1200> m_jsonBuffer; - char m_buff[1200]; + + ReaderWriter * m_rwriter = nullptr; private: - // json stuff - const char* TYPE = "type"; - const char* WIFI_SCAN = "wifi_scan"; - const char* DATA = "data"; - const char* COMMAND = "command"; - const char* WIFI_CONFIG = "wifi_config"; - const char* SSID = "ssid"; - const char* PWD = "pwd"; - const char* ERROR = "error"; - const char* CODE = "code"; - const char* TAILGATE = "tailgate"; + char m_ssid[32] = {0}; + char m_pwd[32] = {0}; private: void parseWebsocketCommand(char *data, size_t len); - void tryConnect(const char * ssid, const char * pwd); + void tryConnect(); // callbacks void wifiEvent(arduino_event_id_t event, arduino_event_info_t info); diff --git a/main/ReaderWriter.cpp b/main/ReaderWriter.cpp new file mode 100644 index 0000000..348ad86 --- /dev/null +++ b/main/ReaderWriter.cpp @@ -0,0 +1,85 @@ +/// © MiroZ 2024 + +#include +#include +#include + +#include "ReaderWriter.h" +#include + +ReaderWriter::ReaderWriter(uint32_t buffer_len) : Parser("|"), m_buffer_len(buffer_len) +{ + assert(m_buffer = (char*)malloc(buffer_len)); + reset(); +} + +ReaderWriter::~ReaderWriter() +{ + if(m_buffer) + free(m_buffer); +} + +void ReaderWriter::reset() +{ + m_buffer[0] = 0; + m_available = m_buffer_len; + m_write_ptr = 0; +} + +/// @brief Appends str to the internal buffer +/// @param str +/// @return number of bytes left in the buffer or 0 if str can't fit in the space left. +uint32_t ReaderWriter::append(const char * str) +{ + uint32_t len = strlen(str); + + if(len + 1 > m_available) + return 0; + + strcpy(&m_buffer[m_write_ptr], str); + m_write_ptr += len; + m_available -= len; + + return m_available; +} + +uint32_t ReaderWriter::fappend(const char * format, ... ) +{ + va_list arg; + char buf[256]; + va_start(arg, format); + vsprintf(buf, format, arg); + va_end(arg); + return append(buf); +} + +uint32_t ReaderWriter::append(int32_t value, uint32_t base) +{ + String s; + char buf[32]; + itoa(value, buf, 10); + return append(buf); +} + +uint32_t ReaderWriter::append(char c) +{ + if(m_available < 2) + return 0; + + m_buffer[m_write_ptr++] = c; + m_buffer[m_write_ptr] = 0; + m_available--; + + return m_available; +} + +char * ReaderWriter::getBuffer() +{ + return m_buffer; +} + +void ReaderWriter::copyString(const char *str) +{ + reset(); + strcpy(m_buffer, str); +} diff --git a/main/ReaderWriter.h b/main/ReaderWriter.h new file mode 100644 index 0000000..1b72ce1 --- /dev/null +++ b/main/ReaderWriter.h @@ -0,0 +1,157 @@ +/// © MiroZ 2024 + +#ifndef __WRITER_H__ +#define __WRITER_H__ + +#include +#include +#include + +#include + +class Parser +{ +protected: + uint32_t m_delimiter = 0; + char * m_buffer = nullptr; + uint32_t m_num_seps = 0; + char m_seps[16] = {0}; + + bool isDelimiter(char c) + { + for(int n = 0; n < m_num_seps; n++) + { + if(c == m_seps[n]) + return true; + } + return false; + } + + bool isDelimiter(uint32_t loc) + { + return isDelimiter(m_buffer[loc]); + } + +public: + + bool hasMore(uint32_t location) + { + if(m_buffer[location] == 0) + return false; + return true; + } + + uint32_t getNthDelimiter(uint32_t nth, uint32_t start = 0) + { + if(nth == 0) + return 0; + + uint32_t count = 0; + + if(isDelimiter(m_buffer[start])) + { + start++; + } + + for(uint32_t n = 0 ;; n++) + { + if(isDelimiter(m_buffer[n+start]) || m_buffer[n+start] == 0) + { + count++; + if(count == nth) + return n + start; + } + if(m_buffer[n + start] == 0) + { + return 0xffffffff; + } + + } + return 0xffffffff; + } + + uint32_t getNextDelimiter(uint32_t start) + { + return getNthDelimiter(1, start); + } + + bool getElementAt(uint32_t index, char * value, uint32_t value_len) + { + uint32_t start = getNthDelimiter(index); + + if(!hasMore(start)) + return false; + + uint32_t end = getNextDelimiter(start); + uint32_t copied = 0; + + for(uint32_t n = start; n < end; n++) + { + if(copied >= value_len) + return false; + + if(isDelimiter(n)) + continue;; + + value[copied++] = m_buffer[n]; + } + value[copied++] = 0; + return true; + } + + bool elementIs(uint32_t index, const char * value) + { + uint32_t start = getNthDelimiter(index); + + if(!hasMore(start)) + return false; + + if(isDelimiter(start)) + start++; + + for(uint32_t n = 0 ;; n++) + { + if(value[n] == 0) + return true; + + if(m_buffer[n + start] != value[n]) + return false; + + if(m_buffer[n + start] == 0) + return false; + } + + return true; + } + +public: + + Parser(const char * separators){strncpy(m_seps, separators, sizeof(m_seps)-1); m_num_seps = strlen(separators); } + Parser(char * str, const char * separators) : Parser(separators) {m_buffer = str;} +}; + +class ReaderWriter : public Parser +{ +protected: + uint32_t m_buffer_len = 0; + uint32_t m_available = 0; + uint32_t m_write_ptr = 0; + +public: + void reset(); + uint32_t append(const char * str); + uint32_t fappend(const char * format, ... ); + uint32_t append(int32_t value, uint32_t base = 10); + uint32_t append(char c); + char * getBuffer(); + + // reader stuff + void copyString(const char *str); + +public: + ReaderWriter(uint32_t buffer_len); + virtual ~ReaderWriter(); +}; + + +#endif // __WRITER_H__ \ No newline at end of file diff --git a/main/Settings.cpp b/main/Settings.cpp index 0ca1ae5..0f1cf86 100644 --- a/main/Settings.cpp +++ b/main/Settings.cpp @@ -85,11 +85,11 @@ void Settings::setDefaults() m_data.led.brightness = 25; // 25 % - strcpy(m_data.wifi.entry[0].ssid, "gumball"); - strcpy(m_data.wifi.entry[0].pwd, "mikelemembe"); - strcpy(m_data.wifi.entry[1].ssid, "miro"); - strcpy(m_data.wifi.entry[1].pwd, "mikelemembe"); + // strcpy(m_data.wifi.entry[0].ssid, "gumball"); + // strcpy(m_data.wifi.entry[0].pwd, "mikelemembe"); + // strcpy(m_data.wifi.entry[1].ssid, "miro"); + // strcpy(m_data.wifi.entry[1].pwd, "mikelemembe"); - m_data.wifi.num = 2; - m_data.wifi.selected = 0xff; + // m_data.wifi.num = 2; + // m_data.wifi.selected = 0xff; } \ No newline at end of file diff --git a/main/Settings.h b/main/Settings.h index 051abb9..87c079f 100644 --- a/main/Settings.h +++ b/main/Settings.h @@ -70,7 +70,7 @@ struct SETTINGS_LEGACY uint32_t TEMP_OFFSET; }; -#define SETTINGS_VERSION 2 // cannot be 0 +#define SETTINGS_VERSION 3 // cannot be 0 #define SETTINGS_NUM_WIFI_ENTRIES 8 // wifi definitions @@ -127,4 +127,4 @@ public: #define SETTINGS Settings::getInstance().data() -#endif \ No newline at end of file +#endif /* __SETTINGS_H__ */ \ No newline at end of file diff --git a/main/TaskFactory.h b/main/TaskFactory.h index 8340445..b0e8dcf 100644 --- a/main/TaskFactory.h +++ b/main/TaskFactory.h @@ -39,4 +39,4 @@ public: extern TaskFactory TASK_FACTORY; -#endif \ No newline at end of file +#endif /* __TASK_FACTORY_H__ */ \ No newline at end of file diff --git a/main/Wifi.h b/main/Wifi.h index d2cf5a0..cf64ccb 100644 --- a/main/Wifi.h +++ b/main/Wifi.h @@ -30,4 +30,4 @@ public: uint32_t connect(); }; -#endif \ No newline at end of file +#endif /* __WIFI_H__ */ \ No newline at end of file diff --git a/main/utilities.h b/main/utilities.h index 1b146a5..a6d45d9 100644 --- a/main/utilities.h +++ b/main/utilities.h @@ -7,4 +7,4 @@ void dump_bytes(const void *data, uint32_t len); -#endif \ No newline at end of file +#endif /* __UTILITIES_H__ */ \ No newline at end of file