Appearance
file /Users/ios_developer/workspace/coldwave-os/build/_deps/libcoldwave-src/commissioning/wifi_commissioning.cpp
Functions Overview
Name | |
---|---|
LOG_MODULE(wifi_commissioning ) | |
int | wifi_commissioning_join(PropArray & params, PropArray & outProps) |
int | wifi_commissioning_get_scan_results(PropArray & params, PropArray & outProps) |
int | wifi_commissioning_end_requested(PropArray & params, PropArray & outProps) |
int | wifi_commissioning_scan(void ) |
void | wifi_commissioning_rssi_sort(wlan_ap_info_t * scan_result, int first, int last) |
int | wifi_commissioning_try_join(wifi_commissioning_data_t * data) |
int | wifi_commissioning_ap_start(int wifi_dev, const char * ssid, const void * passphrase, int passphrase_len) |
int | wifi_commissioning_ap_stop(int wifi_dev) |
int | wifi_commissioning_start(int commissioning_type, wifi_commissioning_init_t * init) |
void | wifi_commissioning_end(void * p) |
void | wifi_commissioning_end_async() |
void | wifi_commissioning_try_join_async(void * p) |
void | wifi_commissioning_broadcast_scan_results(void * p) |
Attributes
Defines
Name | |
---|---|
WC_TIMER_EXPIRED |
Function Details
function LOG_MODULE
cpp
LOG_MODULE(
wifi_commissioning
)
function wifi_commissioning_join
cpp
static int wifi_commissioning_join(
PropArray & params,
PropArray & outProps
)
function wifi_commissioning_get_scan_results
cpp
static int wifi_commissioning_get_scan_results(
PropArray & params,
PropArray & outProps
)
function wifi_commissioning_end_requested
cpp
static int wifi_commissioning_end_requested(
PropArray & params,
PropArray & outProps
)
function wifi_commissioning_scan
cpp
static int wifi_commissioning_scan(
void
)
function wifi_commissioning_rssi_sort
cpp
static void wifi_commissioning_rssi_sort(
wlan_ap_info_t * scan_result,
int first,
int last
)
function wifi_commissioning_try_join
cpp
static int wifi_commissioning_try_join(
wifi_commissioning_data_t * data
)
function wifi_commissioning_ap_start
cpp
static int wifi_commissioning_ap_start(
int wifi_dev,
const char * ssid,
const void * passphrase,
int passphrase_len
)
function wifi_commissioning_ap_stop
cpp
static int wifi_commissioning_ap_stop(
int wifi_dev
)
function wifi_commissioning_start
cpp
int wifi_commissioning_start(
int commissioning_type,
wifi_commissioning_init_t * init
)
function wifi_commissioning_end
cpp
void wifi_commissioning_end(
void * p
)
function wifi_commissioning_end_async
cpp
void wifi_commissioning_end_async()
function wifi_commissioning_try_join_async
cpp
void wifi_commissioning_try_join_async(
void * p
)
function wifi_commissioning_broadcast_scan_results
cpp
void wifi_commissioning_broadcast_scan_results(
void * p
)
Attributes Documentation
variable wifi_commissioning_running
cpp
static int wifi_commissioning_running
variable wifi_commissioning_wifi_dev
cpp
static int wifi_commissioning_wifi_dev
variable wifi_commissioning_commissioner_dev
cpp
static int wifi_commissioning_commissioner_dev
variable wifi_commissioning_ap_started
cpp
static int wifi_commissioning_ap_started
variable wifi_join_action_token
cpp
static volatile uint16_t wifi_join_action_token
variable wifi_scan_action_token
cpp
static volatile uint16_t wifi_scan_action_token
variable wifi_commissioning_scan_results
cpp
static wlan_ap_info_t* wifi_commissioning_scan_results
variable wifi_commissioning_num_scan_results
cpp
static uint32_t wifi_commissioning_num_scan_results
variable wifi_commissioning_data_callback
cpp
static wifi_commissioning_data_callback_t wifi_commissioning_data_callback
variable wifi_commissioning_timeout_tmr
cpp
static osTimerId_t wifi_commissioning_timeout_tmr
variable coldwave_device_service
cpp
static Service* coldwave_device_service
Macros Documentation
define WC_TIMER_EXPIRED
cpp
#define WC_TIMER_EXPIRED ((void*)0xffffU)
Source code
cpp
/*******************************************************************************
* @file wifi_commissioning.cpp
* @license This file is part of the ImagineOn Coldwave eOS software package
* licensed under the ImagineOn software-licensing terms available
* under https://www.imagineon.de/de/info/licensing-terms
* @copyright Copyright (c) 2023. ImagineOn GmbH. www.imagineon.de.
******************************************************************************/
#include "wifi_commissioning.h"
#include "wifi_commissioning_legacy.h"
#include <wlan.h>
#include <kernel.h>
#include <ble.h>
#include <sys/ioctl.h>
#include <logging.h>
LOG_MODULE(wifi_commissioning)
#define WC_TIMER_EXPIRED ((void*)0xffffU)
static int wifi_commissioning_type = -1;
static int wifi_commissioning_running = 0;
static int wifi_commissioning_wifi_dev = -1;
static int wifi_commissioning_commissioner_dev = -1;
static int wifi_commissioning_ap_started = 0;
static volatile uint16_t wifi_join_action_token = 0;
static volatile uint16_t wifi_scan_action_token = 0;
static wlan_ap_info_t *wifi_commissioning_scan_results = nullptr;
static uint32_t wifi_commissioning_num_scan_results = 0;
static wifi_commissioning_data_callback_t wifi_commissioning_data_callback;
static osTimerId_t wifi_commissioning_timeout_tmr = 0;
static Service *coldwave_device_service = nullptr;
static int
wifi_commissioning_join (PropArray& params, PropArray& outProps);
static int
wifi_commissioning_get_scan_results (PropArray& params, PropArray& outProps);
static int
wifi_commissioning_end_requested (PropArray& params, PropArray& outProps);
static int
wifi_commissioning_scan (void);
static void
wifi_commissioning_rssi_sort (wlan_ap_info_t *scan_result, int first, int last);
static int
wifi_commissioning_try_join (wifi_commissioning_data_t *data);
static int
wifi_commissioning_ap_start (int wifi_dev, const char *ssid, const void *passphrase, int passphrase_len);
static int
wifi_commissioning_ap_stop (int wifi_dev);
int wifi_commissioning_start (int commissioning_type, wifi_commissioning_init_t *init)
{
if (init == nullptr)
{
return E_FAILED;
}
if ((init->wifi_dev == -1) || (init->device_srv == nullptr))
{
return E_FAILED;
}
if (commissioning_type == WCT_AP)
{
wifi_commissioning_type = WCT_AP;
}
else if (commissioning_type == WCT_BLE)
{
wifi_commissioning_type = WCT_BLE;
}
else if (commissioning_type == WCT_LEGACY)
{
wifi_commissioning_type = WCT_LEGACY;
}
else
{
return E_FAILED;
}
if (wifi_commissioning_running == 1)
{
return E_RUNNING;
}
wifi_commissioning_commissioner_dev = init->commissioner_dev;
wifi_commissioning_data_callback = init->data_callback;
wifi_commissioning_running = 1;
wifi_commissioning_wifi_dev = init->wifi_dev;
coldwave_device_service = init->device_srv;
coldwave_device_service->set (PropMakeU8 (P_WIFI_CAPABILITIES, WIFI_CAP_JOIN | WIFI_CAP_SCAN));
coldwave_device_service->set (PropMakeBool (P_WIFI_IS_SCANNING, false));
coldwave_device_service->set (PropMakeString (P_WIFI_CURR_SSID, nullptr));
coldwave_device_service->set (PropMakeU8 (P_WIFI_STATE, CW_WIFI_DISCONNECTED));
coldwave_device_service->set (PropMakeU32 (P_WIFI_IF_IP, 0));
coldwave_device_service->onMessage ("WIFI_JOIN", wifi_commissioning_join);
coldwave_device_service->onMessage ("WIFI_SCAN", wifi_commissioning_get_scan_results);
coldwave_device_service->onMessage ("WIFI_END_COMMISSIONING", wifi_commissioning_end_requested);
if (E_OK != wifi_commissioning_scan ())
{
return E_SCAN;
}
Property pWifiCaps (P_WIFI_CAPABILITIES);
int res = E_OK;
if (wifi_commissioning_type == WCT_AP)
{
pWifiCaps.u8 = WIFI_CAP_JOIN | WIFI_CAP_SCAN;
res = wifi_commissioning_ap_start (wifi_commissioning_commissioner_dev,
init->commissioner_name, init->commissioner_password,
strlen (init->commissioner_password));
}
else if (wifi_commissioning_type == WCT_LEGACY)
{
wifi_commissioning_ble_start (init->wifi_dev, wifi_commissioning_commissioner_dev, init->commissioner_name,
wifi_commissioning_try_join, wifi_commissioning_end);
wifi_commissioning_ble_update_ssids (wifi_commissioning_scan_results, wifi_commissioning_num_scan_results);
}
else if (wifi_commissioning_type == WCT_BLE)
{
pWifiCaps.u8 = WIFI_CAP_JOIN | WIFI_CAP_SCAN;
flakeSerialWireCallbacks_t wire_cb;
flakeRouterAddSerialServerWire (wifi_commissioning_commissioner_dev, &wire_cb);
ioctl (wifi_commissioning_commissioner_dev, BLE_IOCTL_SET_CONNECT_CALLBACK, (void *) wire_cb.onConnect);
ioctl (wifi_commissioning_commissioner_dev, BLE_IOCTL_SET_DISCONNECT_CALLBACK, (void *) wire_cb.onDisconnect);
ioctl (wifi_commissioning_commissioner_dev, BLE_IOCTL_START_ADVERTISING, 0);
ioctl (wifi_commissioning_commissioner_dev, BLE_IOCTL_AUTO_RECONNECT, (void *) 1);
}
if (res != E_OK)
{
return res;
}
wifi_commissioning_timeout_tmr = osTimerNew (wifi_commissioning_end, osTimerOnce, WC_TIMER_EXPIRED, 0);
osTimerStart (wifi_commissioning_timeout_tmr, init->timeout_ms);
coldwave_device_service->set (pWifiCaps);
return res;
}
void wifi_commissioning_end (void *p)
{
if (p == WC_TIMER_EXPIRED)
{
wifi_commissioning_data_callback (E_TIMEOUT, nullptr);
}
wifi_commissioning_running = 0;
if (osTimerIsRunning (wifi_commissioning_timeout_tmr))
{
osTimerStop (wifi_commissioning_timeout_tmr);
}
if (wifi_commissioning_type == WCT_BLE)
{
#if WIFI_COMMISSIONING_BLE_LEGACY
wifi_commissioning_ble_stop (wifi_commissioning_ble_dev);
#else
ioctl (wifi_commissioning_commissioner_dev, BLE_IOCTL_AUTO_RECONNECT, 0);
ioctl (wifi_commissioning_commissioner_dev, BLE_IOCTL_DISCONNECT, 0);
#endif
}
else
{
if (E_OK != wifi_commissioning_ap_stop (wifi_commissioning_wifi_dev))
{
return;
}
}
Property pWifiCaps (P_WIFI_CAPABILITIES);
pWifiCaps.u8 = WIFI_CAP_JOIN | WIFI_CAP_SCAN;
coldwave_device_service->set (pWifiCaps);
}
int wifi_commissioning_scan ()
{
wifi_commissioning_num_scan_results = 0;
wifi_commissioning_scan_results = (wlan_ap_info_t *) malloc (sizeof (wlan_ap_info_t) * WIFI_MAX_SCAN_RESULTS);
int32_t err = wlan_scan (wifi_commissioning_wifi_dev, NULL, 0, wifi_commissioning_scan_results, &wifi_commissioning_num_scan_results, WIFI_MAX_SCAN_RESULTS);
if (err != 0)
{
return E_FAILED;
}
wifi_commissioning_rssi_sort (wifi_commissioning_scan_results, 0, wifi_commissioning_num_scan_results - 1);
return E_OK;
};
void wifi_commissioning_rssi_sort (wlan_ap_info_t *scan_result, int first, int last)
{
int i, j, pivot;
wlan_ap_info_t temp;
if (first < last)
{
pivot = first;
i = first;
j = last;
while (i < j)
{
while (abs (scan_result[i].rssi_val) <= abs (scan_result[pivot].rssi_val) && i < last)
i++;
while (abs (scan_result[j].rssi_val) > abs (scan_result[pivot].rssi_val))
j--;
if (i < j)
{
memcpy (&temp, &scan_result[i], sizeof (wlan_ap_info_t));
memcpy (&scan_result[i], &scan_result[j], sizeof (wlan_ap_info_t));
memcpy (&scan_result[j], &temp, sizeof (wlan_ap_info_t));
}
}
memcpy (&temp, &scan_result[pivot], sizeof (wlan_ap_info_t));
memcpy (&scan_result[pivot], &scan_result[j], sizeof (wlan_ap_info_t));
memcpy (&scan_result[j], &temp, sizeof (wlan_ap_info_t));
wifi_commissioning_rssi_sort (scan_result, first, j - 1);
wifi_commissioning_rssi_sort (scan_result, j + 1, last);
}
}
void wifi_commissioning_end_async ()
{
osDispatchAsync (wifi_commissioning_end, 0);
}
void wifi_commissioning_try_join_async (void *p)
{
wifi_commissioning_data_t *commissioning_data = (wifi_commissioning_data_t *) p;
(void) wifi_commissioning_try_join (commissioning_data);
free (commissioning_data);
}
int wifi_commissioning_try_join (wifi_commissioning_data_t *data)
{
PropArray props;
Property pRes (P_RESULT);
pRes.i8 = E_FAILED;
if (data->sec_type != WLAN_SEC_MODE_WPA2
&& data->sec_type != WLAN_SEC_MODE_WPA3)
{
pRes.i8 = E_REFUSED;
}
else
{
int res = wlan_connect (wifi_commissioning_wifi_dev, (uint8_t *) data->ssid, (uint8_t *) data->bssid,
(wlan_security_mode) data->sec_type,
(void *) data->passphrase, false);
if (res == 0)
{
wlan_connection_state_t wcs;
wlan_connection_state(wifi_commissioning_wifi_dev, &wcs);
while (wcs == WLAN_STATE_CONNECTING)
{
Property pWifiState (P_WIFI_STATE);
pWifiState.u8 = CW_WIFI_CONNECTING;
coldwave_device_service->set (pWifiState);
osDelay (10);
wlan_connection_state(wifi_commissioning_wifi_dev, &wcs);
}
if (wcs != WLAN_STATE_CONNECTED)
{
Property pWifiState (P_WIFI_STATE);
pWifiState.u8 = CW_WIFI_DISCONNECTED;
coldwave_device_service->set (pWifiState);
}
else
{
Property pWifiState (P_WIFI_STATE);
pWifiState.u8 = CW_WIFI_CONNECTED;
coldwave_device_service->set (pWifiState);
pRes.i8 = E_OK;
}
}
}
props.set (pRes);
Property pActionToken (P_ACTIONTOKEN);
pActionToken.u16 = wifi_join_action_token;
props.set (pActionToken);
coldwave_device_service->broadcast ("WIFI_JOIN_RESULT", props);
if ((wifi_commissioning_type == WCT_AP) && (pRes.i8 == E_OK))
{
wifi_commissioning_data_callback (E_OK, data);
}
return pRes.i8;
}
int wifi_commissioning_join (PropArray& params, PropArray& outProps)
{
UNUSED(outProps);
if (!params.has (P_ACTIONTOKEN))
{
return E_INCOMPLETE;
}
wifi_join_action_token = params.get (P_ACTIONTOKEN).u16;
wifi_commissioning_data_t *commissioning_data = (wifi_commissioning_data_t *) malloc (sizeof (wifi_commissioning_data_t));
commissioning_data->sec_type = params.get (P_SECTYPE).u8;
// add +1 to also copy '\0'
commissioning_data->ssid_length = strlen (params.get (P_SSID).str) + 1;
commissioning_data->passphrase_length = strlen (params.get (P_PASSKEY).str) + 1;
memcpy (commissioning_data->ssid, params.get (P_SSID).str, MIN(commissioning_data->ssid_length, 32));
memcpy (commissioning_data->passphrase, params.get (P_PASSKEY).str, MIN(commissioning_data->passphrase_length, 63));
memcpy (commissioning_data->bssid, params.get (P_BSSID).bin.lpb, 6);
osDispatchAsync (wifi_commissioning_try_join_async, commissioning_data);
return E_PENDING;
}
int wifi_commissioning_end_requested (PropArray& params, PropArray& outProps)
{
UNUSED(outProps);
UNUSED(params);
wifi_commissioning_end_async ();
return E_OK;
}
void wifi_commissioning_broadcast_scan_results (void *p)
{
UNUSED(p);
uint32_t action_token = wifi_scan_action_token;
PropArray props;
int32_t err = wlan_scan (wifi_commissioning_wifi_dev, NULL, 0, wifi_commissioning_scan_results, &wifi_commissioning_num_scan_results, WIFI_MAX_SCAN_RESULTS);
if (err == 0)
{
wifi_commissioning_rssi_sort (wifi_commissioning_scan_results, 0, wifi_commissioning_num_scan_results - 1);
for (uint8_t i = 0; i < wifi_commissioning_num_scan_results; i++)
{
Property pSSID (P_SSID);
pSSID.str = (char *) wifi_commissioning_scan_results[i].ssid;
props.set (pSSID);
Property pBSSID (P_BSSID);
pBSSID.bin.cb = sizeof (wifi_commissioning_scan_results[i].bssid);
pBSSID.bin.lpb = new byte[6];
for (uint8_t j = 0; j < 6; j++)
{
pBSSID.bin.lpb[j] = wifi_commissioning_scan_results[i].bssid[j];
}
props.set (pBSSID);
Property pSecType (P_SECTYPE);
pSecType.u8 = wifi_commissioning_scan_results[i].security_mode;
props.set (pSecType);
Property pRSSI (P_RSSI);
pRSSI.i16 = wifi_commissioning_scan_results[i].rssi_val;
props.set (pRSSI);
int res = coldwave_device_service->broadcast ("WIFI_SCAN_RESULT", props);
if (res != E_OK) {
LOG_ERROR ("brodacast error %d at msg. %d", res, i);
}
props.clear ();
osDelay (200);
}
}
Property pActionToken (P_ACTIONTOKEN);
pActionToken.u16 = action_token;
props.set (pActionToken);
Property result (P_RESULT);
result.u8 = 0;
props.set (result);
coldwave_device_service->broadcast ("WIFI_SCAN_FINISHED", props);
props.clear ();
wifi_scan_action_token = 0;
}
int wifi_commissioning_get_scan_results (PropArray& params, PropArray& outProps)
{
// this just broadcasts the previously scanned networks (because we can't re-scan in AP
// actual scanning has to be started outside in application
//
UNUSED(outProps);
if (wifi_scan_action_token != 0)
{
return E_FAILED;
}
if (!params.has (P_ACTIONTOKEN))
{
return E_INCOMPLETE;
}
wifi_scan_action_token = params.get (P_ACTIONTOKEN).u16;
osDispatchAsync (wifi_commissioning_broadcast_scan_results, 0);
return E_PENDING;
}
int wifi_commissioning_ap_start (int wifi_dev, const char *ssid, const void *passphrase, int passphrase_len)
{
if (wifi_commissioning_ap_started == 1)
{
return E_RUNNING;
}
wlan_disconnect (wifi_dev);
wifi_commissioning_ap_started = 1;
char _ssid[SSID_MAX_LEN] = {0};
uint32_t ssid_len = MIN(SSID_MAX_LEN, strlen (ssid));
memcpy (_ssid, ssid, ssid_len);
wlan_start_ap (wifi_dev, 6, (uint8_t *) ssid, ssid_len, 0, WLAN_SEC_MODE_WPA2, (uint8_t *) passphrase, passphrase_len);
return E_OK;
}
int wifi_commissioning_ap_stop (int wifi_dev)
{
if (wifi_commissioning_ap_started == 0)
{
return E_OK;
}
int res = wlan_stop_ap (wifi_dev);
if (res != 0)
{
return E_FAILED;
}
wifi_commissioning_ap_started = 0;
return E_OK;
}