From bf29ccda08bef5358aabdc0b9b004f7bfe236d86 Mon Sep 17 00:00:00 2001 From: MiroZ Date: Thu, 23 May 2024 13:42:05 -0700 Subject: [PATCH] somewhat refactored wifi, still not fully clear when provision should automatically start --- Wifi.md | 17 ++++ certs/client.crt | 22 ---- certs/client.key | 28 ------ certs/mosquitto.org.crt | 24 ----- certs/mosquitto.org.crt_ | 24 ----- main/App.cpp | 41 +++++--- main/App.h | 4 + main/CMakeLists.txt | 1 - main/Mqtt.cpp | 75 +++++++++++++- main/Mqtt.h | 211 ++------------------------------------- main/OTA.cpp | 5 +- main/Settings.cpp | 4 + main/Settings.h | 7 +- main/TaskFactory.h | 3 +- main/Wifi.cpp | 120 +++++++++++++--------- main/Wifi.h | 31 ++++-- main/main.cpp | 7 +- 17 files changed, 245 insertions(+), 379 deletions(-) create mode 100644 Wifi.md delete mode 100755 certs/client.crt delete mode 100755 certs/client.key delete mode 100755 certs/mosquitto.org.crt delete mode 100755 certs/mosquitto.org.crt_ diff --git a/Wifi.md b/Wifi.md new file mode 100644 index 0000000..1c8eb01 --- /dev/null +++ b/Wifi.md @@ -0,0 +1,17 @@ +```mermaid +graph +A(Wifi start) +B[Start provision] +A-->|not provisioned +SETTINGS.wifi.num = 0|B +C{{single +or + multiple}} +A-->|provisioned +SETTINGS.wifi.num > 0|C +D[connect] +C-->|single +SETTINGS.wifi.num = 1|D + +``` + diff --git a/certs/client.crt b/certs/client.crt deleted file mode 100755 index d68de9e..0000000 --- a/certs/client.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDpDCCAoygAwIBAgIBADANBgkqhkiG9w0BAQsFADCBkDELMAkGA1UEBhMCR0Ix -FzAVBgNVBAgMDlVuaXRlZCBLaW5nZG9tMQ4wDAYDVQQHDAVEZXJieTESMBAGA1UE -CgwJTW9zcXVpdHRvMQswCQYDVQQLDAJDQTEWMBQGA1UEAwwNbW9zcXVpdHRvLm9y -ZzEfMB0GCSqGSIb3DQEJARYQcm9nZXJAYXRjaG9vLm9yZzAeFw0yNDA1MTkwMjQx -MjNaFw0yNDA4MTcwMjQxMjNaMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp -Zm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRIwEAYDVQQKDAlNaXJvIElu -Yy4xDTALBgNVBAMMBE1pcm8xHzAdBgkqhkiG9w0BCQEWEHdpbC5lQGNveW90ZS5j -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDWip9n32uj4VritcwO -/jcKcKcpqOjcY4YFFV4iltCgLLAO3xQhOp0b2QliFGhdy01jNpyoNFW3zEMQzzuJ -mGq1pTY75KVdYXT8/LLxUo4ZCZn2oIU5JdHvY5+D0B0ROXIEH9TswZf203D1qa2z -rMH+3Sl01hTyfMmwM/T2iARCgObjZmRDxUfYdjZAC0TyzSj7/2MWi9QIQ8zV5Zjp -DUlgaiMTacHLqZeqqgzGtu1Xi8f3ALWptvIZ/pJWRZn+u1qLFPZ9BBKcxzQB27EJ -YPgRE8bOX9EodCudC6rVt9v4jjIVitp6M6YJIrFMT0XqZ266NaZzcnrz19OZALpx -MXd/AgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMA0GCSqGSIb3DQEB -CwUAA4IBAQByyKl8sJbM6XyulcSrO8+0aqjQ2tFFUMqs/SpOkpG5AW8AwFW70UXC -lPCjOK4DLBJnLtZ2RvBNZTi8sIHpBx9eAxh1eScr3/B0l5TTHha/ddnrk/lLMB39 -OAVsx5ne6k+5VX6ID5siApx+KPRlyY3NfKeirpVof49Yv1ira/yXK0aFHPeTbz8+ -XkNKzUz8uItgZ/S0obcxQAVSevvuWZzpVKN9rhJp5jLbbwaV+nYHbBbXsHU/peGf -TpKeLRBPj4+NwcLz1OZp7X/BeCXAFmZyUoH514UVkl/mZUMtDEzr+Fnuct1FyFsX -B0u2/aNTp81ZP/pmcasqF9H1Y2lG9aT5 ------END CERTIFICATE----- diff --git a/certs/client.key b/certs/client.key deleted file mode 100755 index a0d8bf5..0000000 --- a/certs/client.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDWip9n32uj4Vri -tcwO/jcKcKcpqOjcY4YFFV4iltCgLLAO3xQhOp0b2QliFGhdy01jNpyoNFW3zEMQ -zzuJmGq1pTY75KVdYXT8/LLxUo4ZCZn2oIU5JdHvY5+D0B0ROXIEH9TswZf203D1 -qa2zrMH+3Sl01hTyfMmwM/T2iARCgObjZmRDxUfYdjZAC0TyzSj7/2MWi9QIQ8zV -5ZjpDUlgaiMTacHLqZeqqgzGtu1Xi8f3ALWptvIZ/pJWRZn+u1qLFPZ9BBKcxzQB -27EJYPgRE8bOX9EodCudC6rVt9v4jjIVitp6M6YJIrFMT0XqZ266NaZzcnrz19OZ -ALpxMXd/AgMBAAECggEAYpMO6wscyg+hUsl1GO51G7bnF50kYR7ZVTycJAhnkzD1 -M+ALv7jOtxzh0s7NpUrkI9HT6PUi7XBM4ExXbsE5RnzCjoJf+KfuuM7i6T6lS5u9 -wjO/AqL98qAzirz0nhVm7b4ydxX8XMyJ+lYcGZInEJNNmQFEXqY3hV5aD2wviN4Z -oiOR4uzHceR+6ADGzsnL/Kf5wGjZqAZE9+keVlsgJ/GrOHVFGhFdWlX0crAyezbf -U6TAgzdE/xoDIV6mYfLxUsWKl/Ty6ubLXRrAqmKxeigR2guYYWeS2h/caJ3zuIfV -51thJqaeTCTW4KPta3CEft4tuyiNxhW8CKbGHxIbAQKBgQDf3f3/w6ovtzf/ROC7 -UeBi2qGFMFioxZxlSSgEJEyGFSiHk9y0K5jMBivyU6fyEz6fm/7XUFpzuxv1yFai -JZP9rUIPtnRTxEyL5dP7O0aX8DF2DtLgdBWLo2xh9bGalov9TOnM9B9ByD5d4Alj -UkYcR+3+cLcNRkKAVz175+XYewKBgQD1VfVqs86PTKtvu8ft4hNzGZRbyZzGdUGM -BSOu49KG319evqmjqsGzmkM28PqIouVH0vJ2W5uKJpQ964D+X1TnSrjOlZihdyNp -O4k5tMYTKjBKvsGPvm+Xhu385poCnra5r/9h16D/+q0S5nfSr0WkM/UeIzBVnPVX -WfOLNHtHzQKBgFUW/cpPRsqoK2KdfYX1kwI/85C6VZigs9dTvSAF5Ag61pLhwsvA -nm0+E0oiPf2nDvB/zJdudVLz1abQJQ2wltWfGzL5uLF2NVofWzlsyGJL66Dh9YlW -1jGjRjjduEn32vHGYD+EsrTANeRcmXTk+r0ZIf7KPOmQwQojHr2P4S8tAoGAODF3 -I/iJUHNMNSx6r7b/o3Zxb9CvExnaaJrowG84UmIpcwcSzgUXlu63hIcPq2o8QAZG -OOvkpXEOtVwS0LC/Prbzu4WyTxF9z+WuGcSZNdyM8SHeLfF9l+R08F9VWVJHIiL4 -yM1d+CPPrquROHWi6uhntX5z3Lg1zcsxqGnd7uUCgYBkq/I1bV+vGY4Vh3FuzJOa -XIEHmquei6pPuHPgSBPYZSu87uIyIwcZSGBVsRqbXyIKPhzDZ/SOe0fBh/SZD0QH -6bfhA2BwF4PyhtFyX5cwsiWMurCTjspws5fCT0KqikgkjXC/IlDAioB2an+lsPTz -71KGRyxMkyHbcthk9/uPOg== ------END PRIVATE KEY----- diff --git a/certs/mosquitto.org.crt b/certs/mosquitto.org.crt deleted file mode 100755 index e76dbd8..0000000 --- a/certs/mosquitto.org.crt +++ /dev/null @@ -1,24 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEAzCCAuugAwIBAgIUBY1hlCGvdj4NhBXkZ/uLUZNILAwwDQYJKoZIhvcNAQEL -BQAwgZAxCzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5Vbml0ZWQgS2luZ2RvbTEOMAwG -A1UEBwwFRGVyYnkxEjAQBgNVBAoMCU1vc3F1aXR0bzELMAkGA1UECwwCQ0ExFjAU -BgNVBAMMDW1vc3F1aXR0by5vcmcxHzAdBgkqhkiG9w0BCQEWEHJvZ2VyQGF0Y2hv -by5vcmcwHhcNMjAwNjA5MTEwNjM5WhcNMzAwNjA3MTEwNjM5WjCBkDELMAkGA1UE -BhMCR0IxFzAVBgNVBAgMDlVuaXRlZCBLaW5nZG9tMQ4wDAYDVQQHDAVEZXJieTES -MBAGA1UECgwJTW9zcXVpdHRvMQswCQYDVQQLDAJDQTEWMBQGA1UEAwwNbW9zcXVp -dHRvLm9yZzEfMB0GCSqGSIb3DQEJARYQcm9nZXJAYXRjaG9vLm9yZzCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAME0HKmIzfTOwkKLT3THHe+ObdizamPg -UZmD64Tf3zJdNeYGYn4CEXbyP6fy3tWc8S2boW6dzrH8SdFf9uo320GJA9B7U1FW -Te3xda/Lm3JFfaHjkWw7jBwcauQZjpGINHapHRlpiCZsquAthOgxW9SgDgYlGzEA -s06pkEFiMw+qDfLo/sxFKB6vQlFekMeCymjLCbNwPJyqyhFmPWwio/PDMruBTzPH -3cioBnrJWKXc3OjXdLGFJOfj7pP0j/dr2LH72eSvv3PQQFl90CZPFhrCUcRHSSxo -E6yjGOdnz7f6PveLIB574kQORwt8ePn0yidrTC1ictikED3nHYhMUOUCAwEAAaNT -MFEwHQYDVR0OBBYEFPVV6xBUFPiGKDyo5V3+Hbh4N9YSMB8GA1UdIwQYMBaAFPVV -6xBUFPiGKDyo5V3+Hbh4N9YSMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBAGa9kS21N70ThM6/Hj9D7mbVxKLBjVWe2TPsGfbl3rEDfZ+OKRZ2j6AC -6r7jb4TZO3dzF2p6dgbrlU71Y/4K0TdzIjRj3cQ3KSm41JvUQ0hZ/c04iGDg/xWf -+pp58nfPAYwuerruPNWmlStWAXf0UTqRtg4hQDWBuUFDJTuWuuBvEXudz74eh/wK -sMwfu1HFvjy5Z0iMDU8PUDepjVolOCue9ashlS4EB5IECdSR2TItnAIiIwimx839 -LdUdRudafMu5T5Xma182OC0/u/xRlEm+tvKGGmfFcN0piqVl8OrSPBgIlb+1IKJE -m/XriWr/Cq4h/JfB7NTsezVslgkBaoU= ------END CERTIFICATE----- diff --git a/certs/mosquitto.org.crt_ b/certs/mosquitto.org.crt_ deleted file mode 100755 index e76dbd8..0000000 --- a/certs/mosquitto.org.crt_ +++ /dev/null @@ -1,24 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEAzCCAuugAwIBAgIUBY1hlCGvdj4NhBXkZ/uLUZNILAwwDQYJKoZIhvcNAQEL -BQAwgZAxCzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5Vbml0ZWQgS2luZ2RvbTEOMAwG -A1UEBwwFRGVyYnkxEjAQBgNVBAoMCU1vc3F1aXR0bzELMAkGA1UECwwCQ0ExFjAU -BgNVBAMMDW1vc3F1aXR0by5vcmcxHzAdBgkqhkiG9w0BCQEWEHJvZ2VyQGF0Y2hv -by5vcmcwHhcNMjAwNjA5MTEwNjM5WhcNMzAwNjA3MTEwNjM5WjCBkDELMAkGA1UE -BhMCR0IxFzAVBgNVBAgMDlVuaXRlZCBLaW5nZG9tMQ4wDAYDVQQHDAVEZXJieTES -MBAGA1UECgwJTW9zcXVpdHRvMQswCQYDVQQLDAJDQTEWMBQGA1UEAwwNbW9zcXVp -dHRvLm9yZzEfMB0GCSqGSIb3DQEJARYQcm9nZXJAYXRjaG9vLm9yZzCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAME0HKmIzfTOwkKLT3THHe+ObdizamPg -UZmD64Tf3zJdNeYGYn4CEXbyP6fy3tWc8S2boW6dzrH8SdFf9uo320GJA9B7U1FW -Te3xda/Lm3JFfaHjkWw7jBwcauQZjpGINHapHRlpiCZsquAthOgxW9SgDgYlGzEA -s06pkEFiMw+qDfLo/sxFKB6vQlFekMeCymjLCbNwPJyqyhFmPWwio/PDMruBTzPH -3cioBnrJWKXc3OjXdLGFJOfj7pP0j/dr2LH72eSvv3PQQFl90CZPFhrCUcRHSSxo -E6yjGOdnz7f6PveLIB574kQORwt8ePn0yidrTC1ictikED3nHYhMUOUCAwEAAaNT -MFEwHQYDVR0OBBYEFPVV6xBUFPiGKDyo5V3+Hbh4N9YSMB8GA1UdIwQYMBaAFPVV -6xBUFPiGKDyo5V3+Hbh4N9YSMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBAGa9kS21N70ThM6/Hj9D7mbVxKLBjVWe2TPsGfbl3rEDfZ+OKRZ2j6AC -6r7jb4TZO3dzF2p6dgbrlU71Y/4K0TdzIjRj3cQ3KSm41JvUQ0hZ/c04iGDg/xWf -+pp58nfPAYwuerruPNWmlStWAXf0UTqRtg4hQDWBuUFDJTuWuuBvEXudz74eh/wK -sMwfu1HFvjy5Z0iMDU8PUDepjVolOCue9ashlS4EB5IECdSR2TItnAIiIwimx839 -LdUdRudafMu5T5Xma182OC0/u/xRlEm+tvKGGmfFcN0piqVl8OrSPBgIlb+1IKJE -m/XriWr/Cq4h/JfB7NTsezVslgkBaoU= ------END CERTIFICATE----- diff --git a/main/App.cpp b/main/App.cpp index e94f6b4..7a7a383 100644 --- a/main/App.cpp +++ b/main/App.cpp @@ -16,7 +16,7 @@ #define LED_PIN 26 -//static const char * TAG = "app"; +static const char * TAG = "app"; App::App() { @@ -34,18 +34,21 @@ void App::init() { // try connecting m_led->setColor(0, 255, 0); - uint32_t status = m_wifi->start(); - if(status == WH_OK) + m_wifi->start(); + + Wifi::WIFI_STATUS wifi_status = m_wifi->waitForConnection(); + + if(wifi_status == Wifi::WIFI_STATUS::CONNECTED) { - ESP_LOGI(TAG, "Getting local time"); + ESP_LOGI(TAG, "Getting local time..."); struct tm timeinfo; configTime(0, 0, "pool.ntp.org"); if(getLocalTime(&timeinfo)) - ESP_LOGI(TAG, "Got local time"); + ESP_LOGI(TAG, "ok"); else - ESP_LOGE(TAG, "Failed to get local time"); + ESP_LOGE(TAG, "Failed"); - m_led->setColor(0, 0, 0); + // m_led->setColor(0, 0, 0); MDNS.begin("esp32"); needs_provision = false; } @@ -58,21 +61,27 @@ void App::init() provision.start(); } + otaCheck(); + + m_led->setPulse(255, 0, 255); + + m_mqtt = new Mqtt(); + m_mqtt->start(); + +} + +void App::otaCheck() +{ ota_update::OTA ota(*this); ota.start(); - m_led->setColor(0, 0, 0); - - Mqtt m; - m.test(); - // Mqtt::test(); } void App::start() { - while(true) - { - vTaskDelay(pdMS_TO_TICKS(10020)); - } + // while(true) + // { + // vTaskDelay(pdMS_TO_TICKS(10020)); + // } } void App::readSensors() diff --git a/main/App.h b/main/App.h index 4280473..246d522 100644 --- a/main/App.h +++ b/main/App.h @@ -8,17 +8,21 @@ #include "Settings.h" #include "Led.h" #include "Wifi.h" +#include "Mqtt.h" class App { protected: Wifi * m_wifi = nullptr; + Mqtt * m_mqtt = nullptr; public: Led * m_led = nullptr; public: App(); + + void otaCheck(); void init(); void start(); void readSensors(); diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index caafa46..56ac3d5 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -3,7 +3,6 @@ idf_component_register(SRCS main.cpp App.cpp Settings.cpp Led.cpp TaskFactory.cp INCLUDE_DIRS "." EMBED_TXTFILES ../html/logo.png ../html/provision.html EMBED_TXTFILES ../certs/eventgrid.azure.pem ../certs/client1-authn-ID.key ../certs/client1-authn-ID.pem - EMBED_TXTFILES ../certs/mosquitto.org.crt ../certs/client.crt ../certs/client.key ) #message(FATAL_ERROR "error ${ROLE}") diff --git a/main/Mqtt.cpp b/main/Mqtt.cpp index 820814b..2d534a4 100644 --- a/main/Mqtt.cpp +++ b/main/Mqtt.cpp @@ -2,6 +2,77 @@ #include "Mqtt.h" -extern const uint8_t logo_png_start[] asm("_binary_eventgrid_azure_pem_start"); -extern const uint8_t logo_png_end[] asm("_binary_eventgrid_azure_pem_end"); +#include +#include "TaskFactory.h" +static const char * mqtt_broker = "mqtt-dev-server.westus2-1.ts.eventgrid.azure.net"; +static const char * topic = "wellnuotopics/topic1"; +static const int mqtt_port = 8883; + +static const char * TAG = "mqtts"; + +void Mqtt::callback(char* topic, uint8_t * payload, uint32_t length) +{ + ESP_LOGI(TAG, "Message arrived in topic: %s\n", topic); + payload[length] = 0; + ESP_LOGW(TAG, "%s", (char*)payload); +} + +void Mqtt::task() +{ + while(true) + { + while (!m_mqtt_client->connected()) + { + ESP_LOGI(TAG, "connecting to mqtt broker..."); + if (m_mqtt_client->connect("Esp32 client", "client1-authn-ID", NULL)) + ESP_LOGI(TAG, "connected"); + else + { + ESP_LOGE(TAG, "failed with state %d", m_mqtt_client->state()); + delay(5000); + } + } + + int n = 0; + + while(true) + { + if(!m_mqtt_client->connected()) + break; + + m_mqtt_client->loop(); + + ESP_LOGI(TAG, "publishing..."); + bool val = m_mqtt_client->publish(topic, "Hi I'm ESP32 ^^"); + + if(val) + ESP_LOGI(TAG, "%d publish ok", n); + else + ESP_LOGE(TAG, "%d publish failed", n); + + ESP_LOGI(TAG, "%d", TaskFactory::getStackHighWaterMark()); + + delay(50000); + + n++; + } + } +} + +void Mqtt::start() +{ + ESP_LOGW(TAG, "Starting mqtt"); + + m_esp_client = new WiFiClientSecure(); + m_mqtt_client = new PubSubClient(*m_esp_client); + + m_esp_client->setCACert((const char*)server_cert); + m_esp_client->setCertificate((const char *)client_cert); // for client verification + m_esp_client->setPrivateKey((const char *)client_key); // for client verification + + m_mqtt_client->setServer(mqtt_broker, mqtt_port); + m_mqtt_client->setCallback(std::bind(&Mqtt::callback, this, _1, _2, _3)); + + m_task = TASK_FACTORY.createTask(std::bind(&Mqtt::task, this), "mqtt task", 6144, 5, 0); +} \ No newline at end of file diff --git a/main/Mqtt.h b/main/Mqtt.h index 7557033..d2fe13e 100644 --- a/main/Mqtt.h +++ b/main/Mqtt.h @@ -4,224 +4,31 @@ #define __MQTT_T__ #include -#include #include #include #include #include "mqtt_client.h" -static const char *TAG = "MQTTS"; - extern const uint8_t server_cert[] asm("_binary_eventgrid_azure_pem_start"); extern const uint8_t client_cert[] asm("_binary_client1_authn_ID_pem_start"); extern const uint8_t client_key[] asm("_binary_client1_authn_ID_key_start"); -extern const uint8_t test_cert[] asm("_binary_mosquitto_org_crt_start"); -extern const uint8_t test_client_cert[] asm("_binary_client_crt_start"); -extern const uint8_t test_client_key[] asm("_binary_client_key_start"); - -esp_mqtt_client_handle_t client; - using namespace std::placeholders; class Mqtt { -#if 0 +protected: + WiFiClientSecure *m_esp_client; + PubSubClient *m_mqtt_client; + void callback(char* topic, uint8_t * payload, uint32_t length); + + TaskHandle_t m_task = nullptr; + void task(); + public: + void start(); -static void log_error_if_nonzero(const char *message, int error_code) -{ - if (error_code != 0) { - ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code); - } -} - - -static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) -{ - ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id); - esp_mqtt_event_handle_t event = (esp_mqtt_event_handle_t)event_data; - esp_mqtt_client_handle_t client = event->client; - int msg_id; - switch ((esp_mqtt_event_id_t)event_id) { - case MQTT_EVENT_CONNECTED: - ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); -// msg_id = esp_mqtt_client_subscribe(client, "wellnuotopics/topic1", 0); -// ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); - - // msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1); - // ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); - - // msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1"); - // ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id); - break; - case MQTT_EVENT_DISCONNECTED: - ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); - break; - - case MQTT_EVENT_SUBSCRIBED: - ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id); - msg_id = esp_mqtt_client_publish(client, "wellnuotopics/topic1", "0", 0, 0, 0); - ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id); - break; - case MQTT_EVENT_UNSUBSCRIBED: - ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id); - break; - case MQTT_EVENT_PUBLISHED: - ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id); - break; - case MQTT_EVENT_DATA: - ESP_LOGI(TAG, "MQTT_EVENT_DATA"); - printf("TOPIC=%.*s\r\n", event->topic_len, event->topic); - printf("DATA=%.*s\r\n", event->data_len, event->data); - break; - case MQTT_EVENT_ERROR: - ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); - if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) { - log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err); - log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err); - log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno); - ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno)); - - } - break; - default: - ESP_LOGI(TAG, "Other event id:%d", event->event_id); - break; - } -} - - -static void mqtt_app_start(void) -{ - esp_mqtt_client_config_t mqtt_cfg; - memset(&mqtt_cfg, 0, sizeof(mqtt_cfg)); - - // test server - // mqtt_cfg.uri = "mqtts://test.mosquitto.org:8884"; - // mqtt_cfg.cert_pem = (const char *)test_cert; - // mqtt_cfg.client_key_pem = (const char *)test_client_key; - // mqtt_cfg.client_cert_pem = (const char *)test_client_cert; - mqtt_cfg.uri = "mqtts://mqtt-dev-server.westus2-1.ts.eventgrid.azure.net:8883"; - mqtt_cfg.username = "client1-authn-ID"; - mqtt_cfg.client_id = "client1-esp"; - mqtt_cfg.cert_pem = (const char *)server_cert; - mqtt_cfg.client_key_pem = (const char *)client_key; - mqtt_cfg.client_cert_pem = (const char *)client_cert; - - - ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size()); - client = esp_mqtt_client_init(&mqtt_cfg); - /* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */ - esp_mqtt_client_register_event(client, (esp_mqtt_event_id_t)ESP_EVENT_ANY_ID, mqtt_event_handler, NULL); - esp_mqtt_client_start(client); -} - -static void test() -{ - mqtt_app_start(); - - while(true) - { - delay(5000); - int val = esp_mqtt_client_publish (client, "wellnuotopics/topic1", "mytestdata", 10, 0, false); - ESP_LOGI(TAG, "publish: %d", val); - } -} -#endif -public: -#if 1 - void callback(char* topic, byte* payload, unsigned int length) { - printf("Message arrived in topic: %s\n", topic); - printf("Message:'"); - for (int i = 0; i < length; i++) { - printf("%c", (char)payload[i]); - } - printf("'\n"); - printf("-----------------------\n"); - } - -#include "time.h" - - - void printLocalTime() - { - struct tm timeinfo; - char buf[48]; - if(!getLocalTime(&timeinfo)){ - printf("Failed to obtain time\n"); - return; - } - strftime(buf, 26, "%Y-%m-%d %H:%M:%S", &timeinfo); - ESP_LOGI(TAG, "%s", buf); - } - - void test() - { - const char* mqtt_broker = "mqtt-dev-server.westus2-1.ts.eventgrid.azure.net"; - const char* topic = "wellnuotopics/topic1"; - const int mqtt_port = 8883 ; - - WiFiClientSecure espClient; - PubSubClient client(espClient); - - espClient.setCACert((const char*)server_cert); - espClient.setCertificate((const char *)client_cert); // for client verification - espClient.setPrivateKey((const char *)client_key); // for client verification - - client.setServer(mqtt_broker, mqtt_port); - client.setCallback(std::bind(&Mqtt::callback, this, _1, _2, _3)); - - printLocalTime(); - - while (!client.connected()) - { - String client_id = "esp32-client"; - client_id += String(WiFi.macAddress()); - // Print the Name and the id of the esp32 controller - ESP_LOGI("", "connecting client %s mqtt broker...", client_id.c_str()); - if (client.connect("Esp32 client", "client1-authn-ID", NULL)) { - ESP_LOGI("", "Public emqx mqtt broker connected"); - } else { - ESP_LOGE("", "failed with state %d", client.state()); - delay(5000); - } - } - - bool val; - - // val = client.subscribe(topic); - // if(val) - // ESP_LOGI(TAG, "sub ok"); - // else - // ESP_LOGI(TAG, "sub failed"); - // Publish and Subscribe - - // val = client.publish(topic, "Hi I'm ESP32 ^^"); - // if(val) - // ESP_LOGI(TAG, "publish ok"); - // else - // ESP_LOGI(TAG, "publish failed"); - - int n = 0; - - while(true) - { -// client.loop(); - delay(2500); - - val = client.publish(topic, "Hi I'm ESP32 ^^"); - if(val) - ESP_LOGI(TAG, "%d publish ok", n); - else - ESP_LOGE(TAG, "%d publish failed", n); - - n++; - } - - } -#endif }; #endif \ No newline at end of file diff --git a/main/OTA.cpp b/main/OTA.cpp index 6f792b3..3d80ef8 100644 --- a/main/OTA.cpp +++ b/main/OTA.cpp @@ -166,12 +166,12 @@ void OTA::start() if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version) + sizeof(new_app_info.project_name) + sizeof(new_app_info.time) + sizeof(new_app_info.date)) == 0) { - ESP_LOGW(TAG, "Current running version is the same as a remote. No need for update."); + ESP_LOGI(TAG, "Current running version is the same as a remote. No need for update."); httpCleanup(client); return; } - m_app.m_led->setPulse(255, 0, 255); + m_app.m_led->setPulse(255, 255, 0); image_header_was_checked = true; @@ -190,7 +190,6 @@ void OTA::start() httpCleanup(client); taskFatalError(); } - } err = esp_ota_write(update_handle, (const void *) otaWriteData, data_read); diff --git a/main/Settings.cpp b/main/Settings.cpp index 0f1cf86..9408a75 100644 --- a/main/Settings.cpp +++ b/main/Settings.cpp @@ -8,6 +8,7 @@ #include "Settings.h" #include "errors.h" #include +#include static const char *TAG = "Settings"; @@ -84,6 +85,9 @@ void Settings::setDefaults() m_data.version = SETTINGS_VERSION; m_data.led.brightness = 25; // 25 % + m_data.wifi.subnet_mask = PP_HTONL(LWIP_MAKEU32(255, 255, 255, 0)); + m_data.wifi.dns_primary = PP_HTONL(LWIP_MAKEU32(8, 8, 8, 8)); + m_data.wifi.dns_secondary = PP_HTONL(LWIP_MAKEU32(8, 8, 4, 4)); // strcpy(m_data.wifi.entry[0].ssid, "gumball"); // strcpy(m_data.wifi.entry[0].pwd, "mikelemembe"); diff --git a/main/Settings.h b/main/Settings.h index 776a479..1cefb65 100644 --- a/main/Settings.h +++ b/main/Settings.h @@ -70,7 +70,7 @@ struct SETTINGS_LEGACY uint32_t TEMP_OFFSET; }; -#define SETTINGS_VERSION 4 // cannot be 0 +#define SETTINGS_VERSION 2 // cannot be 0 #define SETTINGS_NUM_WIFI_ENTRIES 8 // wifi definitions @@ -87,6 +87,11 @@ struct WIFI uint8_t always_scan_before_connect; struct WIFI_ENTRY entry[SETTINGS_NUM_WIFI_ENTRIES]; uint8_t selected; + + // network stuff + uint32_t subnet_mask; + uint32_t dns_primary; + uint32_t dns_secondary; }; // diff --git a/main/TaskFactory.h b/main/TaskFactory.h index a1fd247..1439ef3 100644 --- a/main/TaskFactory.h +++ b/main/TaskFactory.h @@ -29,7 +29,8 @@ protected: public: TaskHandle_t createTask(TASK_FUNCTION task_function, const char *name, uint32_t stack_size, UBaseType_t priority, BaseType_t core); - static uint32_t getStackHighWaterMark(TaskHandle_t task){ return (uint32_t)uxTaskGetStackHighWaterMark(task); } + static uint32_t getStackHighWaterMark(TaskHandle_t task = NULL){ return (uint32_t)uxTaskGetStackHighWaterMark(task); } + static void deleteTask(TaskHandle_t task = NULL){ vTaskDelete(task); } TaskFactory(); ~TaskFactory(); diff --git a/main/Wifi.cpp b/main/Wifi.cpp index d8c973f..1f37877 100644 --- a/main/Wifi.cpp +++ b/main/Wifi.cpp @@ -18,30 +18,30 @@ Wifi::Wifi() esp_log_level_set("wifi", ESP_LOG_WARN); esp_log_level_set("wifi_init", ESP_LOG_INFO); - // memset(m_ignored, 0, SETTINGS_NUM_WIFI_ENTRIES); WiFi.onEvent(std::bind(&Wifi::wifi_event, this, _1, _2)); - - // esp_timer_create_args_t timer; - // timer.arg = this; - // timer.callback = &timerCallback; - // timer.dispatch_method = ESP_TIMER_TASK; - // timer.skip_unhandled_events = true; - // timer.name = "wifi countdown timer"; +#ifdef USE_TIMER + esp_timer_create_args_t timer; + timer.arg = this; + timer.callback = &timerCallback; + timer.dispatch_method = ESP_TIMER_TASK; + timer.skip_unhandled_events = true; + timer.name = "wifi countdown timer"; - // ESP_ERROR_CHECK(esp_timer_create(&timer, &m_timer)); - // ESP_ERROR_CHECK(esp_timer_start_periodic(m_timer, 60000000)); // 1 min - - // m_task = TASK_FACTORY.createTask(std::bind(&Wifi::wifiTask, this), "wifi task", 2048, 5, 0); + ESP_ERROR_CHECK(esp_timer_create(&timer, &m_timer)); + ESP_ERROR_CHECK(esp_timer_start_periodic(m_timer, 60000000)); // 1 min +#endif } -// void Wifi::timerCallback(void* arg) -// { -// for(int n = 0; n < SETTINGS_NUM_WIFI_ENTRIES; n++) -// { -// if(((Wifi*)arg)->m_ignored[n] > 0) -// ((Wifi*)arg)->m_ignored[n]--; -// } -// } +#ifdef USE_TIMER +void Wifi::timerCallback(void* arg) +{ + for(int n = 0; n < SETTINGS_NUM_WIFI_ENTRIES; n++) + { + if(((Wifi*)arg)->m_ignored[n] > 0) + ((Wifi*)arg)->m_ignored[n]--; + } +} +#endif void Wifi::wifi_event(arduino_event_id_t event, arduino_event_info_t info) { @@ -53,25 +53,29 @@ void Wifi::wifi_event(arduino_event_id_t event, arduino_event_info_t info) } } -// void Wifi::wifiTask() -// { -// while(true) -// { -// delay(1000); -// ESP_LOGI(TAG, "in wifi task!"); -// } -// } +void Wifi::task() +{ + while(true) + { + if(!WiFi.isConnected()) + { + m_wifi_status = WIFI_STATUS::PENDING; + m_wifi_status = startConnecting(); + } + delay(15000); + } +} /// @brief Connect to provisioned wifi /// @param index index of wifi in settings -/// @return ok/not connected -uint32_t Wifi::connectTo(int index) +/// @return WIFI_STATUS::CONNECTED/NOT_CONENCTED connected +Wifi::WIFI_STATUS Wifi::connectTo(int index) { IPAddress local_IP(0, 0, 0, 0); IPAddress gateway(0, 0, 0, 0); - IPAddress subnet(255, 255, 255, 0); - IPAddress primaryDNS(8, 8, 8, 8); - IPAddress secondaryDNS(8, 8, 4, 4); + IPAddress subnet(SETTINGS.wifi.subnet_mask); + IPAddress primaryDNS(SETTINGS.wifi.dns_primary); + IPAddress secondaryDNS(SETTINGS.wifi.dns_secondary); ESP_LOGI(TAG, "Connecting to %s...", SETTINGS.wifi.entry[index].ssid); @@ -85,25 +89,45 @@ uint32_t Wifi::connectTo(int index) if(status == WL_CONNECTED) { ESP_LOGI(TAG, "Connected"); - return WH_OK; + return WIFI_STATUS::CONNECTED; } WiFi.disconnect(); ESP_LOGW(TAG, "Failed to connect"); - return WH_ERR_WIFI_NOT_CONNECTED; + return WIFI_STATUS::NOT_CONNECTED; +} + +int Wifi::start() +{ + if(m_task == nullptr) + { + ESP_LOGW(TAG, "Starting wifi"); + m_task = TASK_FACTORY.createTask(std::bind(&Wifi::task, this), "wifi task", 4096, 5, 0); + } + return 0; +} + +Wifi::WIFI_STATUS Wifi::waitForConnection() +{ + Wifi::WIFI_STATUS st; + + while((st = status()) == Wifi::WIFI_STATUS::PENDING) + delay(500); + + return st; } /// @brief Connects to wifi. Returns immediately if already connected. /// @return WH_OK | WH_ERR_WIFI_NOT_PROVISIONED -uint32_t Wifi::start() +Wifi::WIFI_STATUS Wifi::startConnecting() { if(SETTINGS.wifi.num == 0) { ESP_LOGE(TAG, "Not provisioned!"); - return WH_ERR_WIFI_NOT_PROVISIONED; + return WIFI_STATUS::NOT_PROVISIONED; } if(WiFi.isConnected()) - return WH_OK; + return WIFI_STATUS::CONNECTED; // if only one network is provisioned if(SETTINGS.wifi.num == 1) @@ -111,14 +135,14 @@ uint32_t Wifi::start() SETTINGS.wifi.selected = 0; for(int n = 0; n < 3; n++) { - if(connectTo(SETTINGS.wifi.selected) == WH_OK) - return WH_OK; + if(connectTo(SETTINGS.wifi.selected) == WIFI_STATUS::CONNECTED) + return WIFI_STATUS::CONNECTED; WiFi.disconnect(); } - ESP_LOGW(TAG, "Cannot connect, need provisioning"); - return WH_ERR_WIFI_NOT_PROVISIONED; + ESP_LOGE(TAG, "Not connected"); + return WIFI_STATUS::NOT_CONNECTED; } // multiple networks are provisioned. Use either specific network or scan for highest rssi @@ -130,12 +154,12 @@ uint32_t Wifi::start() ssid_ix = scan(); if(ssid_ix < 0) - return WH_ERR_WIFI_NOT_PROVISIONED; + return WIFI_STATUS::NOT_PROVISIONED; if(connectTo(ssid_ix) == WH_OK) { SETTINGS.wifi.selected = ssid_ix; - return WH_OK; + return WIFI_STATUS::CONNECTED; } // didn't work. go through them all giving priority to one with highest rssi @@ -148,7 +172,7 @@ uint32_t Wifi::start() if(ssid_ix >= 0) { if(connectTo(ssid_ix) == WH_OK) - return WH_OK; + return WIFI_STATUS::CONNECTED; else m_ignored[ssid_ix] = IGNORE_SSID_MINS; } @@ -164,12 +188,12 @@ uint32_t Wifi::start() for(int n = 0; n < SETTINGS.wifi.num; n++) { if(connectTo(n) == WH_OK) - return WH_OK; + return WIFI_STATUS::CONNECTED; } } - ESP_LOGW(TAG, "Cannot connect, need provisioning"); - return WH_ERR_WIFI_NOT_PROVISIONED; + ESP_LOGE(TAG, "Cannot connect, need provisioning"); + return WIFI_STATUS::NOT_PROVISIONED; } /// @brief Scans all visible ssid's and picks known ssid with highest rssi that is not ignored. diff --git a/main/Wifi.h b/main/Wifi.h index 556cb79..cb1f3e5 100644 --- a/main/Wifi.h +++ b/main/Wifi.h @@ -8,16 +8,33 @@ #include "Settings.h" #include "TaskFactory.h" +#define _USE_TIMER + class Wifi { +public: + typedef enum + { + NOT_CONNECTED, + PENDING, + NOT_PROVISIONED, + CONNECTED + } WIFI_STATUS; + protected: uint8_t m_ignored[SETTINGS_NUM_WIFI_ENTRIES]; - // esp_timer_handle_t m_timer; - // static void timerCallback(void* arg); - // TaskHandle_t m_task = nullptr; - // void wifiTask(); + WIFI_STATUS m_wifi_status = WIFI_STATUS::NOT_CONNECTED; - uint32_t connectTo(int index); +#ifdef USE_TIMER + esp_timer_handle_t m_timer; + static void timerCallback(void* arg); +#endif + + TaskHandle_t m_task = nullptr; + void task(); + + WIFI_STATUS startConnecting(); + WIFI_STATUS connectTo(int index); int scan(); public: @@ -27,7 +44,9 @@ protected: void wifi_event(arduino_event_id_t event, arduino_event_info_t info); public: - uint32_t start(); + int start(); + WIFI_STATUS status() { return m_wifi_status; } + WIFI_STATUS waitForConnection(); }; #endif /* __WIFI_H__ */ \ No newline at end of file diff --git a/main/main.cpp b/main/main.cpp index 35d9660..51e0fe6 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "TaskFactory.h" #include "esp_task_wdt.h" #include "App.h" @@ -19,9 +20,13 @@ extern "C" void app_main(void) ESP_ERROR_CHECK(esp_task_wdt_init(15, false)); - ESP_LOGI(TAG, "Starting app..."); + ESP_LOGW(TAG, "Starting the app..."); App * app = new App(); app->init(); app->start(); + ESP_LOGI(TAG, "stack high water mark %d", TaskFactory::getStackHighWaterMark()); + + // we're no longer needed + TaskFactory::deleteTask(); } \ No newline at end of file