Quellcode durchsuchen

KBF-23 implement wifi dual to STA mode switching

Bence Balint vor 3 Jahren
Ursprung
Commit
fb01a67772

+ 7 - 0
include/kbf/web_service.h

@@ -23,6 +23,13 @@ namespace kbf {
          */
         explicit WebService(int port = 80);
 
+        /**
+         * @brief Destructor.
+         *
+         * Will call stop() if #running.
+         */
+        ~WebService();
+
         /**
          * @brief Starts the service.
          *

+ 13 - 2
include/kbf/wifi.h

@@ -54,6 +54,14 @@ namespace kbf::wifi {
      */
     void stop();
 
+    /**
+     * @brief Disables AP.
+     *
+     * If the driver was in dual mode, it will change to STA mode.
+     * If the driver was in softAP mode, it will change to NULL mode.
+     */
+    void stopAP();
+
     /**
      * @brief Returns the currently used AP instance.
      *
@@ -89,7 +97,7 @@ namespace kbf::wifi {
         /** @see #kbf::wifi::start() */
         friend void kbf::wifi::start(shared_ptr<AP>, shared_ptr<STA>);
 
-        /** @see #kbf::wifi::start() */
+        /** @see #kbf::wifi::stop() */
         friend void kbf::wifi::stop();
 
     public:
@@ -238,9 +246,12 @@ namespace kbf::wifi {
         /** @see #kbf::wifi::start() */
         friend void kbf::wifi::start(shared_ptr<AP>, shared_ptr<STA>);
 
-        /** @see #kbf::wifi::start() */
+        /** @see #kbf::wifi::stop() */
         friend void kbf::wifi::stop();
 
+        /** @see #kbf::wifi::stopAP() */
+        friend void kbf::wifi::stopAP();
+
     public:
         /** @brief Tag used for logging. */
         static constexpr const char *TAG = "kbf::wifi::AP";

+ 6 - 0
src/web_service.cpp

@@ -9,6 +9,12 @@ using namespace kbf;
 WebService::WebService(int port) : server(), port(port) {
 }
 
+WebService::~WebService() {
+    if (running) {
+        stop();
+    }
+}
+
 void WebService::start() {
     if (running) {
         ABORT("WebService already running");

+ 14 - 1
src/wifi/driver.cpp

@@ -76,7 +76,7 @@ void kbf::wifi::start(shared_ptr<STA> sta) {
 }
 
 void kbf::wifi::start(shared_ptr<AP> ap, shared_ptr<STA> sta) {
-    ESP_LOGI(TAG, "starting STA mode");
+    ESP_LOGI(TAG, "starting dual mode");
 
     init();
 
@@ -108,6 +108,19 @@ void kbf::wifi::stop() {
     }
 }
 
+void kbf::wifi::stopAP() {
+    if (s_ap) {
+        esp_netif_destroy(s_ap->netif);
+        s_ap = nullptr;
+    }
+
+    if (s_sta) {
+        esp_wifi_set_mode(WIFI_MODE_STA);
+    } else {
+        esp_wifi_set_mode(WIFI_MODE_NULL);
+    }
+}
+
 shared_ptr<kbf::wifi::AP> kbf::wifi::getAP() {
     return s_ap;
 }

+ 2 - 2
src/wifi/sta.cpp

@@ -6,12 +6,12 @@
 using namespace kbf;
 
 wifi::STA::STA() {
-    ESP_LOGD(TAG, "STA()");
+    ESP_LOGI(TAG, "STA()");
     config.pmf_cfg = {true, false};
 }
 
 wifi::STA::~STA() {
-    ESP_LOGD(TAG, "~STA()");
+    ESP_LOGI(TAG, "~STA()");
     unregisterEventHandlers();
 }
 

+ 85 - 3
test/test_wifi.cpp

@@ -1,5 +1,3 @@
-#include <unity.h>
-
 #include <iostream>
 #include <string>
 #include <atomic>
@@ -8,6 +6,10 @@
 #include <kbf.h>
 #include <kbf/wifi.h>
 #include <kbf/rtos.h>
+#include <kbf/http/client.h>
+#include <kbf/web_service.h>
+
+#include <unity.h>
 
 using std::cout;
 using std::endl;
@@ -263,7 +265,7 @@ void wifiScanSlave() {
 
 TEST_CASE_MULTIPLE_DEVICES("WiFi scan", "[kbf_wifi]", wifiScanMaster, wifiScanSlave)
 
-kbf::rtos::EventGroup eventGroup;
+static kbf::rtos::EventGroup eventGroup;
 
 void wifiIpMaster() {
     using namespace kbf;
@@ -301,3 +303,83 @@ void wifiIpSlave() {
 }
 
 TEST_CASE_MULTIPLE_DEVICES("WiFi custom IP address", "[kbf_wifi]", wifiIpMaster, wifiIpSlave)
+
+static kbf::http::Client *client;
+
+void wifiModeSwitchMaster() {
+    using namespace kbf;
+    eventGroup = rtos::EventGroup();
+
+    auto ap = wifi::AP::create(
+            KBF_TEST_WIFI_DUAL_MASTER_SSID,
+            KBF_TEST_WIFI_PASS,
+            net::IP("192.168.1.1")
+    );
+    ap->onConnect = {[](wifi::AP::STA &) {
+        wifi::getSTA()->connect(KBF_TEST_WIFI_DUAL_SLAVE_SSID, KBF_TEST_WIFI_PASS);
+    }};
+
+    delete client;
+    client = new http::Client();
+
+    auto sta = wifi::STA::create();
+    sta->onIp = {[]() {
+        wifi::stopAP();
+        kbf::sleep(1000);
+        auto response = client->get("http://192.168.2.1/");
+        TEST_ASSERT_EQUAL(200, response->status);
+        eventGroup.setBit(0);
+    }};
+
+    wifi::start(ap, sta);
+    eventGroup.waitForBit(0);
+    wifi::stop();
+}
+
+class TestController : public kbf::WebService::Controller {
+public:
+    TestController() : kbf::WebService::Controller("/") {}
+
+    kbf::http::Response get(const kbf::http::Request &request) override {
+        eventGroup.setBit(0);
+        if (eventGroup.getBit(1)) return kbf::http::Response("", 501);
+        if (!eventGroup.getBit(2)) return kbf::http::Response("", 502);
+        return kbf::http::Response("", 200);
+    }
+};
+
+void wifiModeSwitchSlave() {
+    using namespace kbf;
+    using namespace std;
+    eventGroup = rtos::EventGroup();
+
+    auto ap = wifi::AP::create(
+            KBF_TEST_WIFI_DUAL_SLAVE_SSID,
+            KBF_TEST_WIFI_PASS,
+            net::IP("192.168.2.1")
+    );
+    ap->onDisconnect = {[](wifi::AP::STA &) {
+        eventGroup.setBit(1);
+    }};
+
+    auto sta = wifi::STA::create();
+    sta->onReconnecting = {[](int, int) {
+        return false;
+    }};
+    sta->onDisconnect   = {[]() {
+        eventGroup.setBit(2);
+    }};
+    wifi::start(ap, sta);
+
+    auto webService = WebService();
+    webService.attach<TestController>();
+    webService.start();
+
+    sta->connect(KBF_TEST_WIFI_DUAL_MASTER_SSID, KBF_TEST_WIFI_PASS);
+
+    eventGroup.waitForBit(0);
+    kbf::sleep(1000);
+    wifi::stop();
+}
+
+TEST_CASE_MULTIPLE_DEVICES("WiFi mode switching", "[kbf_wifi]", wifiModeSwitchMaster, wifiModeSwitchSlave)

+ 45 - 0
test_app/.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,45 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="HttpUrlsUsage" enabled="true" level="WEAK WARNING" enabled_by_default="true">
+      <option name="ignoredUrls">
+        <list>
+          <option value="http://localhost" />
+          <option value="http://127.0.0.1" />
+          <option value="http://0.0.0.0" />
+          <option value="http://www.w3.org/2000/svg" />
+          <option value="http://www.w3.org/2000/10/XMLSchema" />
+          <option value="http://www.w3.org/2001/XMLSchema" />
+          <option value="http://www.w3.org/2001/XMLSchema-instance" />
+          <option value="http://www.w3.org/2001/XInclude" />
+          <option value="http://www.w3.org/2003/03/wsdl" />
+          <option value="http://json-schema.org/draft" />
+          <option value="http://java.sun.com/xml/ns/" />
+          <option value="http://java.sun.com/jsp/" />
+          <option value="http://java.sun.com/JSP/" />
+          <option value="http://java.sun.com/j2ee/dtds/" />
+          <option value="http://java.sun.com/dtd/" />
+          <option value="http://xmlns.jcp.org/xml/ns/" />
+          <option value="http://javafx.com/javafx/" />
+          <option value="http://javafx.com/fxml" />
+          <option value="http://maven.apache.org/xsd/" />
+          <option value="http://maven.apache.org/POM/" />
+          <option value="http://www.springframework.org/schema/" />
+          <option value="http://www.springframework.org/tags" />
+          <option value="http://www.thymeleaf.org" />
+          <option value="http://www.jboss.org/j2ee/schema/" />
+          <option value="http://www.jboss.com/xml/ns/" />
+          <option value="http://www.ibm.com/webservices/xsd" />
+          <option value="http://activemq.apache.org/schema/" />
+          <option value="http://schema.cloudfoundry.org/spring/" />
+          <option value="http://schemas.xmlsoap.org/" />
+          <option value="http://schemas.android.com/" />
+          <option value="http://jakarta.apache.org/" />
+          <option value="http://cxf.apache.org/schemas/" />
+          <option value="http://192.168.4.1" />
+          <option value="http://192.168.2.1" />
+        </list>
+      </option>
+    </inspection_tool>
+  </profile>
+</component>