فهرست منبع

DK-31 save and reset pairing

Bence Balint 3 سال پیش
والد
کامیت
e180fd9ce7

+ 5 - 4
components/dk/CMakeLists.txt

@@ -5,10 +5,11 @@ idf_component_register(
         "src/dk.cpp"
         "src/settings_manager.cpp"
 
-        "src/controllers/pair_controller.cpp"
-        "src/controllers/scan_controller.cpp"
-        "src/controllers/settings_controller.cpp"
-        "src/controllers/verify_controller.cpp"
+        "src/pairing_service/pair_controller.cpp"
+        "src/pairing_manager.cpp"
+        "src/pairing_service/scan_controller.cpp"
+        "src/pairing_service/settings_controller.cpp"
+        "src/pairing_service/verify_controller.cpp"
 
         INCLUDE_DIRS
         "include"

+ 12 - 3
components/dk/include/dk.h

@@ -4,18 +4,27 @@
 #include <kbf/driver/button.h>
 #include <kbf/driver/lcd.h>
 #include <kbf/net.h>
+#include <kbf/rtos.h>
 #include <kbf/web_service.h>
 
 namespace dk {
     const constexpr char *const TAG = "dk";
 
-    extern kbf::WebService webService;
+    extern kbf::WebService pairingService;
     extern kbf::net::MDNS  *mdns;
 
-    extern kbf::driver::LCD lcd;
+    extern kbf::driver::LCD    lcd;
     extern kbf::driver::Button *button;
 
-    void main(void *);
+    extern kbf::rtos::EventGroup eventGroup;
+
+    [[noreturn]] void main(void *);
+
+    void setPairing(const std::string &pairingId);
+
+    void clearPairing();
+
+    bool paired();
 }
 
 #endif //DK_H

+ 11 - 0
components/dk/include/pairing_manager.h

@@ -0,0 +1,11 @@
+#ifndef DOORKEEPER_DEV_PAIRING_MANAGER_H
+#define DOORKEEPER_DEV_PAIRING_MANAGER_H
+
+class PairingManager {
+public:
+    PairingManager();
+
+
+};
+
+#endif //DOORKEEPER_DEV_PAIRING_MANAGER_H

+ 124 - 38
components/dk/src/dk.cpp

@@ -1,5 +1,8 @@
 #include "dk.h"
 
+#include <vector>
+#include <atomic>
+
 #include <freertos/FreeRTOS.h>
 #include <freertos/task.h>
 #include <kbf.h>
@@ -9,14 +12,85 @@
 
 #include "settings_manager.h"
 #include "controllers/pair_controller.h"
-#include "controllers/scan_controller.h"
 #include "controllers/settings_controller.h"
 #include "controllers/verify_controller.h"
 
 
+#define MESSAGE_TIMEOUT 1000 // TODO use Kconfig
+
+
 using namespace kbf;
+using std::vector;
+using std::atomic;
 
 namespace dk {
+    void handleConnect(wifi::AP::STA &sta);
+
+    void setupPairingMode();
+
+    void setupArmedMode();
+
+    void testNotification();
+
+    rtos::EventGroup       eventGroup;
+    struct Events {
+        static const unsigned int SET_PAIRING_MODE = 0;
+        static const unsigned int SET_ARMED_MODE   = 1;
+    };
+    const std::vector<int> ALL_EVENTS = {
+            Events::SET_PAIRING_MODE,
+            Events::SET_ARMED_MODE,
+    };
+
+    WebService pairingService;
+    net::MDNS  *mdns;
+
+    driver::Button *button;
+
+    driver::LCD lcd = driver::LCD(32, 33, 25, 26, 27, 13); // TODO use Kconfig
+
+    [[noreturn]] void main(void *) {
+        ESP_LOGI(TAG, "starting");
+
+        button = new driver::Button(19); // TODO use Kconfig
+        button->onRelease   = {[](driver::Button &button) {
+            ESP_LOGI(TAG, "button->onRelease()");
+            testNotification();
+        }};
+        button->onLongPress = {[](driver::Button &button) {
+            ESP_LOGI(TAG, "button->onLongPress()");
+            clearPairing();
+        }};
+
+        pairingService.attach<PairController>();
+        pairingService.attach<SettingsController>();
+        pairingService.attach<VerifyController>();
+
+        if (paired()) {
+            wifi::start();
+            setupArmedMode();
+        } else {
+            setupPairingMode();
+        }
+
+        while (true) {
+            eventGroup.waitForAny(ALL_EVENTS);
+            if (eventGroup.getBit(Events::SET_PAIRING_MODE)) {
+                setupPairingMode();
+            }
+            if (eventGroup.getBit(Events::SET_ARMED_MODE)) {
+                setupArmedMode();
+            }
+            eventGroup.clear();
+        }
+    }
+
+    void showMessage(const string &message) {
+        lcd.println(message, 1);
+        kbf::sleep(MESSAGE_TIMEOUT);
+        lcd.println("", 1);
+    }
+
     void handleConnect(wifi::AP::STA &sta) {
         lcd.clear();
         kbf::sleep(50);
@@ -25,51 +99,63 @@ namespace dk {
         lcd.print("credentials");
     }
 
-    WebService webService;
-    net::MDNS  *mdns;
+    void setupPairingMode() {
+        ESP_LOGI(TAG, "setupPairingMode()");
+        lcd.println("DoorKeeper", 0);
+        lcd.println("pairing", 1);
 
-    driver::Button *button;
-    driver::LCD    lcd = driver::LCD(32, 33, 25, 26, 27, 13);
+        pairingService.stop();
+        wifi::stop();
 
-    void main(void *) {
-        ESP_LOGI(TAG, "starting");
+        auto sta = wifi::STA::create();
+        auto ap  = wifi::AP::create("doorkeeper", "initinit");
+        ap->onConnect = handleConnect;
 
-        button = new driver::Button(19); // TODO use Kconfig
-        button->onPress = {[](driver::Button &button) {
-            ESP_LOGI(TAG, "sending test notification");
-            auto pairingId = SettingsManager::instance()->pairingId();
-            ESP_LOGI(TAG, "pairingId = %s", pairingId.c_str());
-            auto client = http::Client();
-            auto response = client.post("http://dev.api.doorkeeper.kraxor.net/test_notification", {{"pairing_id", pairingId}});
-            ESP_LOGI(TAG, "test_notification response: %d", response->status);
-        }};
+        wifi::start(ap, sta);
+        pairingService.start();
+    }
 
-        if (SettingsManager::instance()->softAPEnabled()) {
-            auto sta = wifi::STA::create();
-            auto ap = wifi::AP::create("doorkeeper", "initinit");
-            ap->onConnect = handleConnect;
-            wifi::start(ap, sta);
-
-            dk::lcd.clear();
-            kbf::sleep(50);
-            dk::lcd.print("pairing mode");
-            dk::lcd.move(0, 1);
-            dk::lcd.print("setting up");
-        } else {
-            wifi::start();
-            dk::lcd.print("idle");
+    void setupArmedMode() {
+        ESP_LOGI(TAG, "setupArmedMode()");
+        lcd.println("DoorKeeper armed", 0);
+        lcd.println("", 1); // TODO print icons
+
+        pairingService.stop();
+    }
+
+    void testNotification() {
+        ESP_LOGI(TAG, "testNotification()");
+
+        if (!paired()) {
+            ESP_LOGI(TAG, "  not paired");
+            showMessage("not paired");
+            return;
         }
 
-        webService.attach<PairController>();
-        webService.attach<ScanController>();
-        webService.attach<SettingsController>();
-        webService.attach<VerifyController>();
-        webService.start();
+        auto pairingId = SettingsManager::instance()->pairingId();
+        ESP_LOGI(TAG, "  pairingId = %s", pairingId.c_str());
+        auto client   = http::Client();
+        auto response = client.post("http://dev.api.doorkeeper.kraxor.net/test_notification",
+                                    {{"pairing_id", pairingId}});
+        ESP_LOGI(TAG, "test_notification response: %d", response->status);
 
-        dk::lcd.move(0, 1);
-        dk::lcd.print("waiting...");
+        showMessage("message sent");
+    }
+
+    void setPairing(const string &pairingId) {
+        ESP_LOGI(TAG, "setPairing(%s)", pairingId.c_str());
+        SettingsManager::instance()->setPairingId(pairingId);
+        eventGroup.setBit(Events::SET_ARMED_MODE);
+    }
+
+    void clearPairing() {
+        ESP_LOGI(TAG, "clearPairing()");
+        SettingsManager::instance()->setPairingId("");
+        eventGroup.setBit(Events::SET_PAIRING_MODE);
+    }
 
-        vTaskDelete(nullptr);
+    bool paired() {
+        return !SettingsManager::instance()->pairingId().empty();
     }
 }
 

+ 1 - 0
components/dk/src/pairing_manager.cpp

@@ -0,0 +1 @@
+#include "pairing_manager.h"

+ 2 - 2
components/dk/src/controllers/pair_controller.cpp → components/dk/src/pairing_service/pair_controller.cpp

@@ -58,9 +58,9 @@ http::Response PairController::post(const http::Request &request) {
 void stopAP(void *) {
     ESP_LOGI(TAG, "stopAP()");
 
-    webService.stop();
+    pairingService.stop();
     wifi::stopAP();
-    webService.start();
+    pairingService.start();
 
     mdns = new net::MDNS("doorkeeper");
     mdns->addService("_http", 80, "DoorKeeper API");

+ 0 - 0
components/dk/src/controllers/scan_controller.cpp → components/dk/src/pairing_service/scan_controller.cpp


+ 0 - 0
components/dk/src/controllers/settings_controller.cpp → components/dk/src/pairing_service/settings_controller.cpp


+ 2 - 8
components/dk/src/controllers/verify_controller.cpp → components/dk/src/pairing_service/verify_controller.cpp

@@ -49,14 +49,8 @@ http::Response VerifyController::post(const http::Request &request) {
     }
 
     ESP_LOGI(TAG, "verification successful");
-    lcd.clear();
-    kbf::sleep(50);
-    lcd.print("DoorKeeper v0.1");
-    lcd.move(0, 1);
-    lcd.print("ready");
-
-    ESP_LOGI(TAG, "setting pairingId to %s", pairingId.c_str());
-    SettingsManager::instance()->setPairingId(pairingId);
+    lcd.print("successful");
+    dk::setPairing(pairingId);
 
     return http::Response(nlohmann::json({{"success", true}}));
 }

+ 10 - 0
scripts/unpair.sh

@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+set -e
+
+if [ $# -lt 1 ]; then
+    echo "usage: $0 <pairing_id>"
+    exit 0
+fi
+
+curl "http://dev.api.doorkeeper.kraxor.net/app/unpair" -d "{\"pairing_id\": \"$1\"}"