From f0084d81eeec1926fdbc764fe5297f4a2a771e9d Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Tue, 3 Sep 2019 11:39:02 -0700 Subject: [PATCH] Allow WhdAccessPoint scan result with extended parameters - Add WhdAccessPoint to include additional WHD scan info - To save memory, only move assignment is supported for WhdAccessPoint - Add scan_whd to scan for WhdAccessPoint - Set set_blocking(false) to unsupported by return NSAPI_ERROR_UNSUPPORTED --- .../TARGET_WHD/interface/WhdAccessPoint.cpp | 48 ++++++++++++ .../TARGET_WHD/interface/WhdAccessPoint.h | 74 +++++++++++++++++++ .../TARGET_WHD/interface/WhdSTAInterface.cpp | 26 +++++-- .../TARGET_WHD/interface/WhdSTAInterface.h | 39 +++++++++- .../TARGET_WHD/interface/WhdSoftAPInterface.h | 15 ++++ 5 files changed, 193 insertions(+), 9 deletions(-) create mode 100644 features/netsocket/emac-drivers/TARGET_WHD/interface/WhdAccessPoint.cpp create mode 100644 features/netsocket/emac-drivers/TARGET_WHD/interface/WhdAccessPoint.h diff --git a/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdAccessPoint.cpp b/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdAccessPoint.cpp new file mode 100644 index 000000000000..e93d5867344a --- /dev/null +++ b/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdAccessPoint.cpp @@ -0,0 +1,48 @@ +#include +#include +#include "WhdAccessPoint.h" + +WhdAccessPoint::WhdAccessPoint(nsapi_wifi_ap_t ap, whd_bss_type_t bss_type, uint8_t *ie_ptr, uint32_t ie_len) : + WiFiAccessPoint(ap), _bss_type(bss_type) +{ + _ie_ptr = (uint8_t *)malloc(ie_len * sizeof(uint8_t)); + if (_ie_ptr != NULL) { + _ie_len = ie_len; + memcpy(_ie_ptr, ie_ptr, ie_len * sizeof(uint8_t)); + } +} + +WhdAccessPoint &WhdAccessPoint::operator=(WhdAccessPoint &&rhs) +{ + if (this != &rhs) { + WiFiAccessPoint::operator=(rhs); + _bss_type = rhs._bss_type; + _ie_ptr = rhs._ie_ptr; + _ie_len = rhs._ie_len; + rhs._ie_ptr = NULL; + rhs._ie_len = 0; + } + return *this; +} + +whd_bss_type_t WhdAccessPoint::get_bss_type() const +{ + return _bss_type; +} + +uint8_t *WhdAccessPoint::get_ie_data() const +{ + return _ie_ptr; +} + +uint32_t WhdAccessPoint::get_ie_len() const +{ + return _ie_len; +} + +WhdAccessPoint::~WhdAccessPoint() +{ + if (_ie_ptr != NULL) { + free(_ie_ptr); + } +} diff --git a/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdAccessPoint.h b/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdAccessPoint.h new file mode 100644 index 000000000000..5ceaba62a82d --- /dev/null +++ b/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdAccessPoint.h @@ -0,0 +1,74 @@ +/* WHD Access Point Interface + * Copyright (c) 2017-2019 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WHD_ACCESS_POINT_H +#define WHD_ACCESS_POINT_H + +#include "netsocket/WiFiAccessPoint.h" +#include "whd_types.h" + +/* Enum for scan result type */ +enum scan_result_type { + SRES_TYPE_WIFI_ACCESS_POINT, + SRES_TYPE_WHD_ACCESS_POINT +}; + +/** WhdAccessPoint class + * + * Class that represents a Whd Access Point + * which contains additional Whd specific information + */ +class WhdAccessPoint : public WiFiAccessPoint { +public: + WhdAccessPoint() : WiFiAccessPoint() {}; + WhdAccessPoint(nsapi_wifi_ap_t ap, whd_bss_type_t bss_type, uint8_t *ie_ptr, uint32_t ie_len); + + /** Define move assignment and prevent copy-assignment + * + * Due to IE element data could have large memory footprint, + * only move assignment is allowed. + */ + WhdAccessPoint &operator=(WhdAccessPoint &&rhs); + WhdAccessPoint &operator=(const WhdAccessPoint &rhs) = delete; + + /** Get WHD access point's bss type + * + * @return The whd_bss_type_t of the access point + */ + whd_bss_type_t get_bss_type() const; + + /** Get WHD access point's IE data + * + * @return The pointer to ie data buffer + */ + uint8_t *get_ie_data() const; + + /** Get WHD access point's IE length + * + * @return The ie data length + */ + uint32_t get_ie_len() const; + + virtual ~WhdAccessPoint(); + +private: + whd_bss_type_t _bss_type; + uint8_t *_ie_ptr; /**< Pointer to received Beacon/Probe Response IE(Information Element) */ + uint32_t _ie_len; /**< Length of IE(Information Element) */ +}; + +#endif diff --git a/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSTAInterface.cpp b/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSTAInterface.cpp index 8b22a3bf127f..35f9c62ea09f 100644 --- a/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSTAInterface.cpp +++ b/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSTAInterface.cpp @@ -37,6 +37,7 @@ struct whd_scan_userdata { rtos::Semaphore *sema; + scan_result_type sres_type; WiFiAccessPoint *aps; std::vector *result_buff; unsigned count; @@ -173,6 +174,7 @@ static void *whd_wifi_link_state_change_handler(whd_interface_t ifp, return handler_user_data; } + MBED_WEAK WhdSTAInterface::OlmInterface &WhdSTAInterface::OlmInterface::get_default_instance() { static OlmInterface olm; @@ -395,7 +397,6 @@ static void whd_scan_handler(whd_scan_result_t **result_ptr, if (data->count > 0 && data->aps != NULL) { // get ap stats nsapi_wifi_ap ap; - uint8_t length = record->SSID.length; if (length < sizeof(ap.ssid) - 1) { length = sizeof(ap.ssid) - 1; @@ -408,17 +409,21 @@ static void whd_scan_handler(whd_scan_result_t **result_ptr, ap.security = whd_tosecurity(record->security); ap.rssi = record->signal_strength; ap.channel = record->channel; - data->aps[data->offset] = WiFiAccessPoint(ap); + if (data->sres_type == SRES_TYPE_WIFI_ACCESS_POINT) { + data->aps[data->offset] = WiFiAccessPoint(ap); + } else if (data->sres_type == SRES_TYPE_WHD_ACCESS_POINT) { + WhdAccessPoint *aps_sres = static_cast(data->aps); + aps_sres[data->offset] = std::move(WhdAccessPoint(ap, record->bss_type, + record->ie_ptr, record->ie_len)); + } } // store to result_buff for future duplication removal data->result_buff->push_back(*record); data->offset = data->result_buff->size(); - } - -int WhdSTAInterface::scan(WiFiAccessPoint *aps, unsigned count) +int WhdSTAInterface::internal_scan(WiFiAccessPoint *aps, unsigned count, scan_result_type sres_type) { // initialize wiced, this is noop if already init if (!_whd_emac.powered_up) { @@ -426,6 +431,7 @@ int WhdSTAInterface::scan(WiFiAccessPoint *aps, unsigned count) } interal_scan_data.sema = new Semaphore(); + interal_scan_data.sres_type = sres_type; interal_scan_data.aps = aps; interal_scan_data.count = count; interal_scan_data.offset = 0; @@ -449,6 +455,16 @@ int WhdSTAInterface::scan(WiFiAccessPoint *aps, unsigned count) return res; } +int WhdSTAInterface::scan(WiFiAccessPoint *aps, unsigned count) +{ + return internal_scan(aps, count, SRES_TYPE_WIFI_ACCESS_POINT); +} + +int WhdSTAInterface::scan_whd(WhdAccessPoint *aps, unsigned count) +{ + return internal_scan(aps, count, SRES_TYPE_WHD_ACCESS_POINT); +} + int WhdSTAInterface::is_interface_connected(void) { if (!_whd_emac.ifp) { diff --git a/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSTAInterface.h b/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSTAInterface.h index 8224a7e9a731..66b074a48df0 100644 --- a/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSTAInterface.h +++ b/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSTAInterface.h @@ -21,6 +21,7 @@ #include "netsocket/WiFiInterface.h" #include "netsocket/EMACInterface.h" #include "netsocket/OnboardNetworkStack.h" +#include "WhdAccessPoint.h" #include "whd_emac.h" #include "whd_types_int.h" @@ -31,7 +32,6 @@ struct ol_desc; */ class WhdSTAInterface : public WiFiInterface, public EMACInterface { public: - class OlmInterface { public: /** Get the default OLM interface. */ @@ -117,17 +117,33 @@ class WhdSTAInterface : public WiFiInterface, public EMACInterface { return 0; } + /** Set blocking status of interface. + * Nonblocking mode unsupported. + * + * @param blocking true if connect is blocking + * @return 0 on success, negative error code on failure + */ + nsapi_error_t set_blocking(bool blocking) + { + if (blocking) { + _blocking = blocking; + return NSAPI_ERROR_OK; + } else { + return NSAPI_ERROR_UNSUPPORTED; + } + } + /** Gets the current radio signal strength for active connection * * @return Connection strength in dBm (negative value) */ int8_t get_rssi(); - /** Scan for available networks + /** Scan for available networks in WiFiAccessPoint format * * This function will block. * - * @param ap Pointer to allocated array to store discovered AP + * @param ap Pointer to allocated array of WiFiAccessPoint format for discovered AP * @param count Size of allocated @a res array, or 0 to only count available AP * @param timeout Timeout in milliseconds; 0 for no timeout (Default: 0) * @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error @@ -135,6 +151,18 @@ class WhdSTAInterface : public WiFiInterface, public EMACInterface { */ int scan(WiFiAccessPoint *res, unsigned count); + /** Scan for available networks in WhdAccessPoint format + * + * This function will block. + * + * @param ap Pointer to allocated array of WhdAccessPoint format for discovered AP + * @param count Size of allocated @a res array, or 0 to only count available AP + * @param timeout Timeout in milliseconds; 0 for no timeout (Default: 0) + * @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error + * see @a nsapi_error + */ + int scan_whd(WhdAccessPoint *res, unsigned count); + /* is interface connected, if yes return WICED_SUCCESS else WICED_NOT_CONNECTED */ int is_interface_connected(); @@ -208,8 +236,11 @@ class WhdSTAInterface : public WiFiInterface, public EMACInterface { int ret = _olm->wake(); return ret; } -private: +protected: + int internal_scan(WiFiAccessPoint *aps, unsigned count, scan_result_type sres_type); + +private: char _ssid[33]; /* The longest possible name (defined in 802.11) +1 for the \0 */ char _pass[64]; /* The longest allowed passphrase + 1 */ nsapi_security_t _security; diff --git a/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSoftAPInterface.h b/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSoftAPInterface.h index 68914aa992b8..a4a0e1385c05 100644 --- a/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSoftAPInterface.h +++ b/features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSoftAPInterface.h @@ -131,6 +131,21 @@ class WhdSoftAPInterface : public EMACInterface { */ int unregister_event_handler(void); + /** Set blocking status of interface. + * Nonblocking mode unsupported. + * + * @param blocking true if connect is blocking + * @return 0 on success, negative error code on failure + */ + nsapi_error_t set_blocking(bool blocking) + { + if (blocking) { + _blocking = blocking; + return NSAPI_ERROR_OK; + } else { + return NSAPI_ERROR_UNSUPPORTED; + } + } protected: WHD_EMAC &_whd_emac;