From 0493ec2245a79a58fc096db2eab7f835dcd0a0d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Mon, 27 Jun 2022 13:03:52 +0200 Subject: [PATCH] [beken-72xx] Implement WiFi scanning --- arduino/beken-72xx/cores/arduino/WVariant.h | 3 + arduino/beken-72xx/libraries/WiFi/WiFi.cpp | 33 ++++++++ arduino/beken-72xx/libraries/WiFi/WiFi.h | 6 ++ arduino/beken-72xx/libraries/WiFi/WiFiData.h | 16 ++++ .../beken-72xx/libraries/WiFi/WiFiGeneric.cpp | 55 +++++++++++++ arduino/beken-72xx/libraries/WiFi/WiFiPriv.h | 35 ++++++++ .../beken-72xx/libraries/WiFi/WiFiScan.cpp | 79 +++++++++++++++++++ .../realtek-ambz/libraries/WiFi/WiFiData.h | 4 - builder/frameworks/beken-72xx-arduino.py | 1 + platform/beken-7231t/fixups/sys_config.h | 2 +- platform/beken-72xx/fixups/arch_main.c | 2 + 11 files changed, 231 insertions(+), 5 deletions(-) create mode 100644 arduino/beken-72xx/libraries/WiFi/WiFi.cpp create mode 100644 arduino/beken-72xx/libraries/WiFi/WiFi.h create mode 100644 arduino/beken-72xx/libraries/WiFi/WiFiData.h create mode 100644 arduino/beken-72xx/libraries/WiFi/WiFiGeneric.cpp create mode 100644 arduino/beken-72xx/libraries/WiFi/WiFiPriv.h create mode 100644 arduino/beken-72xx/libraries/WiFi/WiFiScan.cpp diff --git a/arduino/beken-72xx/cores/arduino/WVariant.h b/arduino/beken-72xx/cores/arduino/WVariant.h index 50559f9..1fda7a0 100644 --- a/arduino/beken-72xx/cores/arduino/WVariant.h +++ b/arduino/beken-72xx/cores/arduino/WVariant.h @@ -13,6 +13,9 @@ extern "C" { void delayMilliseconds(unsigned long); #define delay delayMilliseconds +// from fixups/arch_main.c +extern unsigned char __bk_rf_is_init; + #ifdef __cplusplus } // extern "C" #endif diff --git a/arduino/beken-72xx/libraries/WiFi/WiFi.cpp b/arduino/beken-72xx/libraries/WiFi/WiFi.cpp new file mode 100644 index 0000000..424f44a --- /dev/null +++ b/arduino/beken-72xx/libraries/WiFi/WiFi.cpp @@ -0,0 +1,33 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-26. */ + +#include "WiFiPriv.h" + +WiFiClass::WiFiClass() { + data.scanSem = xSemaphoreCreateBinary(); +} + +WiFiClass::~WiFiClass() { + vSemaphoreDelete(data.scanSem); +} + +WiFiAuthMode securityTypeToAuthMode(uint8_t type) { + // wlan_ui_pub.h:62 + switch (type) { + case BK_SECURITY_TYPE_NONE: + return WIFI_AUTH_OPEN; + case BK_SECURITY_TYPE_WEP: + return WIFI_AUTH_WEP; + case BK_SECURITY_TYPE_WPA_TKIP: + case BK_SECURITY_TYPE_WPA_AES: + return WIFI_AUTH_WPA_PSK; + case BK_SECURITY_TYPE_WPA2_TKIP: + case BK_SECURITY_TYPE_WPA2_AES: + case BK_SECURITY_TYPE_WPA2_MIXED: + return WIFI_AUTH_WPA2_PSK; + case BK_SECURITY_TYPE_WPA3_SAE: + return WIFI_AUTH_WPA3_PSK; + case BK_SECURITY_TYPE_WPA3_WPA2_MIXED: + return WIFI_AUTH_WPA2_WPA3_PSK; + } + return WIFI_AUTH_INVALID; +} diff --git a/arduino/beken-72xx/libraries/WiFi/WiFi.h b/arduino/beken-72xx/libraries/WiFi/WiFi.h new file mode 100644 index 0000000..17b0c8f --- /dev/null +++ b/arduino/beken-72xx/libraries/WiFi/WiFi.h @@ -0,0 +1,6 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-26. */ + +#pragma once + +#include +#include diff --git a/arduino/beken-72xx/libraries/WiFi/WiFiData.h b/arduino/beken-72xx/libraries/WiFi/WiFiData.h new file mode 100644 index 0000000..57b688e --- /dev/null +++ b/arduino/beken-72xx/libraries/WiFi/WiFiData.h @@ -0,0 +1,16 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-26. */ + +#pragma once + +#include + +extern "C" { + +#include +#include + +} // extern "C" + +typedef struct { + SemaphoreHandle_t scanSem; +} WiFiData; diff --git a/arduino/beken-72xx/libraries/WiFi/WiFiGeneric.cpp b/arduino/beken-72xx/libraries/WiFi/WiFiGeneric.cpp new file mode 100644 index 0000000..5302079 --- /dev/null +++ b/arduino/beken-72xx/libraries/WiFi/WiFiGeneric.cpp @@ -0,0 +1,55 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-26. */ + +#include "WiFiPriv.h" + +bool WiFiClass::modePriv(WiFiMode mode, WiFiModeAction sta, WiFiModeAction ap) { + __wrap_bk_printf_disable(); + + if (!__bk_rf_is_init) { + LT_D_WG("Initializing func&app"); + func_init_extended(); + app_pre_start(); + __bk_rf_is_init = true; + } + + LT_HEAP_I(); + + if (sta == WLMODE_ENABLE) { + LT_D_WG("Enabling STA"); + bk_wlan_sta_init(NULL); + } else if (sta == WLMODE_DISABLE) { + LT_D_WG("Disabling STA"); + bk_wlan_stop(BK_STATION); + } + + LT_HEAP_I(); + + if (ap == WLMODE_ENABLE) { + LT_D_WG("Enabling AP"); + bk_wlan_ap_init(NULL); + } else if (ap == WLMODE_DISABLE) { + LT_D_WG("Disabling AP"); + bk_wlan_stop(BK_SOFT_AP); + } + + LT_HEAP_I(); + + __wrap_bk_printf_enable(); +} + +WiFiMode WiFiClass::getMode() { + if (!g_wlan_general_param) + return WIFI_MODE_NULL; + uint8_t role = g_wlan_general_param->role; + // change 1->2, 2->1 + return (WiFiMode)(role + (role == 1) - (role == 2)); +} + +WiFiStatus WiFiClass::status() { + // wpa_suppliant_ctrl_get_wpas()->disconnected; + if (wpas_connect_ssid && wpas_connect_ssid->ssid_len) { + return WL_CONNECTED; + } else { + return WL_DISCONNECTED; + } +} diff --git a/arduino/beken-72xx/libraries/WiFi/WiFiPriv.h b/arduino/beken-72xx/libraries/WiFi/WiFiPriv.h new file mode 100644 index 0000000..88f5139 --- /dev/null +++ b/arduino/beken-72xx/libraries/WiFi/WiFiPriv.h @@ -0,0 +1,35 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-26. */ + +#pragma once + +#include "WiFi.h" + +extern "C" { + +#include +#include + +#include +#include +#include +#include +#include +#include + +extern void func_init_extended(); +extern void app_pre_start(); +extern void bk_wlan_ap_init(network_InitTypeDef_st *inNetworkInitPara); + +// func/hostapd-2.5/wpa_supplicant/main_supplicant.c +extern struct wpa_ssid_value *wpas_connect_ssid; + +// app/param_config.c +extern general_param_t *g_wlan_general_param; +extern ap_param_t *g_ap_param_ptr; +extern sta_param_t *g_sta_param_ptr; +extern uint8_t system_mac[6]; + +// WiFi.cpp +WiFiAuthMode securityTypeToAuthMode(uint8_t type); + +} // extern "C" diff --git a/arduino/beken-72xx/libraries/WiFi/WiFiScan.cpp b/arduino/beken-72xx/libraries/WiFi/WiFiScan.cpp new file mode 100644 index 0000000..02ec7e1 --- /dev/null +++ b/arduino/beken-72xx/libraries/WiFi/WiFiScan.cpp @@ -0,0 +1,79 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-27. */ + +#include "WiFiPriv.h" + +static void scanHandler(void *ctx, uint8_t param) { + LT_HEAP_I(); + WiFiClass *cls = (WiFiClass *)ctx; + if (!cls) { + LT_W("Called without ctx"); + return; + } + WiFiScanData *scan = cls->scan; + if (!scan) { + LT_W("Called without cls->scan"); + return; + } + + struct sta_scan_res *result; + uint8_t count = bk_wlan_get_scan_ap_result_numbers(); + if (count == 0) { + LT_D_WG("No APs found"); + goto end; + } + LT_D_WG("Found %d APs", count); + + result = (struct sta_scan_res *)malloc(sizeof(struct sta_scan_res) * count); + if (!result) { + LT_W("sta_scan_res alloc failed"); + goto end; + } + bk_wlan_get_scan_ap_result(result, count); + + cls->scanAlloc(count); + if (!scan->ap) { + LT_W("scan->ap alloc failed"); + goto end; + } + + for (uint8_t i = 0; i < count; i++) { + scan->ap[i].ssid = strdup(result[i].ssid); + scan->ap[i].auth = securityTypeToAuthMode(result[i].security); + scan->ap[i].rssi = result[i].level; + scan->ap[i].channel = result[i].channel; + memcpy(scan->ap[i].bssid.addr, result[i].bssid, 6); + } + +end: + scan->running = false; + xSemaphoreGive(cls->data.scanSem); + LT_HEAP_I(); + return; +} + +int16_t WiFiClass::scanNetworks(bool async, bool showHidden, bool passive, uint32_t maxMsPerChannel, uint8_t channel) { + if (scan && scan->running) + return WIFI_SCAN_RUNNING; + enableSTA(true); + scanDelete(); + scanInit(); + + LT_I("Starting WiFi scan"); + + __wrap_bk_printf_disable(); + mhdr_scanu_reg_cb(scanHandler, this); + bk_wlan_start_scan(); + __wrap_bk_printf_enable(); + + LT_HEAP_I(); + + scan->running = true; + + if (!async) { + LT_I("Waiting for results"); + xSemaphoreTake(data.scanSem, 1); // reset the semaphore quickly + xSemaphoreTake(data.scanSem, pdMS_TO_TICKS(maxMsPerChannel * 20)); + return scan->count; + } + return WIFI_SCAN_RUNNING; +} diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiData.h b/arduino/realtek-ambz/libraries/WiFi/WiFiData.h index 188ae1e..2488579 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiData.h +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiData.h @@ -4,16 +4,12 @@ #include -#ifdef __cplusplus extern "C" { -#endif #include #include -#ifdef __cplusplus } // extern "C" -#endif typedef struct { bool initialized; diff --git a/builder/frameworks/beken-72xx-arduino.py b/builder/frameworks/beken-72xx-arduino.py index 31a6636..2a88972 100644 --- a/builder/frameworks/beken-72xx-arduino.py +++ b/builder/frameworks/beken-72xx-arduino.py @@ -21,6 +21,7 @@ env.Append( "-Wno-write-strings", "-Wno-char-subscripts", "-Wno-missing-braces", + "-Wno-attributes", ], LINKFLAGS=[ # stdio wrappers (port/printf/printf.c) diff --git a/platform/beken-7231t/fixups/sys_config.h b/platform/beken-7231t/fixups/sys_config.h index 0291e51..687edf0 100644 --- a/platform/beken-7231t/fixups/sys_config.h +++ b/platform/beken-7231t/fixups/sys_config.h @@ -87,7 +87,7 @@ #define CFG_WIFI_RAW_TX_CMD 0 #define CFG_WIFI_SENSOR 0 #define CFG_WLAN_FAST_CONNECT 0 -#define CFG_WPA_CTRL_IFACE 1 +#define CFG_WPA_CTRL_IFACE 0 #define CFG_WPA3 0 #define CFG_XTAL_FREQUENCE CFG_XTAL_FREQUENCE_26M #define CFG_XTAL_FREQUENCE_26M 26000000 diff --git a/platform/beken-72xx/fixups/arch_main.c b/platform/beken-72xx/fixups/arch_main.c index e5f76c5..1ca42b1 100644 --- a/platform/beken-72xx/fixups/arch_main.c +++ b/platform/beken-72xx/fixups/arch_main.c @@ -30,6 +30,8 @@ extern void main(void); __attribute__((weak)) void __wrap_bk_printf_disable(); __attribute__((weak)) void __wrap_bk_printf_enable(); +unsigned char __bk_rf_is_init = 0; + void entry_main(void) { // compatibility with BK7231S_1.0.5 #if CFG_SUPPORT_BOOTLOADER