-
-
Notifications
You must be signed in to change notification settings - Fork 180
/
Copy pathNF_ESP32_Wireless.cpp
529 lines (424 loc) · 14 KB
/
NF_ESP32_Wireless.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//
// This file includes the board specific Ethernet Initialisation
#include "NF_ESP32_Network.h"
#include "esp_netif_net_stack.h"
#if defined(CONFIG_SOC_WIFI_SUPPORTED)
static const char *TAG = "wifi";
static wifi_mode_t wifiMode;
// flag to store if Wi-Fi has been initialized
static bool IsWifiInitialised = false;
static esp_netif_t *wifiStaNetif = NULL;
static esp_netif_t *wifiAPNetif = NULL;
// flag to signal if connect is to happen
bool NF_ESP32_IsToConnect = false;
//
// Check what is the required Wi-Fi mode
// Station only or AP only or Station and AP
//
// See what network interfaces are enabled
//
wifi_mode_t NF_ESP32_CheckExpectedWifiMode()
{
wifi_mode_t mode = WIFI_MODE_NULL;
HAL_Configuration_Wireless80211 *wirelessConfig = NULL;
HAL_Configuration_WirelessAP *wirelessAPConfig = NULL;
HAL_Configuration_NetworkInterface *networkConfig =
(HAL_Configuration_NetworkInterface *)platform_malloc(sizeof(HAL_Configuration_NetworkInterface));
// check allocation
if (networkConfig == NULL)
{
return WIFI_MODE_NULL;
}
// Check Wi-Fi station available
if (g_TargetConfiguration.NetworkInterfaceConfigs->Count >= 1)
{
// get config Index 0 (Wireless station config in ESP32)
if (ConfigurationManager_GetConfigurationBlock(networkConfig, DeviceConfigurationOption_Network, 0))
{
// Wireless Config with SSID setup
if (networkConfig->InterfaceType == NetworkInterfaceType::NetworkInterfaceType_Wireless80211)
{
wirelessConfig = ConfigurationManager_GetWirelessConfigurationFromId(networkConfig->SpecificConfigId);
if (wirelessConfig != NULL)
{
if (wirelessConfig->Options & Wireless80211Configuration_ConfigurationOptions_Enable)
{
mode = WIFI_MODE_STA;
}
}
}
}
}
// Check if AP config available
if (g_TargetConfiguration.NetworkInterfaceConfigs->Count >= 2)
{
// get config Index 1 (Wireless AP config in ESP32)
if (ConfigurationManager_GetConfigurationBlock(networkConfig, DeviceConfigurationOption_Network, 1))
{
// Wireless Config with SSID setup
if (networkConfig->InterfaceType == NetworkInterfaceType::NetworkInterfaceType_WirelessAP)
{
wirelessAPConfig =
ConfigurationManager_GetWirelessAPConfigurationFromId(networkConfig->SpecificConfigId);
if (wirelessAPConfig != NULL)
{
if (wirelessAPConfig->Options & WirelessAPConfiguration_ConfigurationOptions_Enable)
{
// Use STATION + AP or just AP
mode = (mode == WIFI_MODE_STA) ? WIFI_MODE_APSTA : WIFI_MODE_AP;
}
}
}
}
}
// this one is always set
platform_free(networkConfig);
// free this one, if it was allocated
if (wirelessConfig)
{
platform_free(wirelessConfig);
}
return mode;
}
wifi_mode_t NF_ESP32_GetCurrentWifiMode()
{
wifi_mode_t current_wifi_mode;
esp_wifi_get_mode(¤t_wifi_mode);
return current_wifi_mode;
}
esp_err_t NF_ESP32_ConfigureNetworkStation(esp_netif_t *netIf)
{
return NF_ESP32_ConfigureNetworkByIndex(IDF_WIFI_STA_DEF, netIf);
}
void NF_ESP32_DeinitWifi()
{
// clear flags
IsWifiInitialised = false;
NF_ESP32_IsToConnect = false;
esp_wifi_stop();
esp_netif_destroy_default_wifi(wifiStaNetif);
wifiStaNetif = NULL;
esp_netif_destroy_default_wifi(wifiAPNetif);
wifiAPNetif = NULL;
esp_wifi_deinit();
}
esp_err_t NF_ESP32_InitaliseWifi()
{
esp_err_t ec = ESP_OK;
wifi_mode_t expectedWifiMode = NF_ESP32_CheckExpectedWifiMode();
if (IsWifiInitialised)
{
// Check if we are running correct mode
if (NF_ESP32_GetCurrentWifiMode() != expectedWifiMode)
{
// if not force a new initialization
NF_ESP32_DeinitWifi();
}
}
// Don't init if Wi-Fi Mode null (Disabled)
if (expectedWifiMode == WIFI_MODE_NULL)
{
return ESP_FAIL;
}
if (!IsWifiInitialised)
{
// create Wi-Fi STA (ignoring return)
wifiStaNetif = esp_netif_create_default_wifi_sta();
// Set static address if configured
// ignore any errors
ec = NF_ESP32_ConfigureNetworkStation(wifiStaNetif);
if (ec != ESP_OK)
{
ESP_LOGE(TAG, "Unable to configure Wifi station - result %d", ec);
}
// We need to start the WIFI stack before the station can Connect
// Also we can only get the NetIf number used by ESP IDF after it has been started.
// Starting will also start the Soft- AP (if we have enabled it).
// So make sure it configured as per wireless config otherwise we will get the default SSID
if (expectedWifiMode & WIFI_MODE_AP)
{
// create AP (ignoring return)
wifiAPNetif = esp_netif_create_default_wifi_ap();
// Remove DHCP server flag as not configured in sdkconfig, DHCP server done in managed code
// Otherwise startup hangs
if (wifiAPNetif)
{
wifiAPNetif->flags = (esp_netif_flags_t)(ESP_NETIF_FLAG_AUTOUP);
}
}
// Initialise WiFi, allocate resource for WiFi driver, such as WiFi control structure,
// RX/TX buffer, WiFi NVS structure etc, this WiFi also start WiFi task.
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
#if CONFIG_SPIRAM_IGNORE_NOTFOUND
// The comment out function below is only avaliable in ESP IDF 5.1x
// if (!esp_psram_is_initialized()){
if (heap_caps_get_total_size(MALLOC_CAP_SPIRAM) == 0)
{
cfg.cache_tx_buf_num = 0;
cfg.feature_caps &= ~CONFIG_FEATURE_CACHE_TX_BUF_BIT;
}
#endif
ec = esp_wifi_init(&cfg);
if (ec != ESP_OK)
{
return ec;
}
// set Wi-Fi mode
ec = esp_wifi_set_mode(expectedWifiMode);
if (ec != ESP_OK)
{
return ec;
}
// start Wi-Fi
ec = esp_wifi_start();
if (ec != ESP_OK)
{
return ec;
}
// if need, config the AP
// this can only be performed after Wi-Fi is started
if (expectedWifiMode & WIFI_MODE_AP)
{
HAL_Configuration_NetworkInterface *networkConfig =
(HAL_Configuration_NetworkInterface *)platform_malloc(sizeof(HAL_Configuration_NetworkInterface));
if (networkConfig == NULL)
{
return ESP_FAIL;
}
if (ConfigurationManager_GetConfigurationBlock(networkConfig, DeviceConfigurationOption_Network, 1))
{
// take care of configuring Soft AP
ec = NF_ESP32_WirelessAP_Configure(networkConfig);
platform_free(networkConfig);
}
if (ec != ESP_OK)
{
return ec;
}
}
IsWifiInitialised = true;
}
return ec;
}
esp_err_t NF_ESP32_Wireless_Start_Connect(HAL_Configuration_Wireless80211 *config)
{
esp_err_t ec;
// Connect directly
wifi_config_t sta_config = {};
hal_strncpy_s(
(char *)sta_config.sta.ssid,
sizeof(sta_config.sta.ssid),
(char *)config->Ssid,
hal_strlen_s((char *)config->Ssid));
hal_strncpy_s(
(char *)sta_config.sta.password,
sizeof(sta_config.sta.password),
(char *)config->Password,
hal_strlen_s((char *)config->Password));
sta_config.sta.bssid_set = false;
ec = esp_wifi_set_config(WIFI_IF_STA, &sta_config);
if (ec != ESP_OK)
{
return ec;
}
// set flag
NF_ESP32_IsToConnect = true;
// call disconnect to be sure that connect event is raised again
esp_wifi_disconnect();
// call connect
esp_wifi_connect();
return ESP_OK;
}
esp_err_t NF_ESP32_Wireless_Disconnect()
{
esp_err_t ec;
NF_ESP32_IsToConnect = false;
ec = esp_wifi_disconnect();
if (ec != ESP_OK)
{
return ec;
}
return ESP_OK;
}
int NF_ESP32_Wireless_Open(HAL_Configuration_NetworkInterface *config)
{
esp_err_t ec;
bool okToStartSmartConnect = false;
ec = NF_ESP32_InitaliseWifi();
if (ec != ESP_OK)
{
return SOCK_SOCKET_ERROR;
}
// Get Wireless config
HAL_Configuration_Wireless80211 *wirelessConfig =
ConfigurationManager_GetWirelessConfigurationFromId(config->SpecificConfigId);
if (wirelessConfig == NULL)
{
return SOCK_SOCKET_ERROR;
}
// Wireless station not enabled
if (!(NF_ESP32_GetCurrentWifiMode() & WIFI_MODE_STA))
{
return SOCK_SOCKET_ERROR;
}
// sanity check for Wireless station disabled
if (wirelessConfig->Options & Wireless80211Configuration_ConfigurationOptions_Disable)
{
return SOCK_SOCKET_ERROR;
}
// Connect if Auto connect and we have an SSID
if ((wirelessConfig->Options & Wireless80211Configuration_ConfigurationOptions_AutoConnect) &&
(hal_strlen_s((const char *)wirelessConfig->Ssid) > 0))
{
NF_ESP32_Wireless_Start_Connect(wirelessConfig);
// don't start smart connect
okToStartSmartConnect = false;
}
else
{
// clear flag
NF_ESP32_IsToConnect = false;
}
if (okToStartSmartConnect &&
(wirelessConfig->Options & Wireless80211Configuration_ConfigurationOptions_SmartConfig))
{
// Start Smart config (if enabled)
NF_ESP32_Start_wifi_smart_config();
// clear flag
NF_ESP32_IsToConnect = false;
}
return NF_ESP32_Wait_NetNumber(IDF_WIFI_STA_DEF);
}
bool NF_ESP32_Wireless_Close()
{
if (IsWifiInitialised)
{
NF_ESP32_DeinitWifi();
}
return false;
}
// Start a scan
int NF_ESP32_Wireless_Scan()
{
wifi_scan_config_t config = {};
config.scan_type = WIFI_SCAN_TYPE_PASSIVE;
// 500ms
config.scan_time.passive = 500;
// Start a Wi-Fi scan
// When complete a Scan Complete event will be fired
return esp_wifi_scan_start(&config, false);
}
wifi_auth_mode_t MapAuthentication(AuthenticationType type)
{
wifi_auth_mode_t mapAuth[] = {
WIFI_AUTH_OPEN, // 0 None
WIFI_AUTH_OPEN, // 1 EAP
WIFI_AUTH_OPEN, // 2 PEAP
WIFI_AUTH_OPEN, // 3 WCN
WIFI_AUTH_OPEN, // 4 Open
WIFI_AUTH_OPEN, // 5 Shared
WIFI_AUTH_WEP, // 6 WEP
WIFI_AUTH_WPA_PSK, // 7 WPA
WIFI_AUTH_WPA_WPA2_PSK // 8 WPA2
};
return mapAuth[type];
}
esp_err_t NF_ESP32_WirelessAP_Configure(HAL_Configuration_NetworkInterface *config)
{
esp_err_t ec;
esp_netif_ip_info_t ip_info;
esp_netif_t *espNetif = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF");
ec = esp_netif_get_ip_info(espNetif, &ip_info);
if (config->IPv4Address != 0)
{
ip_info.ip.addr = config->IPv4Address;
ip_info.netmask.addr = config->IPv4NetMask;
ip_info.gw.addr = config->IPv4GatewayAddress;
ec = esp_netif_set_ip_info(espNetif, &ip_info);
}
else
{
config->IPv4Address = ip_info.ip.addr;
config->IPv4NetMask = ip_info.netmask.addr;
config->IPv4GatewayAddress = ip_info.gw.addr;
}
HAL_Configuration_WirelessAP *apConfig =
ConfigurationManager_GetWirelessAPConfigurationFromId(config->SpecificConfigId);
if (apConfig == 0)
{
return ESP_FAIL;
}
wifi_config_t ap_config = {0};
hal_strncpy_s(
(char *)ap_config.ap.ssid,
sizeof(ap_config.ap.ssid),
(char *)apConfig->Ssid,
hal_strlen_s((char *)apConfig->Ssid));
hal_strncpy_s(
(char *)ap_config.ap.password,
sizeof(ap_config.ap.password),
(char *)apConfig->Password,
hal_strlen_s((char *)apConfig->Password));
ap_config.ap.ssid_len = hal_strlen_s((char *)apConfig->Ssid);
ap_config.ap.channel = apConfig->Channel;
ap_config.ap.ssid_hidden = (apConfig->Options & WirelessAPConfiguration_ConfigurationOptions_HiddenSSID) ? 1 : 0;
ap_config.ap.authmode = MapAuthentication(apConfig->Authentication);
if (hal_strlen_s((char *)ap_config.ap.password) == 0)
{
ap_config.ap.authmode = WIFI_AUTH_OPEN;
}
// Max connections for ESP32
ap_config.ap.max_connection = apConfig->MaxConnections;
if (ap_config.ap.max_connection > ESP_WIFI_MAX_CONN_NUM)
{
ap_config.ap.max_connection = ESP_WIFI_MAX_CONN_NUM;
}
ap_config.ap.beacon_interval = 100;
ec = esp_wifi_set_config(WIFI_IF_AP, &ap_config);
if (ec != ESP_OK)
{
ESP_LOGE(TAG, "WiFi set AP config - result %d", ec);
}
return ec;
}
//
// Open Wireless Soft AP
//
// If AP is enabled it will have been configured and started running when the WiFI stack is initialised
// All we need to do here is return the NetIf number used by ESP IDF
// Also make sure Wi-Fi in initialised correctly if config is changed
int IRAM_ATTR NF_ESP32_WirelessAP_Open(HAL_Configuration_NetworkInterface *config)
{
esp_err_t ec;
// Initialise Wi-Fi stack if required
ec = NF_ESP32_InitaliseWifi();
if (ec != ESP_OK)
{
return SOCK_SOCKET_ERROR;
}
// AP mode enabled ?
if (!(NF_ESP32_GetCurrentWifiMode() & WIFI_MODE_AP))
{
return SOCK_SOCKET_ERROR;
}
// Return NetIf number
// FIXME find a better way to get the netif ptr
// This becomes available on the event AP STARTED
// for the moment we just wait for it
return NF_ESP32_Wait_NetNumber(IDF_WIFI_AP_DEF);
}
//
// Closing down AP
//
// Either config being updated or shutdown
// Closing AP will also stop Station
//
bool NF_ESP32_WirelessAP_Close()
{
NF_ESP32_DeinitWifi();
return true;
}
#endif