mirror of https://github.com/ARMmbed/mbed-os.git
Add synchronization and switching between SoftAP/STA
- A shared mutex is added for synchronization - ScopedMutexLock is used to to protect - SoftAP: start, stop - STA: scan, join, disconnect - Fix switching issue between SoftAP and STA mode for primary interface - Avoid reinit primary interface by getting mapping the current interface to the other one which is already on - In concurrent mode, STA is the default if it is up, otherwise SoftAP is default. - For non-concurrent mode, the most recent started interface is set as default.pull/11894/head
parent
f50e7b1da3
commit
b654b76a3c
|
@ -346,6 +346,9 @@ void CyDhcpServer::runServer(void)
|
|||
|
||||
/* Create receive DHCP socket */
|
||||
_socket.open(_nstack);
|
||||
char iface_name[8] = {0};
|
||||
_niface->get_interface_name(iface_name);
|
||||
_socket.setsockopt(NSAPI_SOCKET, NSAPI_BIND_TO_DEVICE, iface_name, strlen(iface_name));
|
||||
_socket.bind((uint16_t)IP_PORT_DHCP_SERVER);
|
||||
|
||||
/* Save the current netmask to be sent in DHCP packets as the 'subnet mask option' */
|
||||
|
|
|
@ -181,13 +181,14 @@ MBED_WEAK WhdSTAInterface::OlmInterface &WhdSTAInterface::OlmInterface::get_defa
|
|||
return olm;
|
||||
}
|
||||
|
||||
WhdSTAInterface::WhdSTAInterface(WHD_EMAC &emac, OnboardNetworkStack &stack, OlmInterface &olm)
|
||||
WhdSTAInterface::WhdSTAInterface(WHD_EMAC &emac, OnboardNetworkStack &stack, OlmInterface &olm, whd_interface_shared_info_t &shared)
|
||||
: EMACInterface(emac, stack),
|
||||
_ssid("\0"),
|
||||
_pass("\0"),
|
||||
_security(NSAPI_SECURITY_NONE),
|
||||
_whd_emac(emac),
|
||||
_olm(&olm)
|
||||
_olm(&olm),
|
||||
_iface_shared(shared)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -233,6 +234,7 @@ nsapi_error_t WhdSTAInterface::set_credentials(const char *ssid, const char *pas
|
|||
|
||||
nsapi_error_t WhdSTAInterface::connect()
|
||||
{
|
||||
ScopedMutexLock lock(_iface_shared.mutex);
|
||||
|
||||
#define MAX_RETRY_COUNT ( 5 )
|
||||
int i;
|
||||
|
@ -249,6 +251,8 @@ nsapi_error_t WhdSTAInterface::connect()
|
|||
return whd_toerror(res);
|
||||
}
|
||||
|
||||
_iface_shared.if_status_flags |= IF_STATUS_STA_UP;
|
||||
_iface_shared.default_if_cfg = DEFAULT_IF_STA;
|
||||
if (!_interface) {
|
||||
nsapi_error_t err = _stack.add_ethernet_interface(_emac, true, &_interface);
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
|
@ -256,6 +260,9 @@ nsapi_error_t WhdSTAInterface::connect()
|
|||
return err;
|
||||
}
|
||||
_interface->attach(_connection_status_cb);
|
||||
_iface_shared.iface_sta = _interface;
|
||||
} else {
|
||||
_stack.set_default_interface(_interface);
|
||||
}
|
||||
|
||||
// Initialize the Offload Manager
|
||||
|
@ -313,6 +320,8 @@ void WhdSTAInterface::wifi_on()
|
|||
|
||||
nsapi_error_t WhdSTAInterface::disconnect()
|
||||
{
|
||||
ScopedMutexLock lock(_iface_shared.mutex);
|
||||
|
||||
if (!_interface) {
|
||||
return NSAPI_STATUS_DISCONNECTED;
|
||||
}
|
||||
|
@ -323,6 +332,14 @@ nsapi_error_t WhdSTAInterface::disconnect()
|
|||
return err;
|
||||
}
|
||||
|
||||
_iface_shared.if_status_flags &= ~IF_STATUS_STA_UP;
|
||||
if (_iface_shared.if_status_flags & IF_STATUS_SOFT_AP_UP) {
|
||||
_iface_shared.default_if_cfg = DEFAULT_IF_SOFT_AP;
|
||||
_stack.set_default_interface(_iface_shared.iface_softap);
|
||||
} else {
|
||||
_iface_shared.default_if_cfg = DEFAULT_IF_NOT_SET;
|
||||
}
|
||||
|
||||
// leave network
|
||||
whd_result_t res = whd_wifi_leave(_whd_emac.ifp);
|
||||
if (res != WHD_SUCCESS) {
|
||||
|
@ -425,6 +442,8 @@ static void whd_scan_handler(whd_scan_result_t **result_ptr,
|
|||
|
||||
int WhdSTAInterface::internal_scan(WiFiAccessPoint *aps, unsigned count, scan_result_type sres_type)
|
||||
{
|
||||
ScopedMutexLock lock(_iface_shared.mutex);
|
||||
|
||||
// initialize wiced, this is noop if already init
|
||||
if (!_whd_emac.powered_up) {
|
||||
_whd_emac.power_up();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "netsocket/OnboardNetworkStack.h"
|
||||
#include "WhdAccessPoint.h"
|
||||
#include "whd_emac.h"
|
||||
#include "whd_interface.h"
|
||||
#include "whd_types_int.h"
|
||||
|
||||
struct ol_desc;
|
||||
|
@ -58,7 +59,8 @@ public:
|
|||
WhdSTAInterface(
|
||||
WHD_EMAC &emac = WHD_EMAC::get_instance(),
|
||||
OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance(),
|
||||
OlmInterface &olm = OlmInterface::get_default_instance());
|
||||
OlmInterface &olm = OlmInterface::get_default_instance(),
|
||||
whd_interface_shared_info_t &shared = whd_iface_shared);
|
||||
|
||||
static WhdSTAInterface *get_default_instance();
|
||||
|
||||
|
@ -246,6 +248,7 @@ private:
|
|||
nsapi_security_t _security;
|
||||
WHD_EMAC &_whd_emac;
|
||||
OlmInterface *_olm;
|
||||
whd_interface_shared_info_t &_iface_shared;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "nsapi.h"
|
||||
#include "lwipopts.h"
|
||||
#include "WhdSoftAPInterface.h"
|
||||
|
@ -27,6 +26,7 @@
|
|||
#include "whd_emac.h"
|
||||
#include "whd_wifi_api.h"
|
||||
|
||||
|
||||
extern int whd_toerror(whd_result_t res);
|
||||
extern nsapi_security_t whd_tosecurity(whd_security_t sec);
|
||||
extern whd_security_t whd_fromsecurity(nsapi_security_t sec);
|
||||
|
@ -58,9 +58,10 @@ static void *whd_default_handle_softap_events(whd_interface_t ifp, const whd_eve
|
|||
}
|
||||
|
||||
|
||||
WhdSoftAPInterface::WhdSoftAPInterface(WHD_EMAC &emac, OnboardNetworkStack &stack)
|
||||
WhdSoftAPInterface::WhdSoftAPInterface(WHD_EMAC &emac, OnboardNetworkStack &stack, whd_interface_shared_info_t &shared)
|
||||
: EMACInterface(emac, stack),
|
||||
_whd_emac(emac)
|
||||
_whd_emac(emac),
|
||||
_iface_shared(shared)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -69,8 +70,9 @@ WhdSoftAPInterface::WhdSoftAPInterface(WHD_EMAC &emac, OnboardNetworkStack &stac
|
|||
int WhdSoftAPInterface::start(const char *ssid, const char *pass, nsapi_security_t security, uint8_t channel,
|
||||
bool start_dhcp_server, const whd_custom_ie_info_t *ie_info, bool ap_sta_concur)
|
||||
{
|
||||
nsapi_error_t err;
|
||||
ScopedMutexLock lock(_iface_shared.mutex);
|
||||
|
||||
nsapi_error_t err;
|
||||
// power up primary emac interface first
|
||||
if (ap_sta_concur) {
|
||||
WHD_EMAC &emac_prime = WHD_EMAC::get_instance(WHD_STA_ROLE);
|
||||
|
@ -116,13 +118,20 @@ int WhdSoftAPInterface::start(const char *ssid, const char *pass, nsapi_security
|
|||
return err;
|
||||
}
|
||||
|
||||
_iface_shared.if_status_flags |= IF_STATUS_SOFT_AP_UP;
|
||||
if (!ap_sta_concur || (_iface_shared.default_if_cfg == DEFAULT_IF_NOT_SET)) {
|
||||
_iface_shared.default_if_cfg = DEFAULT_IF_SOFT_AP;
|
||||
}
|
||||
if (!_interface) {
|
||||
nsapi_error_t err = _stack.add_ethernet_interface(_whd_emac, true, &_interface);
|
||||
nsapi_error_t err = _stack.add_ethernet_interface(_whd_emac, _iface_shared.default_if_cfg == DEFAULT_IF_SOFT_AP, &_interface);
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
_interface = NULL;
|
||||
return err;
|
||||
}
|
||||
_interface->attach(_connection_status_cb);
|
||||
_iface_shared.iface_softap = _interface;
|
||||
} else if (_iface_shared.default_if_cfg == DEFAULT_IF_SOFT_AP) {
|
||||
_stack.set_default_interface(_interface);
|
||||
}
|
||||
|
||||
if (ie_info) {
|
||||
|
@ -169,6 +178,8 @@ int WhdSoftAPInterface::start(const char *ssid, const char *pass, nsapi_security
|
|||
|
||||
int WhdSoftAPInterface::stop(void)
|
||||
{
|
||||
ScopedMutexLock lock(_iface_shared.mutex);
|
||||
|
||||
if (_dhcp_server && CY_RSLT_SUCCESS != _dhcp_server->stop()) {
|
||||
return NSAPI_ERROR_DHCP_FAILURE;
|
||||
}
|
||||
|
@ -180,6 +191,11 @@ int WhdSoftAPInterface::stop(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
_iface_shared.if_status_flags &= ~IF_STATUS_SOFT_AP_UP;
|
||||
if ((_iface_shared.if_status_flags & IF_STATUS_STA_UP) == 0) {
|
||||
_iface_shared.default_if_cfg = DEFAULT_IF_NOT_SET;
|
||||
}
|
||||
|
||||
// stop softap
|
||||
whd_result_t res = whd_wifi_stop_ap(_whd_emac.ifp);
|
||||
if (res != WHD_SUCCESS) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "netsocket/OnboardNetworkStack.h"
|
||||
#include "whd_emac.h"
|
||||
#include "CyDhcpServer.h"
|
||||
#include "whd_interface.h"
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
|
@ -47,7 +48,8 @@ public:
|
|||
* @return pointer to default WhdSoftAPInterface instance
|
||||
*/
|
||||
WhdSoftAPInterface(WHD_EMAC &emac = WHD_EMAC::get_instance(WHD_AP_ROLE),
|
||||
OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance());
|
||||
OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance(),
|
||||
whd_interface_shared_info_t &shared = whd_iface_shared);
|
||||
|
||||
/** Get the default WhdSoftAPInterface instance.
|
||||
* @return pointer to default WhdSoftAPInterface instance
|
||||
|
@ -150,6 +152,7 @@ public:
|
|||
protected:
|
||||
WHD_EMAC &_whd_emac;
|
||||
std::unique_ptr<CyDhcpServer> _dhcp_server;
|
||||
whd_interface_shared_info_t &_iface_shared;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -109,7 +109,13 @@ bool WHD_EMAC::power_up()
|
|||
// wifi driver and turns on the wifi chip.
|
||||
res = cybsp_wifi_init_secondary(&ifp /* Out */, &unicast_addr);
|
||||
} else {
|
||||
WHD_EMAC &emac_other = WHD_EMAC::get_instance(interface_type == WHD_STA_ROLE ? WHD_AP_ROLE :
|
||||
WHD_STA_ROLE);
|
||||
if (!emac_other.powered_up) {
|
||||
res = cybsp_wifi_init_primary(&ifp /* OUT */);
|
||||
} else {
|
||||
ifp = emac_other.ifp;
|
||||
}
|
||||
}
|
||||
|
||||
if (CY_RSLT_SUCCESS == res) {
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
#include "WhdSTAInterface.h"
|
||||
#include "WhdSoftAPInterface.h"
|
||||
#include "whd_interface.h"
|
||||
|
||||
whd_interface_shared_info_t whd_iface_shared;
|
||||
|
||||
WiFiInterface *WiFiInterface::get_target_default_instance()
|
||||
{
|
|
@ -0,0 +1,51 @@
|
|||
/* WHD implementation of NetworkInterfaceAPI
|
||||
* 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_INTERFACE_H
|
||||
#define WHD_INTERFACE_H
|
||||
|
||||
#include "rtos/Mutex.h"
|
||||
#include "OnboardNetworkStack.h"
|
||||
|
||||
/** WhdSTAInterface class
|
||||
* Shared information
|
||||
*/
|
||||
#define IF_STATUS_ALL_IF_DOWN 0x0
|
||||
#define IF_STATUS_STA_UP 0x1
|
||||
#define IF_STATUS_SOFT_AP_UP 0x2
|
||||
|
||||
enum whd_default_interface_config
|
||||
{
|
||||
DEFAULT_IF_NOT_SET,
|
||||
DEFAULT_IF_STA,
|
||||
DEFAULT_IF_SOFT_AP
|
||||
};
|
||||
|
||||
struct whd_interface_shared_info_t {
|
||||
rtos::Mutex mutex;
|
||||
whd_default_interface_config default_if_cfg;
|
||||
uint32_t if_status_flags;
|
||||
OnboardNetworkStack::Interface *iface_sta;
|
||||
OnboardNetworkStack::Interface *iface_softap;
|
||||
whd_interface_shared_info_t() : default_if_cfg(DEFAULT_IF_NOT_SET), if_status_flags(IF_STATUS_ALL_IF_DOWN),
|
||||
iface_sta(NULL), iface_softap(NULL)
|
||||
{}
|
||||
};
|
||||
|
||||
extern whd_interface_shared_info_t whd_iface_shared;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue