1 /*
2 * Copyright (c) 2018, Texas Instruments Incorporated
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 */
7
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include "simplelink_log.h"
12 LOG_MODULE_DECLARE(LOG_MODULE_NAME);
13
14 #include <zephyr/kernel.h>
15 #include <stdint.h>
16
17 #include <ti/drivers/net/wifi/simplelink.h>
18 #include <ti/net/slnetif.h>
19 #include <ti/net/slnetutils.h>
20 #include <ti/drivers/net/wifi/slnetifwifi.h>
21 #include <CC3220SF_LAUNCHXL.h>
22
23 #include "simplelink_support.h"
24
25 #define SET_STATUS_BIT(status, bit) {status |= (1 << (bit)); }
26 #define CLR_STATUS_BIT(status, bit) {status &= ~(1 << (bit)); }
27 #define GET_STATUS_BIT(status, bit) (0 != (status & (1 << (bit))))
28
29 #define SL_STOP_TIMEOUT (200)
30
31 #undef ASSERT_ON_ERROR
32 #define ASSERT_ON_ERROR(ret, e) __ASSERT(ret >= 0, e)
33 #define DEVICE_ERROR "See \"DEVICE ERRORS CODES\" in SimpleLink errors.h"
34 #define WLAN_ERROR "See \"WLAN ERRORS CODES\" in SimpleLink errors.h"
35 #define NETAPP_ERROR "See \"NETAPP ERRORS CODES\" in SimpleLink errors.h"
36
37 #define CHANNEL_MASK_ALL (0x1FFF)
38 #define RSSI_TH_MAX (-95)
39
40 #define SLNET_IF_WIFI_PRIO (5)
41 #define SLNET_IF_WIFI_NAME "CC32xx"
42
43 enum status_bits {
44 /* Network Processor is powered up */
45 STATUS_BIT_NWP_INIT = 0,
46 /* The device is connected to the AP */
47 STATUS_BIT_CONNECTION,
48 /* The device has leased IP to any connected client */
49 STATUS_BIT_IP_LEASED,
50 /* The device has acquired an IP */
51 STATUS_BIT_IP_ACQUIRED,
52 /* The device has acquired an IPv6 address */
53 STATUS_BIT_IPV6_ACQUIRED,
54 };
55
56 struct nwp_status {
57 /* Callback to notify net & wifi mgmt events from SL Event Handlers */
58 simplelink_wifi_cb_t cb;
59
60 /* Status Variables */
61 uint32_t status; /* The state of the NWP */
62 uint32_t role; /* The device's role (STA, P2P or AP) */
63
64 /* Scan results table: */
65 SlWlanNetworkEntry_t net_entries[CONFIG_WIFI_SIMPLELINK_SCAN_COUNT];
66 };
67
68 /* STA/AP mode state: shared with simplelink.c */
69 struct sl_connect_state sl_conn;
70
71 /* Network Coprocessor state, including role and connection state: */
72 static struct nwp_status nwp;
73
74 /* Minimal configuration of SlNetIfWifi for Zephyr */
75 static SlNetIf_Config_t slnetifwifi_config_zephyr = {
76 .sockCreate = SlNetIfWifi_socket,
77 .sockClose = SlNetIfWifi_close,
78 .sockSelect = SlNetIfWifi_select,
79 .sockSetOpt = SlNetIfWifi_setSockOpt,
80 .sockGetOpt = SlNetIfWifi_getSockOpt,
81 .sockRecvFrom = SlNetIfWifi_recvFrom,
82 .sockSendTo = SlNetIfWifi_sendTo,
83 .utilGetHostByName = SlNetIfWifi_getHostByName,
84 .ifGetIPAddr = SlNetIfWifi_getIPAddr,
85 .ifGetConnectionStatus = SlNetIfWifi_getConnectionStatus
86 };
87
88 /* Configure the device to a default state, resetting previous parameters .*/
configure_simplelink(void)89 static int32_t configure_simplelink(void)
90 {
91 int32_t retval = -1;
92 int32_t mode = -1;
93 uint32_t if_bitmap = 0U;
94 SlWlanScanParamCommand_t scan_default = { 0 };
95 SlWlanRxFilterOperationCommandBuff_t rx_filterid_mask = { { 0 } };
96 uint8_t config_opt;
97 uint8_t power;
98
99 #if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_CONFIG_MY_IPV4_ADDR)
100 struct in_addr addr4;
101 SlNetCfgIpV4Args_t ipV4;
102
103 memset(&ipV4, 0, sizeof(ipV4));
104 #endif
105
106 /* Turn on NWP */
107 mode = sl_Start(0, 0, 0);
108 ASSERT_ON_ERROR(mode, DEVICE_ERROR);
109
110 if (mode != ROLE_STA) {
111 /* Set NWP role as STA */
112 mode = sl_WlanSetMode(ROLE_STA);
113 ASSERT_ON_ERROR(mode, WLAN_ERROR);
114
115 /* For changes to take affect, we restart the NWP */
116 retval = sl_Stop(SL_STOP_TIMEOUT);
117 ASSERT_ON_ERROR(retval, DEVICE_ERROR);
118
119 mode = sl_Start(0, 0, 0);
120 ASSERT_ON_ERROR(mode, DEVICE_ERROR);
121 }
122
123 if (mode != ROLE_STA) {
124 LOG_ERR("Failed to configure NWP to default state");
125 return -1;
126 }
127
128 /* Use Fast Connect Policy, to automatically connect to last AP: */
129 retval = sl_WlanPolicySet(SL_WLAN_POLICY_CONNECTION,
130 SL_WLAN_CONNECTION_POLICY(1, 1, 0, 0),
131 NULL, 0);
132 ASSERT_ON_ERROR(retval, WLAN_ERROR);
133
134 /* Disable Auto Provisioning*/
135 retval = sl_WlanProvisioning(SL_WLAN_PROVISIONING_CMD_STOP, 0xFF, 0,
136 NULL, 0x0);
137 ASSERT_ON_ERROR(retval, WLAN_ERROR);
138
139 /* Delete existing profiles */
140 retval = sl_WlanProfileDel(0xFF);
141 ASSERT_ON_ERROR(retval, WLAN_ERROR);
142
143 #if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_CONFIG_MY_IPV4_ADDR)
144 if (net_addr_pton(AF_INET, CONFIG_NET_CONFIG_MY_IPV4_ADDR, &addr4)
145 < 0) {
146 LOG_ERR("Invalid CONFIG_NET_CONFIG_MY_IPV4_ADDR");
147 return -1;
148 }
149 ipV4.Ip = (_u32)SL_IPV4_VAL(addr4.s4_addr[0],
150 addr4.s4_addr[1],
151 addr4.s4_addr[2],
152 addr4.s4_addr[3]);
153
154 #if defined(CONFIG_NET_CONFIG_MY_IPV4_GW)
155 if (strcmp(CONFIG_NET_CONFIG_MY_IPV4_GW, "") != 0) {
156 if (net_addr_pton(AF_INET, CONFIG_NET_CONFIG_MY_IPV4_GW,
157 &addr4) < 0) {
158 LOG_ERR("Invalid CONFIG_NET_CONFIG_MY_IPV4_GW");
159 return -1;
160 }
161 ipV4.IpGateway = (_u32)SL_IPV4_VAL(addr4.s4_addr[0],
162 addr4.s4_addr[1],
163 addr4.s4_addr[2],
164 addr4.s4_addr[3]);
165 }
166 #endif
167
168 #if defined(CONFIG_NET_CONFIG_MY_IPV4_NETMASK)
169 if (strcmp(CONFIG_NET_CONFIG_MY_IPV4_NETMASK, "") != 0) {
170 if (net_addr_pton(AF_INET, CONFIG_NET_CONFIG_MY_IPV4_NETMASK,
171 &addr4) < 0) {
172 LOG_ERR("Invalid CONFIG_NET_CONFIG_MY_IPV4_NETMASK");
173 return -1;
174 }
175 ipV4.IpMask = (_u32)SL_IPV4_VAL(addr4.s4_addr[0],
176 addr4.s4_addr[1],
177 addr4.s4_addr[2],
178 addr4.s4_addr[3]);
179 }
180 #endif
181
182 retval = sl_NetCfgSet(SL_NETCFG_IPV4_STA_ADDR_MODE,
183 SL_NETCFG_ADDR_STATIC,
184 sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4);
185 ASSERT_ON_ERROR(retval, NETAPP_ERROR);
186 #else
187 /* enable DHCP client */
188 retval = sl_NetCfgSet(SL_NETCFG_IPV4_STA_ADDR_MODE,
189 SL_NETCFG_ADDR_DHCP, 0, 0);
190 ASSERT_ON_ERROR(retval, NETAPP_ERROR);
191 #endif
192
193 #if defined(CONFIG_NET_IPV6)
194 if_bitmap = ~0;
195 #else
196 /* Disable ipv6 */
197 if_bitmap = !(SL_NETCFG_IF_IPV6_STA_LOCAL |
198 SL_NETCFG_IF_IPV6_STA_GLOBAL);
199 #endif
200 retval = sl_NetCfgSet(SL_NETCFG_IF, SL_NETCFG_IF_STATE,
201 sizeof(if_bitmap),
202 (const unsigned char *)&if_bitmap);
203 ASSERT_ON_ERROR(retval, NETAPP_ERROR);
204
205 /* Configure scan parameters to default */
206 scan_default.ChannelsMask = CHANNEL_MASK_ALL;
207 scan_default.RssiThreshold = RSSI_TH_MAX;
208
209 retval = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID,
210 SL_WLAN_GENERAL_PARAM_OPT_SCAN_PARAMS,
211 sizeof(scan_default), (uint8_t *)&scan_default);
212 ASSERT_ON_ERROR(retval, WLAN_ERROR);
213
214 /* Disable scans: In other words, use "one-shot" scanning */
215 config_opt = SL_WLAN_SCAN_POLICY(0, 0);
216 retval = sl_WlanPolicySet(SL_WLAN_POLICY_SCAN, config_opt, NULL, 0);
217 ASSERT_ON_ERROR(retval, WLAN_ERROR);
218
219 /* Set TX power lvl to max */
220 power = 0U;
221 retval = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID,
222 SL_WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1,
223 (uint8_t *)&power);
224 ASSERT_ON_ERROR(retval, WLAN_ERROR);
225
226 /* Set NWP Power policy to 'normal' */
227 retval = sl_WlanPolicySet(SL_WLAN_POLICY_PM, SL_WLAN_NORMAL_POLICY,
228 NULL, 0);
229 ASSERT_ON_ERROR(retval, WLAN_ERROR);
230
231 /* Unregister mDNS services */
232 retval = sl_NetAppMDNSUnRegisterService(0, 0, 0);
233 ASSERT_ON_ERROR(retval, NETAPP_ERROR);
234
235 /* Remove all 64 RX filters (8*8) */
236 (void)memset(rx_filterid_mask.FilterBitmap, 0xFF, 8);
237
238 retval = sl_WlanSet(SL_WLAN_RX_FILTERS_ID, SL_WLAN_RX_FILTER_REMOVE,
239 sizeof(SlWlanRxFilterOperationCommandBuff_t),
240 (uint8_t *)&rx_filterid_mask);
241 ASSERT_ON_ERROR(retval, WLAN_ERROR);
242
243 /* Set NWP role as STA */
244 retval = sl_WlanSetMode(ROLE_STA);
245 ASSERT_ON_ERROR(retval, WLAN_ERROR);
246
247 /* For changes to take affect, we restart the NWP */
248 retval = sl_Stop(0xFF);
249 ASSERT_ON_ERROR(retval, DEVICE_ERROR);
250
251 mode = sl_Start(0, 0, 0);
252 ASSERT_ON_ERROR(mode, DEVICE_ERROR);
253
254 if (mode != ROLE_STA) {
255 LOG_ERR("Failed to configure device to it's default state");
256 retval = -1;
257 } else {
258 nwp.role = ROLE_STA;
259 SET_STATUS_BIT(nwp.status, STATUS_BIT_NWP_INIT);
260 retval = 0;
261 }
262
263 return retval;
264 }
265
266 /**
267 * @brief SimpleLinkWlanEventHandler
268 *
269 * This handler gets called whenever a WLAN event is reported
270 * by the host driver / NWP.
271 *
272 * @note See the CC3120/CC3220 NWP programmer's guide (SWRU455)
273 * sections 4.3.4, 4.4.5 and 4.5.5.
274 */
SimpleLinkWlanEventHandler(SlWlanEvent_t * wlan_event)275 void SimpleLinkWlanEventHandler(SlWlanEvent_t *wlan_event)
276 {
277 SlWlanEventDisconnect_t *event_data = NULL;
278
279 if (!wlan_event) {
280 return;
281 }
282
283 switch (wlan_event->Id) {
284 case SL_WLAN_EVENT_CONNECT:
285 SET_STATUS_BIT(nwp.status, STATUS_BIT_CONNECTION);
286
287 /* Store new connection SSID and BSSID: */
288 memcpy(sl_conn.ssid, wlan_event->Data.Connect.SsidName,
289 wlan_event->Data.Connect.SsidLen);
290 memcpy(sl_conn.bssid, wlan_event->Data.Connect.Bssid,
291 BSSID_LEN_MAX);
292
293 LOG_INF("[WLAN EVENT] STA Connected to the AP: %s, "
294 "BSSID: %x:%x:%x:%x:%x:%x",
295 sl_conn.ssid, sl_conn.bssid[0],
296 sl_conn.bssid[1], sl_conn.bssid[2],
297 sl_conn.bssid[3], sl_conn.bssid[4],
298 sl_conn.bssid[5]);
299
300 /* Continue the notification callback chain... */
301 sl_conn.error = 0;
302 nwp.cb(SL_WLAN_EVENT_CONNECT, &sl_conn);
303 break;
304
305 case SL_WLAN_EVENT_DISCONNECT:
306 CLR_STATUS_BIT(nwp.status, STATUS_BIT_CONNECTION);
307 CLR_STATUS_BIT(nwp.status, STATUS_BIT_IP_ACQUIRED);
308 CLR_STATUS_BIT(nwp.status, STATUS_BIT_IPV6_ACQUIRED);
309
310 event_data = &wlan_event->Data.Disconnect;
311
312 /* If the user has initiated 'Disconnect' request,
313 * 'reason_code' is SL_WLAN_DISCONNECT_USER_INITIATED
314 */
315 if (SL_WLAN_DISCONNECT_USER_INITIATED ==
316 event_data->ReasonCode) {
317 LOG_INF("[WLAN EVENT] "
318 "Device disconnected from the AP: %s",
319 event_data->SsidName);
320 LOG_INF("BSSID: %x:%x:%x:%x:%x:%x on application's"
321 " request", event_data->Bssid[0],
322 event_data->Bssid[1], event_data->Bssid[2],
323 event_data->Bssid[3], event_data->Bssid[4],
324 event_data->Bssid[5]);
325 sl_conn.error = 0;
326 } else {
327 LOG_ERR("[WLAN ERROR] "
328 "Device disconnected from the AP: %s",
329 event_data->SsidName);
330 LOG_ERR("BSSID: %x:%x:%x:%x:%x:%x on error: %d",
331 event_data->Bssid[0],
332 event_data->Bssid[1], event_data->Bssid[2],
333 event_data->Bssid[3], event_data->Bssid[4],
334 event_data->Bssid[5],
335 event_data->ReasonCode);
336 sl_conn.error = event_data->ReasonCode;
337 }
338
339 (void)memset(&(sl_conn.ssid), 0x0, sizeof(sl_conn.ssid));
340 (void)memset(&(sl_conn.bssid), 0x0, sizeof(sl_conn.bssid));
341
342 /* Continue the notification callback chain... */
343 nwp.cb(SL_WLAN_EVENT_DISCONNECT, &sl_conn);
344 break;
345
346 case SL_WLAN_EVENT_STA_ADDED:
347 memcpy(&(sl_conn.bssid), wlan_event->Data.STAAdded.Mac,
348 SL_WLAN_BSSID_LENGTH);
349 LOG_INF("[WLAN EVENT] STA was added to AP: "
350 "BSSID: %x:%x:%x:%x:%x:%x",
351 sl_conn.bssid[0], sl_conn.bssid[1],
352 sl_conn.bssid[2], sl_conn.bssid[3],
353 sl_conn.bssid[4], sl_conn.bssid[5]);
354 break;
355 case SL_WLAN_EVENT_STA_REMOVED:
356 memcpy(&(sl_conn.bssid), wlan_event->Data.STAAdded.Mac,
357 SL_WLAN_BSSID_LENGTH);
358 LOG_INF("[WLAN EVENT] STA was removed from AP: "
359 "BSSID: %x:%x:%x:%x:%x:%x",
360 sl_conn.bssid[0], sl_conn.bssid[1],
361 sl_conn.bssid[2], sl_conn.bssid[3],
362 sl_conn.bssid[4], sl_conn.bssid[5]);
363
364 (void)memset(&(sl_conn.bssid), 0x0, sizeof(sl_conn.bssid));
365 break;
366 default:
367 LOG_ERR("[WLAN EVENT] Unexpected event [0x%lx]",
368 wlan_event->Id);
369 break;
370 }
371 }
372
373 /**
374 * @brief SimpleLinkNetAppEventHandler
375 *
376 * This handler gets called whenever a Netapp event is reported
377 * by the host driver / NWP.
378 *
379 * @note See the CC3120/CC3220 NWP programmer's guide (SWRU455)
380 * section 5.7.
381 */
SimpleLinkNetAppEventHandler(SlNetAppEvent_t * netapp_event)382 void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *netapp_event)
383 {
384 SlIpV4AcquiredAsync_t *event_data = NULL;
385 uint32_t i;
386
387 if (!netapp_event) {
388 return;
389 }
390
391 switch (netapp_event->Id) {
392 case SL_NETAPP_EVENT_IPV4_ACQUIRED:
393 SET_STATUS_BIT(nwp.status, STATUS_BIT_IP_ACQUIRED);
394
395 /* Ip Acquired Event Data */
396 event_data = &netapp_event->Data.IpAcquiredV4;
397 sl_conn.ip_addr = event_data->Ip;
398
399 /* Gateway IP address */
400 sl_conn.gateway_ip = event_data->Gateway;
401
402 LOG_INF("[NETAPP EVENT] IP set to: IPv4=%d.%d.%d.%d, "
403 "Gateway=%d.%d.%d.%d",
404 SL_IPV4_BYTE(sl_conn.ip_addr, 3),
405 SL_IPV4_BYTE(sl_conn.ip_addr, 2),
406 SL_IPV4_BYTE(sl_conn.ip_addr, 1),
407 SL_IPV4_BYTE(sl_conn.ip_addr, 0),
408
409 SL_IPV4_BYTE(sl_conn.gateway_ip, 3),
410 SL_IPV4_BYTE(sl_conn.gateway_ip, 2),
411 SL_IPV4_BYTE(sl_conn.gateway_ip, 1),
412 SL_IPV4_BYTE(sl_conn.gateway_ip, 0));
413
414 nwp.cb(SIMPLELINK_WIFI_CB_IPACQUIRED, &sl_conn);
415 break;
416
417 case SL_NETAPP_EVENT_IPV6_ACQUIRED:
418 SET_STATUS_BIT(nwp.status, STATUS_BIT_IPV6_ACQUIRED);
419
420 for (i = 0U; i < 4; i++) {
421 sl_conn.ipv6_addr[i] =
422 netapp_event->Data.IpAcquiredV6.Ip[i];
423 }
424
425 if (LOG_LEVEL >= LOG_LEVEL_INF) {
426 LOG_INF("[NETAPP EVENT] IP Acquired: "
427 "IPv6=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
428 ((sl_conn.ipv6_addr[0] >> 16) & 0xffff),
429 sl_conn.ipv6_addr[0] & 0xffff,
430 ((sl_conn.ipv6_addr[1] >> 16) & 0xffff),
431 sl_conn.ipv6_addr[1] & 0xffff,
432 ((sl_conn.ipv6_addr[2] >> 16) & 0xffff),
433 sl_conn.ipv6_addr[2] & 0xffff,
434 ((sl_conn.ipv6_addr[3] >> 16) & 0xffff),
435 sl_conn.ipv6_addr[3] & 0xffff);
436
437 }
438
439 nwp.cb(SIMPLELINK_WIFI_CB_IPV6ACQUIRED, &sl_conn);
440 break;
441
442 case SL_DEVICE_EVENT_DROPPED_NETAPP_IP_LEASED:
443 SET_STATUS_BIT(nwp.status, STATUS_BIT_IP_LEASED);
444 SET_STATUS_BIT(nwp.status, STATUS_BIT_IP_ACQUIRED);
445
446 sl_conn.sta_ip = netapp_event->Data.IpLeased.IpAddress;
447 LOG_INF("[NETAPP EVENT] IP Leased to Client: "
448 "IP=%d.%d.%d.%d",
449 SL_IPV4_BYTE(sl_conn.sta_ip, 3),
450 SL_IPV4_BYTE(sl_conn.sta_ip, 2),
451 SL_IPV4_BYTE(sl_conn.sta_ip, 1),
452 SL_IPV4_BYTE(sl_conn.sta_ip, 0));
453
454 break;
455
456 case SL_DEVICE_EVENT_DROPPED_NETAPP_IP_RELEASED:
457 LOG_INF("[NETAPP EVENT] IP is released.");
458 break;
459
460 default:
461 LOG_ERR("[NETAPP EVENT] Unexpected event [0x%lx]",
462 netapp_event->Id);
463 break;
464 }
465
466 if ((netapp_event->Id == SL_NETAPP_EVENT_IPV4_ACQUIRED) ||
467 (netapp_event->Id == SL_NETAPP_EVENT_IPV6_ACQUIRED)) {
468 /* Initialize SlNetSock layer for getaddrinfo */
469 SlNetIf_init(0);
470 /*
471 * We are only using SlNetSock to support getaddrinfo()
472 * for the WiFi interface, so hardcoding the interface
473 * id to 1 here.
474 */
475 SlNetIf_add(SLNETIF_ID_1, SLNET_IF_WIFI_NAME,
476 (const SlNetIf_Config_t *)&slnetifwifi_config_zephyr,
477 SLNET_IF_WIFI_PRIO);
478
479 SlNetSock_init(0);
480 SlNetUtil_init(0);
481 }
482 }
483
484 /**
485 * @brief SimpleLinkGeneralEventHandler
486 *
487 * This handler gets called whenever a general error is reported
488 * by the NWP / Host driver. Since these errors are not fatal,
489 * the application can handle them.
490 *
491 * @note See the CC3120/CC3220 NWP programmer's guide (SWRU455)
492 * section 17.9.
493 */
SimpleLinkGeneralEventHandler(SlDeviceEvent_t * dev_event)494 void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *dev_event)
495 {
496 if (!dev_event) {
497 return;
498 }
499
500 LOG_INF("[GENERAL EVENT] - ID=[%d] Sender=[%d]",
501 dev_event->Data.Error.Code,
502 dev_event->Data.Error.Source);
503 }
504
505 /**
506 * @brief SimpleLinkFatalErrorEventHandler
507 *
508 * This handler gets called whenever a driver error occurs requiring
509 * restart of the device in order to recover.
510 */
SimpleLinkFatalErrorEventHandler(SlDeviceFatal_t * fatal_err_event)511 void SimpleLinkFatalErrorEventHandler(SlDeviceFatal_t *fatal_err_event)
512 {
513
514 switch (fatal_err_event->Id) {
515 case SL_DEVICE_EVENT_FATAL_DEVICE_ABORT:
516 LOG_ERR("[ERROR] - FATAL ERROR: "
517 "Abort NWP event detected: "
518 "AbortType=%ld, AbortData=0x%lx",
519 fatal_err_event->Data.DeviceAssert.Code,
520 fatal_err_event->Data.DeviceAssert.Value);
521 break;
522
523 case SL_DEVICE_EVENT_FATAL_DRIVER_ABORT:
524 LOG_ERR("[ERROR] - FATAL ERROR: Driver Abort detected.");
525 break;
526
527 case SL_DEVICE_EVENT_FATAL_NO_CMD_ACK:
528 LOG_ERR("[ERROR] - FATAL ERROR: No Cmd Ack detected "
529 "[cmd opcode = 0x%lx]",
530 fatal_err_event->Data.NoCmdAck.Code);
531 break;
532
533 case SL_DEVICE_EVENT_FATAL_SYNC_LOSS:
534 LOG_ERR("[ERROR] - FATAL ERROR: Sync loss detected");
535 break;
536
537 case SL_DEVICE_EVENT_FATAL_CMD_TIMEOUT:
538 LOG_ERR("[ERROR] - FATAL ERROR: "
539 "Async event timeout detected "
540 "[event opcode =0x%lx]",
541 fatal_err_event->Data.CmdTimeout.Code);
542 break;
543
544 default:
545 LOG_ERR("[ERROR] - FATAL ERROR: "
546 "Unspecified error detected");
547 break;
548 }
549 }
550
551 /* Unused, but must be defined to link. */
SimpleLinkSockEventHandler(SlSockEvent_t * psock)552 void SimpleLinkSockEventHandler(SlSockEvent_t *psock)
553 {
554 ARG_UNUSED(psock);
555 }
556
557 /* Unused, but must be defined to link. */
SimpleLinkHttpServerEventHandler(SlNetAppHttpServerEvent_t * http_event,SlNetAppHttpServerResponse_t * http_resp)558 void SimpleLinkHttpServerEventHandler(SlNetAppHttpServerEvent_t *http_event,
559 SlNetAppHttpServerResponse_t *http_resp)
560 {
561 ARG_UNUSED(http_event);
562 ARG_UNUSED(http_resp);
563 }
564
565
566 /* Unused, but must be defined to link. */
SimpleLinkNetAppRequestEventHandler(SlNetAppRequest_t * netapp_request,SlNetAppResponse_t * netapp_response)567 void SimpleLinkNetAppRequestEventHandler(SlNetAppRequest_t *netapp_request,
568 SlNetAppResponse_t *netapp_response)
569 {
570 ARG_UNUSED(netapp_request);
571 ARG_UNUSED(netapp_response);
572 }
573
574 /* Unused, but must be defined to link. */
SimpleLinkNetAppRequestMemFreeEventHandler(uint8_t * buffer)575 void SimpleLinkNetAppRequestMemFreeEventHandler(uint8_t *buffer)
576 {
577 ARG_UNUSED(buffer);
578 }
579
580 /* Note: SimpleLink WiFi scan also can return the following:
581 * - BSSID
582 * - Whether network hidden or visible
583 * - Other types of security
584 */
z_simplelink_get_scan_result(int index,struct wifi_scan_result * scan_result)585 void z_simplelink_get_scan_result(int index,
586 struct wifi_scan_result *scan_result)
587 {
588 SlWlanNetworkEntry_t *net_entry;
589 int sec_bmp;
590
591 __ASSERT_NO_MSG(index <= CONFIG_WIFI_SIMPLELINK_SCAN_COUNT);
592 net_entry = &nwp.net_entries[index];
593
594 (void)memset(scan_result, 0x0, sizeof(struct wifi_scan_result));
595
596 __ASSERT_NO_MSG(net_entry->SsidLen <= WIFI_SSID_MAX_LEN);
597 memcpy(scan_result->ssid, net_entry->Ssid, net_entry->SsidLen);
598 scan_result->ssid_length = net_entry->SsidLen;
599 scan_result->channel = net_entry->Channel;
600
601 /* Parse security bitmap: */
602 sec_bmp = net_entry->SecurityInfo;
603 if (SL_WLAN_SCAN_RESULT_SEC_TYPE_BITMAP(sec_bmp) & 0x6) {
604 scan_result->security = WIFI_SECURITY_TYPE_PSK;
605 } else {
606 scan_result->security = WIFI_SECURITY_TYPE_NONE;
607 }
608
609 scan_result->rssi = net_entry->Rssi;
610 }
611
z_simplelink_start_scan(void)612 int z_simplelink_start_scan(void)
613 {
614 int32_t ret;
615
616 /* Clear the results buffer */
617 (void)memset(&nwp.net_entries, 0x0, sizeof(nwp.net_entries));
618
619 /* Attempt to get scan results from NWP
620 * Note: If scan policy isn't set, invoking 'sl_WlanGetNetworkList()'
621 * for the first time triggers 'one shot' scan.
622 */
623 ret = sl_WlanGetNetworkList(0, CONFIG_WIFI_SIMPLELINK_SCAN_COUNT,
624 &nwp.net_entries[0]);
625 LOG_DBG("sl_WlanGetNetworkList: %d", ret);
626
627 return ret;
628 }
629
z_simplelink_get_mac(unsigned char * mac)630 void z_simplelink_get_mac(unsigned char *mac)
631 {
632 uint16_t mac_len = SL_MAC_ADDR_LEN;
633 uint16_t config_opt = 0U;
634
635 sl_NetCfgGet(SL_NETCFG_MAC_ADDRESS_GET, &config_opt,
636 &mac_len, (uint8_t *)mac);
637 }
638
z_simplelink_connect(struct wifi_connect_req_params * params)639 int z_simplelink_connect(struct wifi_connect_req_params *params)
640 {
641 SlWlanSecParams_t secParams = { 0 };
642 long lretval;
643
644 if (params->security == WIFI_SECURITY_TYPE_PSK) {
645 secParams.Key = (signed char *)params->psk;
646 secParams.KeyLen = params->psk_length;
647 /* This is only mapping handled for now: */
648 secParams.Type = SL_WLAN_SEC_TYPE_WPA_WPA2;
649 } else {
650 secParams.Key = (signed char *)NULL;
651 secParams.KeyLen = 0;
652 secParams.Type = SL_WLAN_SEC_TYPE_OPEN;
653 }
654
655 lretval = sl_WlanConnect((signed char *)params->ssid,
656 params->ssid_length, 0, &secParams, 0);
657 LOG_DBG("sl_WlanConnect: %ld", lretval);
658
659 return lretval;
660 }
661
z_simplelink_disconnect(void)662 int z_simplelink_disconnect(void)
663 {
664 long lretval;
665
666 lretval = sl_WlanDisconnect();
667 LOG_DBG("sl_WlanDisconnect: %ld", lretval);
668
669 return lretval;
670 }
671
z_simplelink_init(simplelink_wifi_cb_t wifi_cb)672 int z_simplelink_init(simplelink_wifi_cb_t wifi_cb)
673 {
674 int retval;
675
676 __ASSERT(wifi_cb, "callback must be supplied");
677
678 /* Init the board: */
679 CC3220SF_LAUNCHXL_init();
680
681 /* Configure SimpleLink NWP: */
682 nwp.status = 0U;
683 nwp.role = ROLE_RESERVED;
684 nwp.cb = wifi_cb;
685
686 (void)memset(&sl_conn, 0x0, sizeof(sl_conn));
687
688 retval = configure_simplelink();
689 __ASSERT(retval >= 0, "Unable to configure SimpleLink");
690
691 return retval;
692 }
693