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