Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement WiFi.getCredentials #759

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions hal/inc/hal_dynalib_wlan.h
Expand Up @@ -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 */
Expand Down
9 changes: 9 additions & 0 deletions hal/inc/wlan_hal.h
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions hal/src/core/wlan_hal.c
Expand Up @@ -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;
}
55 changes: 55 additions & 0 deletions hal/src/photon/wlan_hal.cpp
Expand Up @@ -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
*/
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
13 changes: 13 additions & 0 deletions user/tests/wiring/api/wifi.cpp
Expand Up @@ -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<found; i++) {
Serial.print("ssid: ");
Serial.println(ap[i].ssid);
Serial.println(ap[i].security);
Serial.println(ap[i].channel);
Serial.println(ap[i].rssi);
}
}

#endif
2 changes: 2 additions & 0 deletions wiring/inc/spark_wiring_wifi.h
Expand Up @@ -213,6 +213,8 @@ class WiFiClass : public NetworkClass
int scan(void (*handler)(WiFiAccessPoint* ap, T* instance), T* instance) {
return scan((wlan_scan_result_t)handler, (void*)instance);
}

int getCredentials(WiFiAccessPoint* results, size_t result_count);
};

extern WiFiClass WiFi;
Expand Down
40 changes: 30 additions & 10 deletions wiring/src/spark_wiring_wifi.cpp
Expand Up @@ -34,42 +34,62 @@ License along with this library; if not, see <http://www.gnu.org/licenses/>.

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 (index<count) {
results[index++] = *result;
}
}

protected:
static void callback(WiFiAccessPoint* result, void* cookie)
{
((APArrayPopulator*)cookie)->addResult(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))
Expand Down