From 06fe283580d154632fd2db61398d2d366ad02569 Mon Sep 17 00:00:00 2001 From: Julien Vanier Date: Mon, 7 Dec 2015 15:43:46 -0500 Subject: [PATCH] Implement WiFi.getCredentials * User provides an array of WiFiAccessPoint that get filled with the APs saved on the device * Returns number of APs on device * Photon only. Returns 0 on the Core since it cannot read APs back from the CC3000 Changes * Implement wlan_get_credentials in HAL * Implement WiFi.getCredentials with array arguments * Add API test Fixes #453 --- hal/inc/hal_dynalib_wlan.h | 1 + hal/inc/wlan_hal.h | 9 ++++++ hal/src/core/wlan_hal.c | 8 +++++ hal/src/photon/wlan_hal.cpp | 55 ++++++++++++++++++++++++++++++++ user/tests/wiring/api/wifi.cpp | 13 ++++++++ wiring/inc/spark_wiring_wifi.h | 2 ++ wiring/src/spark_wiring_wifi.cpp | 40 +++++++++++++++++------ 7 files changed, 118 insertions(+), 10 deletions(-) diff --git a/hal/inc/hal_dynalib_wlan.h b/hal/inc/hal_dynalib_wlan.h index a7f47efd2b..5237390174 100644 --- a/hal/inc/hal_dynalib_wlan.h +++ b/hal/inc/hal_dynalib_wlan.h @@ -67,6 +67,7 @@ DYNALIB_FN(hal_wlan,wlan_select_antenna) DYNALIB_FN(hal_wlan,wlan_set_ipaddress) DYNALIB_FN(hal_wlan,wlan_set_ipaddress_source) DYNALIB_FN(hal_wlan,wlan_scan) +DYNALIB_FN(hal_wlan,wlan_get_credentials) DYNALIB_END(hal_wlan) #endif /* HAL_DYNALIB_WLAN_H */ diff --git a/hal/inc/wlan_hal.h b/hal/inc/wlan_hal.h index 036983f515..fc87f351ed 100644 --- a/hal/inc/wlan_hal.h +++ b/hal/inc/wlan_hal.h @@ -261,6 +261,15 @@ typedef void (*wlan_scan_result_t)(WiFiAccessPoint* ap, void* cookie); */ int wlan_scan(wlan_scan_result_t callback, void* cookie); +/** + * Lists all WLAN credentials currently stored on the device + * @param callback The callback that receives each stored AP + * @param callback_data An opaque handle that is passed to the callback. + * @return count of stored credentials, negative on error. + */ + +int wlan_get_credentials(wlan_scan_result_t callback, void* callback_data); + #ifdef __cplusplus } #endif diff --git a/hal/src/core/wlan_hal.c b/hal/src/core/wlan_hal.c index 575a3c1aa5..cb1736675b 100644 --- a/hal/src/core/wlan_hal.c +++ b/hal/src/core/wlan_hal.c @@ -567,3 +567,11 @@ int wlan_scan(wlan_scan_result_t callback, void* cookie) return err < 0 ? err : count; } +/** + * Lists all WLAN credentials currently stored on the device + */ +int wlan_get_credentials(wlan_scan_result_t callback, void* callback_data) +{ + // Reading credentials from the CC3000 is not possible + return 0; +} diff --git a/hal/src/photon/wlan_hal.cpp b/hal/src/photon/wlan_hal.cpp index 40f37e74ee..f14d8710a8 100644 --- a/hal/src/photon/wlan_hal.cpp +++ b/hal/src/photon/wlan_hal.cpp @@ -300,6 +300,15 @@ WLanSecurityType toSecurityType(wiced_security_t sec) return WLAN_SEC_NOT_SET; } +WLanSecurityCipher toCipherType(wiced_security_t sec) +{ + if (sec & AES_ENABLED) + return WLAN_CIPHER_AES; + if (sec & TKIP_ENABLED) + return WLAN_CIPHER_TKIP; + return WLAN_CIPHER_NOT_SET; +} + /* * Callback function to handle scan results */ @@ -325,6 +334,7 @@ wiced_result_t sniffer( wiced_scan_handler_result_t* malloced_scan_result ) data.ssidLength = record->SSID.length; data.ssid[data.ssidLength] = 0; data.security = toSecurityType(record->security); + data.cipher = toCipherType(record->security); data.rssi = record->signal_strength; data.channel = record->channel; data.maxDataRate = record->max_data_rate; @@ -631,3 +641,48 @@ int wlan_scan(wlan_scan_result_t callback, void* cookie) int result = sniff_security(&info); return result < 0 ? result : info.count; } + +/** + * Lists all WLAN credentials currently stored on the device + */ +int wlan_get_credentials(wlan_scan_result_t callback, void* callback_data) +{ + int count = 0; + platform_dct_wifi_config_t* wifi_config = NULL; + wiced_result_t result = wiced_dct_read_lock( (void**) &wifi_config, WICED_FALSE, DCT_WIFI_CONFIG_SECTION, 0, sizeof(*wifi_config)); + if (!result) { + // the storage may not have been initialized, so device_configured will be 0xFF + initialize_dct(wifi_config); + + // iterate through each stored ap + for(int i = 0; i < CONFIG_AP_LIST_SIZE; i++) { + const wiced_config_ap_entry_t &ap = wifi_config->stored_ap_list[i]; + + if(!is_ap_config_set(ap)) { + continue; + } + count++; + + if(!callback) { + continue; + } + + const wiced_ap_info_t *record = &ap.details; + + WiFiAccessPoint data; + memcpy(data.ssid, record->SSID.value, record->SSID.length); + memcpy(data.bssid, (uint8_t*)&record->BSSID, 6); + data.ssidLength = record->SSID.length; + data.ssid[data.ssidLength] = 0; + data.security = toSecurityType(record->security); + data.cipher = toCipherType(record->security); + data.rssi = record->signal_strength; + data.channel = record->channel; + data.maxDataRate = record->max_data_rate; + + callback(&data, callback_data); + } + wiced_dct_read_unlock(wifi_config, WICED_FALSE); + } + return result < 0 ? result : count; +} diff --git a/user/tests/wiring/api/wifi.cpp b/user/tests/wiring/api/wifi.cpp index 352cb2ca69..c77ddf24ee 100644 --- a/user/tests/wiring/api/wifi.cpp +++ b/user/tests/wiring/api/wifi.cpp @@ -161,4 +161,17 @@ test(api_wifi_ipconfig) (void)address; } +test(api_wifi_get_credentials) +{ + WiFiAccessPoint ap[10]; + int found = WiFi.getCredentials(ap, 10); + for (int i=0; i. namespace spark { - class ScanArray + class APArrayPopulator { WiFiAccessPoint* results; int count; int index; - static void scan_callback(WiFiAccessPoint* result, void* cookie) - { - ((ScanArray*)cookie)->addResult(result); - } - void addResult(WiFiAccessPoint* result) { if (indexaddResult(result); + } + public: - ScanArray(WiFiAccessPoint* results, int size) { + APArrayPopulator(WiFiAccessPoint* results, int size) { this->results = results; this->count = size; this->index = 0; } + }; + + class APScan : public APArrayPopulator { + public: + using APArrayPopulator::APArrayPopulator; int start() { - return wlan_scan(scan_callback, this); + return wlan_scan(callback, this); + } + }; + + class APList : public APArrayPopulator { + public: + using APArrayPopulator::APArrayPopulator; + + int start() + { + return wlan_get_credentials(callback, this); } }; int WiFiClass::scan(WiFiAccessPoint* results, size_t result_count) { - ScanArray scanArray(results, result_count); - return scanArray.start(); + APScan apScan(results, result_count); + return apScan.start(); } + int WiFiClass::listCredentials(WiFiAccessPoint* results, size_t result_count) { + APList apList(results, result_count); + return apList.start(); + } int8_t WiFiClass::RSSI() { if (!network_ready(*this, 0, NULL))