Skip to content

Commit 28884b5

Browse files
committed
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.
1 parent 1798c24 commit 28884b5

File tree

8 files changed

+114
-10
lines changed

8 files changed

+114
-10
lines changed

features/netsocket/emac-drivers/TARGET_WHD/interface/CyDhcpServer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,9 @@ void CyDhcpServer::runServer(void)
346346

347347
/* Create receive DHCP socket */
348348
_socket.open(_nstack);
349+
char iface_name[8] = {0};
350+
_niface->get_interface_name(iface_name);
351+
_socket.setsockopt(NSAPI_SOCKET, NSAPI_BIND_TO_DEVICE, iface_name, strlen(iface_name));
349352
_socket.bind((uint16_t)IP_PORT_DHCP_SERVER);
350353

351354
/* Save the current netmask to be sent in DHCP packets as the 'subnet mask option' */

features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSTAInterface.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,14 @@ MBED_WEAK WhdSTAInterface::OlmInterface &WhdSTAInterface::OlmInterface::get_defa
179179
return olm;
180180
}
181181

182-
WhdSTAInterface::WhdSTAInterface(WHD_EMAC &emac, OnboardNetworkStack &stack, OlmInterface &olm)
182+
WhdSTAInterface::WhdSTAInterface(WHD_EMAC &emac, OnboardNetworkStack &stack, OlmInterface &olm, whd_interface_shared_info_t &shared)
183183
: EMACInterface(emac, stack),
184184
_ssid("\0"),
185185
_pass("\0"),
186186
_security(NSAPI_SECURITY_NONE),
187187
_whd_emac(emac),
188-
_olm(&olm)
188+
_olm(&olm),
189+
_iface_shared(shared)
189190
{
190191
}
191192

@@ -231,6 +232,7 @@ nsapi_error_t WhdSTAInterface::set_credentials(const char *ssid, const char *pas
231232

232233
nsapi_error_t WhdSTAInterface::connect()
233234
{
235+
ScopedMutexLock lock(_iface_shared.mutex);
234236

235237
#define MAX_RETRY_COUNT ( 5 )
236238
int i;
@@ -247,13 +249,18 @@ nsapi_error_t WhdSTAInterface::connect()
247249
return whd_toerror(res);
248250
}
249251

252+
_iface_shared.if_status_flags |= IF_STATUS_STA_UP;
253+
_iface_shared.default_if_cfg = DEFAULT_IF_STA;
250254
if (!_interface) {
251255
nsapi_error_t err = _stack.add_ethernet_interface(_emac, true, &_interface);
252256
if (err != NSAPI_ERROR_OK) {
253257
_interface = NULL;
254258
return err;
255259
}
256260
_interface->attach(_connection_status_cb);
261+
_iface_shared.iface_sta = _interface;
262+
} else {
263+
_stack.set_default_interface(_interface);
257264
}
258265

259266
// Initialize the Offload Manager
@@ -311,6 +318,8 @@ void WhdSTAInterface::wifi_on()
311318

312319
nsapi_error_t WhdSTAInterface::disconnect()
313320
{
321+
ScopedMutexLock lock(_iface_shared.mutex);
322+
314323
if (!_interface) {
315324
return NSAPI_STATUS_DISCONNECTED;
316325
}
@@ -321,6 +330,14 @@ nsapi_error_t WhdSTAInterface::disconnect()
321330
return err;
322331
}
323332

333+
_iface_shared.if_status_flags &= ~IF_STATUS_STA_UP;
334+
if (_iface_shared.if_status_flags & IF_STATUS_SOFT_AP_UP) {
335+
_iface_shared.default_if_cfg = DEFAULT_IF_SOFT_AP;
336+
_stack.set_default_interface(_iface_shared.iface_softap);
337+
} else {
338+
_iface_shared.default_if_cfg = DEFAULT_IF_NOT_SET;
339+
}
340+
324341
// leave network
325342
whd_result_t res = whd_wifi_leave(_whd_emac.ifp);
326343
if (res != WHD_SUCCESS) {
@@ -420,6 +437,8 @@ static void whd_scan_handler(whd_scan_result_t **result_ptr,
420437

421438
int WhdSTAInterface::scan(WiFiAccessPoint *aps, unsigned count)
422439
{
440+
ScopedMutexLock lock(_iface_shared.mutex);
441+
423442
// initialize wiced, this is noop if already init
424443
if (!_whd_emac.powered_up) {
425444
_whd_emac.power_up();

features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSTAInterface.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "netsocket/EMACInterface.h"
2323
#include "netsocket/OnboardNetworkStack.h"
2424
#include "whd_emac.h"
25+
#include "whd_interface.h"
2526
#include "whd_types_int.h"
2627

2728
struct ol_desc;
@@ -58,7 +59,8 @@ class WhdSTAInterface : public WiFiInterface, public EMACInterface {
5859
WhdSTAInterface(
5960
WHD_EMAC &emac = WHD_EMAC::get_instance(),
6061
OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance(),
61-
OlmInterface &olm = OlmInterface::get_default_instance());
62+
OlmInterface &olm = OlmInterface::get_default_instance(),
63+
whd_interface_shared_info_t &shared = whd_iface_shared);
6264

6365
static WhdSTAInterface *get_default_instance();
6466

@@ -215,6 +217,7 @@ class WhdSTAInterface : public WiFiInterface, public EMACInterface {
215217
nsapi_security_t _security;
216218
WHD_EMAC &_whd_emac;
217219
OlmInterface *_olm;
220+
whd_interface_shared_info_t &_iface_shared;
218221
};
219222

220223
#endif

features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSoftAPInterface.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
* limitations under the License.
1616
*/
1717

18-
1918
#include "nsapi.h"
2019
#include "lwipopts.h"
2120
#include "WhdSoftAPInterface.h"
@@ -27,6 +26,7 @@
2726
#include "whd_emac.h"
2827
#include "whd_wifi_api.h"
2928

29+
3030
extern int whd_toerror(whd_result_t res);
3131
extern nsapi_security_t whd_tosecurity(whd_security_t sec);
3232
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
5858
}
5959

6060

61-
WhdSoftAPInterface::WhdSoftAPInterface(WHD_EMAC &emac, OnboardNetworkStack &stack)
61+
WhdSoftAPInterface::WhdSoftAPInterface(WHD_EMAC &emac, OnboardNetworkStack &stack, whd_interface_shared_info_t &shared)
6262
: EMACInterface(emac, stack),
63-
_whd_emac(emac)
63+
_whd_emac(emac),
64+
_iface_shared(shared)
6465
{
6566

6667
}
@@ -69,8 +70,9 @@ WhdSoftAPInterface::WhdSoftAPInterface(WHD_EMAC &emac, OnboardNetworkStack &stac
6970
int WhdSoftAPInterface::start(const char *ssid, const char *pass, nsapi_security_t security, uint8_t channel,
7071
bool start_dhcp_server, const whd_custom_ie_info_t *ie_info, bool ap_sta_concur)
7172
{
72-
nsapi_error_t err;
73+
ScopedMutexLock lock(_iface_shared.mutex);
7374

75+
nsapi_error_t err;
7476
// power up primary emac interface first
7577
if (ap_sta_concur) {
7678
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
116118
return err;
117119
}
118120

121+
_iface_shared.if_status_flags |= IF_STATUS_SOFT_AP_UP;
122+
if (!ap_sta_concur || (_iface_shared.default_if_cfg == DEFAULT_IF_NOT_SET)) {
123+
_iface_shared.default_if_cfg = DEFAULT_IF_SOFT_AP;
124+
}
119125
if (!_interface) {
120-
nsapi_error_t err = _stack.add_ethernet_interface(_whd_emac, true, &_interface);
126+
nsapi_error_t err = _stack.add_ethernet_interface(_whd_emac, _iface_shared.default_if_cfg == DEFAULT_IF_SOFT_AP, &_interface);
121127
if (err != NSAPI_ERROR_OK) {
122128
_interface = NULL;
123129
return err;
124130
}
125131
_interface->attach(_connection_status_cb);
132+
_iface_shared.iface_softap = _interface;
133+
} else if (_iface_shared.default_if_cfg == DEFAULT_IF_SOFT_AP) {
134+
_stack.set_default_interface(_interface);
126135
}
127136

128137
if (ie_info) {
@@ -169,6 +178,8 @@ int WhdSoftAPInterface::start(const char *ssid, const char *pass, nsapi_security
169178

170179
int WhdSoftAPInterface::stop(void)
171180
{
181+
ScopedMutexLock lock(_iface_shared.mutex);
182+
172183
if (_dhcp_server && CY_RSLT_SUCCESS != _dhcp_server->stop()) {
173184
return NSAPI_ERROR_DHCP_FAILURE;
174185
}
@@ -180,6 +191,11 @@ int WhdSoftAPInterface::stop(void)
180191
return err;
181192
}
182193

194+
_iface_shared.if_status_flags &= ~IF_STATUS_SOFT_AP_UP;
195+
if ((_iface_shared.if_status_flags & IF_STATUS_STA_UP) == 0) {
196+
_iface_shared.default_if_cfg = DEFAULT_IF_NOT_SET;
197+
}
198+
183199
// stop softap
184200
whd_result_t res = whd_wifi_stop_ap(_whd_emac.ifp);
185201
if (res != WHD_SUCCESS) {

features/netsocket/emac-drivers/TARGET_WHD/interface/WhdSoftAPInterface.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "netsocket/OnboardNetworkStack.h"
2424
#include "whd_emac.h"
2525
#include "CyDhcpServer.h"
26+
#include "whd_interface.h"
2627
#include <memory>
2728

2829
/**
@@ -47,7 +48,8 @@ class WhdSoftAPInterface : public EMACInterface {
4748
* @return pointer to default WhdSoftAPInterface instance
4849
*/
4950
WhdSoftAPInterface(WHD_EMAC &emac = WHD_EMAC::get_instance(WHD_AP_ROLE),
50-
OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance());
51+
OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance(),
52+
whd_interface_shared_info_t &shared = whd_iface_shared);
5153

5254
/** Get the default WhdSoftAPInterface instance.
5355
* @return pointer to default WhdSoftAPInterface instance
@@ -135,6 +137,7 @@ class WhdSoftAPInterface : public EMACInterface {
135137
protected:
136138
WHD_EMAC &_whd_emac;
137139
std::unique_ptr<CyDhcpServer> _dhcp_server;
140+
whd_interface_shared_info_t &_iface_shared;
138141
};
139142

140143
#endif

features/netsocket/emac-drivers/TARGET_WHD/interface/whd_emac.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,13 @@ bool WHD_EMAC::power_up()
109109
// wifi driver and turns on the wifi chip.
110110
res = cybsp_wifi_init_secondary(&ifp /* Out */, &unicast_addr);
111111
} else {
112-
res = cybsp_wifi_init_primary(&ifp /* OUT */);
112+
WHD_EMAC &emac_other = WHD_EMAC::get_instance(interface_type == WHD_STA_ROLE ? WHD_AP_ROLE :
113+
WHD_STA_ROLE);
114+
if (!emac_other.powered_up) {
115+
res = cybsp_wifi_init_primary(&ifp /* OUT */);
116+
} else {
117+
ifp = emac_other.ifp;
118+
}
113119
}
114120

115121
if (CY_RSLT_SUCCESS == res) {

features/netsocket/emac-drivers/TARGET_WHD/interface/default_wifi_interface.cpp renamed to features/netsocket/emac-drivers/TARGET_WHD/interface/whd_interface.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
#include "WhdSTAInterface.h"
1919
#include "WhdSoftAPInterface.h"
20+
#include "whd_interface.h"
21+
22+
whd_interface_shared_info_t whd_iface_shared;
2023

2124
WiFiInterface *WiFiInterface::get_target_default_instance()
2225
{
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* WHD implementation of NetworkInterfaceAPI
2+
* Copyright (c) 2017-2019 ARM Limited
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef WHD_INTERFACE_H
19+
#define WHD_INTERFACE_H
20+
21+
#include "rtos/Mutex.h"
22+
#include "OnboardNetworkStack.h"
23+
24+
/** WhdSTAInterface class
25+
* Shared information
26+
*/
27+
#define IF_STATUS_ALL_IF_DOWN 0x0
28+
#define IF_STATUS_STA_UP 0x1
29+
#define IF_STATUS_SOFT_AP_UP 0x2
30+
31+
enum whd_default_interface_config
32+
{
33+
DEFAULT_IF_NOT_SET,
34+
DEFAULT_IF_STA,
35+
DEFAULT_IF_SOFT_AP
36+
};
37+
38+
struct whd_interface_shared_info_t {
39+
rtos::Mutex mutex;
40+
whd_default_interface_config default_if_cfg;
41+
uint32_t if_status_flags;
42+
OnboardNetworkStack::Interface *iface_sta;
43+
OnboardNetworkStack::Interface *iface_softap;
44+
whd_interface_shared_info_t() : default_if_cfg(DEFAULT_IF_NOT_SET), if_status_flags(IF_STATUS_ALL_IF_DOWN),
45+
iface_sta(NULL), iface_softap(NULL)
46+
{}
47+
};
48+
49+
extern whd_interface_shared_info_t whd_iface_shared;
50+
51+
#endif

0 commit comments

Comments
 (0)