]> begriffs open source - cmsis-driver-validation/blob - Source/DV_WIFI.c
Improved robustness of SPI testing and SPI Server
[cmsis-driver-validation] / Source / DV_WIFI.c
1 /*
2  * Copyright (c) 2015-2020 Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * -----------------------------------------------------------------------------
19  *
20  * Project:     CMSIS-Driver Validation
21  * Title:       WiFi Driver Validation tests
22  *
23  * -----------------------------------------------------------------------------
24  */
25
26 /*
27   Known limitations:
28   - Bypass mode and functionality is not tested
29   - Set/GetOption API does not test IPv6 options
30   - SetOption operation is not tested, only API is tested
31     (BSSID, MAC, static IP operation testing would require dedicated hardware
32      with manual check of results on dedicated hardware)
33   - WPS operation is not tested (not Station nor AP)
34     (WPS functional testing would require dedicated hardware
35      with manual check of results WPS AP, WPS on Station could
36      be checked by comparing parameters with expected result (configured))
37   - WiFi sockets tested in blocking mode only
38   - WiFi sockets not tested for IPv6
39 */
40
41 #include "cmsis_dv.h"
42 #include "DV_WiFi_Config.h"
43 #include "DV_Framework.h"
44 #include "Driver_WiFi.h"
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48
49 /* Service ports */
50 #define ECHO_PORT               7               // Echo port number
51 #define DISCARD_PORT            9               // Discard port number
52 #define CHARGEN_PORT            19              // Chargen port number
53 #define ASSISTANT_PORT          5000            // Test Assistant port number
54 #define TCP_REJECTED_PORT       5001            // Rejected connection server TCP port
55 #define TCP_TIMEOUT_PORT        5002            // Non-responding server TCP port
56
57 /* Helper function identifiers */
58 #define F_CREATE                0x00000001
59 #define F_CREATE_TCP            F_CREATE        // Never used with CREATE
60 #define F_CREATE_UDP            0x00000002
61 #define F_CLOSE                 0x00000004
62 #define F_BIND                  0x00000008
63 #define F_LISTEN                0x00000010
64 #define F_ACCEPT                0x00000020
65 #define F_CONNECT               0x00000040
66 #define F_RECV                  0x00000080
67 #define F_RECVFROM              0x00000100
68 #define F_SEND                  0x00000200
69 #define F_SENDTO                0x00000400
70 #define F_GETSOCKNAME           0x00000800
71 #define F_GETPEERNAME           0x00001000
72 #define F_GETOPT                0x00002000
73 #define F_SETOPT                0x00004000
74 #define F_GETHOSTBYNAME         0x00008000
75 #define F_PING                  0x00010000
76 #define F_SEND_CTRL             F_PING          // Never used with PING
77 #define F_XFER_FIXED            0x00020000
78 #define F_XFER_INCR             0x00040000
79 #define F_SEND_FRAG             0x00080000
80 #define F_UPLOAD                F_SEND_FRAG     // Never used with SEND_FRAG
81 #define F_RECV_FRAG             0x00100000
82 #define F_DOWNLOAD              F_RECV_FRAG     // Never used with RECV_FRAG
83 #define F_ALL                   0x001FFFFF
84
85 #define SK_TERMINATE            0x00000001
86
87 /* Helper function return values */
88 #define TH_OK                   0x01
89 #define TH_TOUT                 0x02
90 #define TH_ALL                  0x03
91
92 /* Register Driver_WiFi# */
93 extern ARM_DRIVER_WIFI         ARM_Driver_WiFi_(DRV_WIFI);
94 static ARM_DRIVER_WIFI* drv = &ARM_Driver_WiFi_(DRV_WIFI);
95
96 /* Local variables */
97 static uint8_t                  powered   = 0U;
98 static uint8_t                  connected = 0U;
99 static uint8_t                  socket_funcs_exist = 0U;
100 static uint8_t volatile         event;
101
102 static char                     msg_buf [128];
103 static char                     data_buf[128] __ALIGNED(4);
104
105 static ARM_WIFI_SignalEvent_t   event_func;
106 static ARM_WIFI_CAPABILITIES    cap;
107 static ARM_WIFI_CONFIG_t        config;
108 static ARM_WIFI_NET_INFO_t      net_info;
109 static ARM_WIFI_SCAN_INFO_t     scan_info[WIFI_SCAN_MAX_NUM];
110
111 static const uint8_t            ip_unspec[4] = {   0,   0,   0,   0 };
112 static const uint8_t            ip_bcast[4]  = { 255, 255, 255, 255 };
113 static       uint8_t            ip_socket_server[4];
114
115 /* String representation of Driver return codes */
116 static const char *str_ret[] = {
117   "ARM_DRIVER_OK",
118   "ARM_DRIVER_ERROR",
119   "ARM_DRIVER_ERROR_BUSY",
120   "ARM_DRIVER_ERROR_TIMEOUT",
121   "ARM_DRIVER_ERROR_UNSUPPORTED",
122   "ARM_DRIVER_ERROR_PARAMETER",
123   "ARM_DRIVER_ERROR_SPECIFIC"
124 };
125
126 /* String representation of Driver Socket fucntion's return codes */
127 static const char *str_sock_ret[] = {
128  "OK",
129  "ARM_SOCKET_ERROR",
130  "ARM_SOCKET_ESOCK",
131  "ARM_SOCKET_EINVAL",
132  "ARM_SOCKET_ENOTSUP",
133  "ARM_SOCKET_ENOMEM",
134  "ARM_SOCKET_EAGAIN",
135  "ARM_SOCKET_EINPROGRESS",
136  "ARM_SOCKET_ETIMEDOUT",
137  "ARM_SOCKET_EISCONN",
138  "ARM_SOCKET_ENOTCONN",
139  "ARM_SOCKET_ECONNREFUSED",
140  "ARM_SOCKET_ECONNRESET",
141  "ARM_SOCKET_ECONNABORTED",
142  "ARM_SOCKET_EALREADY",
143  "ARM_SOCKET_EADDRINUSE",
144  "ARM_SOCKET_EHOSTNOTFOUND"
145 };
146
147 /* Test message containing all letters of the alphabet */
148 static const uint8_t test_msg[44] = {
149   "The quick brown fox jumps over the lazy dog."
150 };
151 /* Dummy text with normal distribution of letters */
152 static const uint8_t test_buf[2050] = {
153   "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent "
154   "libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum "
155   "imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper "
156   "porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu "
157   "ad litora torquent per conubia nostra, per inceptos himenaeos."
158
159   "Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. "
160   "Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed "
161   "convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus "
162   "risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula "
163   "lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, "
164   "euismod in, nibh."
165
166   "Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent "
167   "per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non "
168   "tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. "
169   "Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat "
170   "imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu "
171   "magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna."
172
173   "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna "
174   "augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices "
175   "posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non "
176   "quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis "
177   "laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum "
178   "tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. "
179   "Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin "
180   "massa. Cras metus."
181
182   "Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis "
183   "tristique, dignissim in, ultrices sit amet augue."
184 };
185 static uint8_t buffer[2048];
186
187 /* WiFi event */
188 static void WIFI_DrvEvent (uint32_t evt, void *arg) {
189   (void)arg;
190
191   event |= evt;
192 }
193
194
195 /*-----------------------------------------------------------------------------
196  *      Tests
197  *----------------------------------------------------------------------------*/
198
199 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
200 /**
201 \defgroup dv_wifi WiFi Validation
202 \brief WiFi driver validation
203 \details
204 The WiFi validation test performs the following tests:
205 - API interface compliance.
206 - Some of the control and management operations.
207 - Socket operation with various transfer sizes and communication parameters.
208 - Socket performance.
209
210 \defgroup wifi_tests Tests
211 \ingroup dv_wifi
212 */
213
214 /* Helper function that initializes and powers on WiFi Module if not initialized and powered */
215 static int32_t init_and_power_on (void) {
216
217   if (powered == 0U) {
218     if ((drv->Initialize   (event_func)     == ARM_DRIVER_OK) && 
219         (drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK)) {
220       powered = 1U;
221     } else {
222       return 0;
223     }
224   }
225
226   return 1;
227 }
228
229 /* Helper function that is called before tests start executing */
230 void WIFI_DV_Initialize (void) {
231
232   sscanf(WIFI_SOCKET_SERVER_IP, "%hhu.%hhu.%hhu.%hhu", &ip_socket_server[0], &ip_socket_server[1], &ip_socket_server[2], &ip_socket_server[3]);
233
234   cap = drv->GetCapabilities();
235
236   event_func = NULL;
237   if ((cap.event_eth_rx_frame   != 0U) ||
238       (cap.event_ap_connect     != 0U) ||
239       (cap.event_ap_disconnect  != 0U)) {
240     event_func = WIFI_DrvEvent;
241   }
242
243   if ((drv->SocketCreate        != NULL) &&
244       (drv->SocketBind          != NULL) &&
245       (drv->SocketListen        != NULL) &&
246       (drv->SocketAccept        != NULL) &&
247       (drv->SocketConnect       != NULL) &&
248       (drv->SocketRecv          != NULL) &&
249       (drv->SocketRecvFrom      != NULL) &&
250       (drv->SocketSend          != NULL) &&
251       (drv->SocketSendTo        != NULL) &&
252       (drv->SocketGetSockName   != NULL) &&
253       (drv->SocketGetPeerName   != NULL) &&
254       (drv->SocketGetOpt        != NULL) &&
255       (drv->SocketSetOpt        != NULL) &&
256       (drv->SocketClose         != NULL) &&
257       (drv->SocketGetHostByName != NULL)) {
258     socket_funcs_exist = 1U;
259   }
260 }
261
262 /* Helper function that is called after tests stop executing */
263 void WIFI_DV_Uninitialize (void) {
264
265   if (connected != 0U) {
266     if (drv->Deactivate (0U) == ARM_DRIVER_OK) {
267       connected = 0U;
268     }
269   }
270   if (powered != 0U) {
271     if ((drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK) && 
272         (drv->Uninitialize ()              == ARM_DRIVER_OK)) {
273       powered = 0U;
274     }
275   }
276 }
277
278 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
279 /* WiFi Control tests */
280 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
281 /**
282 \defgroup wifi_ctrl Control
283 \ingroup wifi_tests
284 \details
285 These tests verify API and operation of the WiFi control functions.
286 @{
287 */
288
289 /**
290 \brief Function: WIFI_GetVersion
291 \details
292 The test function \b WIFI_GetVersion verifies the WiFi Driver \b GetVersion function.
293 \code
294 ARM_DRIVER_VERSION (*GetVersion) (void);
295 \endcode
296 */
297 void WIFI_GetVersion (void) {
298   ARM_DRIVER_VERSION ver;
299
300   ver = drv->GetVersion();
301
302   TEST_ASSERT((ver.api >= ARM_DRIVER_VERSION_MAJOR_MINOR(1,0)) && (ver.drv >= ARM_DRIVER_VERSION_MAJOR_MINOR(1,0)));
303
304   snprintf(msg_buf, sizeof(msg_buf), "[INFO] Driver API version %d.%d, Driver version %d.%d", (ver.api >> 8), (ver.api & 0xFFU), (ver.drv >> 8), (ver.drv & 0xFFU));
305   TEST_MESSAGE(msg_buf);
306 }
307
308 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
309 /**
310 \brief Function: WIFI_GetCapabilities
311 \details
312 The test function \b WIFI_GetCapabilities verifies the WiFi Driver \b GetCapabilities function.
313 \code
314 ARM_WIFI_CAPABILITIES (*GetCapabilities) (void);
315 \endcode
316 */
317 void WIFI_GetCapabilities (void) {
318
319   cap = drv->GetCapabilities();
320
321   TEST_ASSERT_MESSAGE((cap.station_ap != 0U) || (cap.station != 0U) || (cap.ap != 0U), "At least 1 mode must be supported");
322
323   if (cap.wps_station != 0U) {
324     TEST_ASSERT_MESSAGE((cap.station_ap != 0U) || (cap.station != 0U), "If WPS for station is supported version of station mode of operation must be supported also");
325   }
326
327   if (cap.wps_ap != 0U) {
328     TEST_ASSERT_MESSAGE((cap.station_ap != 0U) || (cap.ap != 0U), "If WPS for AP is supported version of AP mode of operation must be supported also");
329   }
330
331   if ((cap.event_ap_connect != 0U) || (cap.event_ap_disconnect != 0U)) {
332     TEST_ASSERT_MESSAGE((cap.station_ap != 0U) || (cap.ap != 0U), "If events for AP are supported version of AP mode of operation must be supported also");
333   }
334
335   if (cap.event_eth_rx_frame != 0U) {
336     TEST_ASSERT_MESSAGE(cap.bypass_mode != 0U, "If event for Ethernet Rx frame is supported, bypass mode must be supported also");
337   }
338 }
339
340 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
341 /**
342 \brief Function: WIFI_Initialize/Uninitialize
343 \details
344 The test function \b WIFI_Initialize_Uninitialize verifies the WiFi Driver \b Initialize and \b Uninitialize functions.
345 \code
346 int32_t (*Initialize) (ARM_WIFI_SignalEvent_t cb_event);
347 \endcode
348 and
349 \code
350 int32_t (*Uninitialize) (void);
351 \endcode
352 Testing sequence:
353  - Initialize without callback
354  - Uninitialize
355  - Initialize with callback (if driver supports it)
356  - Power on
357  - Uninitialize
358  - Initialize without callback
359  - Power on
360  - Power off
361  - Uninitialize
362 */
363 void WIFI_Initialize_Uninitialize (void) {
364   int32_t ret;
365
366   if ((cap.event_eth_rx_frame  != 0U) ||
367       (cap.event_ap_connect    != 0U) ||
368       (cap.event_ap_disconnect != 0U)) {
369     event_func = WIFI_DrvEvent;
370   }
371
372   TEST_ASSERT(drv->Initialize   (NULL)           == ARM_DRIVER_OK);
373   TEST_ASSERT(drv->Uninitialize ()               == ARM_DRIVER_OK);
374   TEST_ASSERT(drv->Initialize   (event_func)     == ARM_DRIVER_OK);
375   TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
376   TEST_ASSERT(drv->Uninitialize ()               == ARM_DRIVER_OK);
377   TEST_ASSERT(drv->Initialize   (NULL)           == ARM_DRIVER_OK);
378   TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
379   ret =       drv->PowerControl (ARM_POWER_OFF);
380   TEST_ASSERT((ret == ARM_DRIVER_OK) || (ret == ARM_DRIVER_ERROR_UNSUPPORTED));
381   TEST_ASSERT(drv->Uninitialize ()               == ARM_DRIVER_OK);
382 }
383
384 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
385 /**
386 \brief Function: WIFI_PowerControl
387 \details
388 The test function \b WIFI_PowerControl verifies the WiFi Driver \b PowerControl function.
389 \code
390 int32_t (*PowerControl) (ARM_POWER_STATE state);
391 \endcode
392 Testing sequence:
393  - Power off
394  - Initialize with callback (if driver supports it)
395  - Power off
396  - Power on
397  - Scan
398  - Power low
399  - Power off
400  - Uninitialize
401 */
402 void WIFI_PowerControl (void) {
403   int32_t ret;
404
405   ret =       drv->PowerControl (ARM_POWER_OFF);
406   TEST_ASSERT(ret == ARM_DRIVER_ERROR);
407   TEST_ASSERT(drv->Initialize   (event_func)     == ARM_DRIVER_OK);
408   ret =       drv->PowerControl (ARM_POWER_OFF);
409   if (ret == ARM_DRIVER_ERROR_UNSUPPORTED) {
410     TEST_MESSAGE("[WARNING] PowerControl (ARM_POWER_OFF) not supported");
411   } else {
412     TEST_ASSERT(ret == ARM_DRIVER_OK);
413   }
414   TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
415   TEST_ASSERT(drv->Scan         (scan_info, WIFI_SCAN_MAX_NUM) >= 0);
416
417   /* Test low power */
418   ret = drv->PowerControl (ARM_POWER_LOW);
419   switch (ret) {
420     case ARM_DRIVER_OK:
421       break;
422
423     case ARM_DRIVER_ERROR_UNSUPPORTED:
424       TEST_MESSAGE("[WARNING] PowerControl (ARM_POWER_LOW) is not supported");
425       break;
426
427     default:
428       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] PowerControl (ARM_POWER_LOW) returned %s", str_ret[-ret]);
429       TEST_MESSAGE(msg_buf);
430       break;
431   }
432
433   drv->PowerControl (ARM_POWER_OFF);
434   drv->Uninitialize ();
435 }
436
437 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
438 /**
439 \brief Function: WIFI_GetModuleInfo
440 \details
441 The test function \b WIFI_GetModuleInfo verifies the WiFi Driver \b GetModuleInfo function.
442 \code
443 int32_t (*GetModuleInfo) (char *module_info, uint32_t max_len);
444 \endcode
445 */
446 void WIFI_GetModuleInfo (void) {
447   int32_t ret;
448
449   if (init_and_power_on () == 0) {
450     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
451     return;
452   }
453
454   ret = drv->GetModuleInfo(NULL, sizeof(data_buf));
455   if (ret == ARM_DRIVER_ERROR_UNSUPPORTED) {
456     TEST_MESSAGE("[WARNING] GetModuleInfo (...) not supported");
457   } else {
458     TEST_ASSERT(ret == ARM_DRIVER_ERROR_PARAMETER);
459   }
460   ret = drv->GetModuleInfo(data_buf, 0U);
461   if (ret == ARM_DRIVER_ERROR_UNSUPPORTED) {
462     TEST_MESSAGE("[WARNING] GetModuleInfo (...) not supported");
463   } else {
464     TEST_ASSERT(ret == ARM_DRIVER_ERROR_PARAMETER);
465   }
466
467   memset((void *)data_buf, 0xCC, sizeof(data_buf));
468   ret = drv->GetModuleInfo(data_buf, sizeof(data_buf));
469   switch (ret) {
470     case ARM_DRIVER_OK:
471       TEST_ASSERT(strlen(data_buf) != 0);
472       snprintf(msg_buf, sizeof(msg_buf), "[INFO] Module Info is %s", data_buf);
473       TEST_MESSAGE(msg_buf);
474       break;
475     case ARM_DRIVER_ERROR_UNSUPPORTED:
476       TEST_MESSAGE("[WARNING] GetModuleInfo () is not supported");
477       break;
478     default:
479       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] GetModuleInfo () returned %s", str_ret[-ret]);
480       TEST_MESSAGE(msg_buf);
481       break;
482   }
483 }
484 /**
485 @}
486 */
487 // End of wifi_ctrl
488
489 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
490 /* WiFi Management tests */
491 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
492 /**
493 \defgroup wifi_mgmt Management
494 \ingroup wifi_tests
495 \details
496 These tests verify API and operation of the WiFi management functions.
497 @{
498 */
499
500 #if (WIFI_SETGETOPTION_BSSID_EN != 0)
501 static void WIFI_SetOption_GetOption_BSSID (void) {
502 #if ((WIFI_SETGETOPTION_BSSID_EN & 1) != 0)
503   uint8_t  u8_arr[8] __ALIGNED(4);
504   uint8_t  bssid[7]  __ALIGNED(4);
505 #endif
506 #if ((WIFI_SETGETOPTION_BSSID_EN & 2) != 0)
507   uint32_t len;
508 #endif
509   uint8_t  not_suported;
510
511   not_suported = 0U;
512
513   if (init_and_power_on () == 0) {
514     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
515     return;
516   }
517
518 #if ((WIFI_SETGETOPTION_BSSID_EN & 1) != 0)
519   // Set tests
520   memset((void *)bssid, 0x11, 7);
521   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_BSSID, bssid, 6U) == ARM_DRIVER_ERROR_PARAMETER);
522   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_BSSID, bssid, 6U) == ARM_DRIVER_ERROR_PARAMETER);
523
524   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
525     TEST_ASSERT(sscanf((const char *)WIFI_BSSID_STA, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &bssid[0], &bssid[1], &bssid[2], &bssid[3], &bssid[4], &bssid[5]) == 6);
526     memset((void *) u8_arr, 0xCC, 8);
527     memcpy((void *)&u8_arr[1], (const void *)bssid, 6);
528     if (drv->SetOption (0U, ARM_WIFI_BSSID, bssid, 6U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
529       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_BSSID, NULL,       0U) == ARM_DRIVER_ERROR_PARAMETER);
530       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_BSSID, NULL,       6U) == ARM_DRIVER_ERROR_PARAMETER);
531       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_BSSID, bssid,      0U) == ARM_DRIVER_ERROR_PARAMETER);
532       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_BSSID, bssid,      5U) == ARM_DRIVER_ERROR_PARAMETER);
533       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_BSSID, &u8_arr[1], 6U) == ARM_DRIVER_OK);
534       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_BSSID, &u8_arr[1], 7U) == ARM_DRIVER_OK);
535       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_BSSID, bssid,      7U) == ARM_DRIVER_OK);
536       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_BSSID, bssid,      6U) == ARM_DRIVER_OK);
537     } else {
538       not_suported |= 1U;
539       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_BSSID for Station is not supported");
540     }
541   }
542   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
543     TEST_ASSERT(sscanf((const char *)WIFI_BSSID_AP, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &bssid[0], &bssid[1], &bssid[2], &bssid[3], &bssid[4], &bssid[5]) == 6);
544     memset((void *) u8_arr, 0xCC, 8);
545     memcpy((void *)&u8_arr[1], (const void *)bssid, 6);
546     if (drv->SetOption (1U, ARM_WIFI_BSSID, bssid, 6U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
547       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BSSID, NULL,       0U) == ARM_DRIVER_ERROR_PARAMETER);
548       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BSSID, NULL,       6U) == ARM_DRIVER_ERROR_PARAMETER);
549       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BSSID, bssid,      0U) == ARM_DRIVER_ERROR_PARAMETER);
550       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BSSID, bssid,      5U) == ARM_DRIVER_ERROR_PARAMETER);
551       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BSSID, &u8_arr[1], 6U) == ARM_DRIVER_OK);
552       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BSSID, &u8_arr[1], 7U) == ARM_DRIVER_OK);
553       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BSSID, bssid,      7U) == ARM_DRIVER_OK);
554       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BSSID, bssid,      6U) == ARM_DRIVER_OK);
555     } else {
556       not_suported |= 2U;
557       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_BSSID for Access Point is not supported");
558     }
559   }
560 #endif
561
562 #if ((WIFI_SETGETOPTION_BSSID_EN & 2) != 0)
563   // Get tests
564   len = 6U;
565   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_BSSID, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
566   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_BSSID, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
567
568   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
569     len = 6U;
570     if (drv->GetOption (0U, ARM_WIFI_BSSID, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
571       len = 0U;
572       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_BSSID, NULL,      &len) == ARM_DRIVER_ERROR_PARAMETER);
573       len = 6U;
574       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_BSSID, NULL,      &len) == ARM_DRIVER_ERROR_PARAMETER);
575       len = 0U;
576       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_BSSID, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
577       len = 5U;
578       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_BSSID, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
579       len = 6U;
580       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_BSSID, data_buf+1,&len) == ARM_DRIVER_OK);
581       len = 7U;
582       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_BSSID, data_buf+1,&len) == ARM_DRIVER_OK);
583       len = 7U;
584       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_BSSID, data_buf,  &len) == ARM_DRIVER_OK);
585       len = 6U;
586       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_BSSID, data_buf,  &len) == ARM_DRIVER_OK);
587     } else {
588       not_suported |= 1U;
589       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_BSSID for Station is not supported");
590     }
591   }
592   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
593     len = 6U;
594     if (drv->GetOption (1U, ARM_WIFI_BSSID, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
595       len = 0U;
596       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BSSID, NULL,      &len) == ARM_DRIVER_ERROR_PARAMETER);
597       len = 6U;
598       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BSSID, NULL,      &len) == ARM_DRIVER_ERROR_PARAMETER);
599       len = 0U;
600       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BSSID, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
601       len = 5U;
602       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BSSID, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
603       len = 6U;
604       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BSSID, data_buf+1,&len) == ARM_DRIVER_OK);
605       len = 7U;
606       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BSSID, data_buf+1,&len) == ARM_DRIVER_OK);
607       len = 7U;
608       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BSSID, data_buf,  &len) == ARM_DRIVER_OK);
609       len = 6U;
610       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BSSID, data_buf,  &len) == ARM_DRIVER_OK);
611     } else {
612       not_suported |= 2U;
613       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_BSSID for Access Point is not supported");
614     }
615   }
616 #endif
617
618 #if ((WIFI_SETGETOPTION_BSSID_EN & 3) == 3)
619   // Check with Get that Set has written the correct values
620   if (((cap.station_ap != 0) || (cap.station != 0)) && ((not_suported & 1U) == 0U)) {   // Station test
621     TEST_ASSERT(sscanf((const char *)WIFI_BSSID_STA, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &bssid[0], &bssid[1], &bssid[2], &bssid[3], &bssid[4], &bssid[5]) == 6);
622     memset((void *)data_buf, 0xCC, sizeof(data_buf));
623     len = 6U;
624     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_BSSID, bssid,    6U)   == ARM_DRIVER_OK);
625     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_BSSID, data_buf, &len) == ARM_DRIVER_OK);
626     TEST_ASSERT(len == 6U);
627     TEST_ASSERT(memcmp((const void *)bssid, (const void *)data_buf, (size_t)len) == 0);
628   }
629   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
630     TEST_ASSERT(sscanf((const char *)WIFI_BSSID_AP, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &bssid[0], &bssid[1], &bssid[2], &bssid[3], &bssid[4], &bssid[5]) == 6);
631     memset((void *)data_buf, 0xCC, sizeof(data_buf));
632     len = 6U;
633     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BSSID, bssid,    6U)   == ARM_DRIVER_OK);
634     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BSSID, data_buf, &len) == ARM_DRIVER_OK);
635     TEST_ASSERT(len == 6U);
636     TEST_ASSERT(memcmp((const void *)bssid, (const void *)data_buf, (size_t)len) == 0);
637   }
638 #endif
639 }
640 #endif
641
642 #if (WIFI_SETGETOPTION_TX_POWER_EN != 0)
643 static void WIFI_SetOption_GetOption_TX_POWER (void) {
644 #if ((WIFI_SETGETOPTION_TX_POWER_EN & 1) != 0)
645   uint32_t power;
646 #endif
647 #if ((WIFI_SETGETOPTION_TX_POWER_EN & 2) != 0)
648   uint32_t len;
649 #endif
650   uint8_t  not_suported;
651
652   not_suported = 0U;
653
654   if (init_and_power_on () == 0) {
655     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
656     return;
657   }
658
659 #if ((WIFI_SETGETOPTION_TX_POWER_EN & 1) != 0)
660   // Set tests
661   power = WIFI_TX_POWER_STA;
662   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_TX_POWER, &power, 4U) == ARM_DRIVER_ERROR_PARAMETER);
663   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_TX_POWER, &power, 4U) == ARM_DRIVER_ERROR_PARAMETER);
664
665   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
666     power = WIFI_TX_POWER_STA;
667     if (drv->SetOption (0U, ARM_WIFI_TX_POWER, &power, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
668       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_TX_POWER, NULL,   0U) == ARM_DRIVER_ERROR_PARAMETER);
669       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_TX_POWER, NULL,   4U) == ARM_DRIVER_ERROR_PARAMETER);
670       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_TX_POWER, &power, 0U) == ARM_DRIVER_ERROR_PARAMETER);
671       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_TX_POWER, &power, 3U) == ARM_DRIVER_ERROR_PARAMETER);
672       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_TX_POWER, &power, 5U) == ARM_DRIVER_OK);
673       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_TX_POWER, &power, 4U) == ARM_DRIVER_OK);
674     } else {
675       not_suported |= 1U;
676       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_TX_POWER for Station is not supported");
677     }
678   }
679   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
680     power = WIFI_TX_POWER_AP;
681     if (drv->SetOption (1U, ARM_WIFI_TX_POWER, &power, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
682       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_TX_POWER, NULL,   0U) == ARM_DRIVER_ERROR_PARAMETER);
683       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_TX_POWER, NULL,   4U) == ARM_DRIVER_ERROR_PARAMETER);
684       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_TX_POWER, &power, 0U) == ARM_DRIVER_ERROR_PARAMETER);
685       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_TX_POWER, &power, 3U) == ARM_DRIVER_ERROR_PARAMETER);
686       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_TX_POWER, &power, 5U) == ARM_DRIVER_OK);
687       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_TX_POWER, &power, 4U) == ARM_DRIVER_OK);
688     } else {
689       not_suported |= 2U;
690       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_TX_POWER for Access Point is not supported");
691     }
692   }
693 #endif
694
695 #if ((WIFI_SETGETOPTION_TX_POWER_EN & 2) != 0)
696   // Get tests
697   len = 4U;
698   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
699   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
700
701   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
702     len = 4U;
703     if (drv->GetOption (0U, ARM_WIFI_TX_POWER, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
704       len = 0U;
705       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_TX_POWER, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
706       len = 4U;
707       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_TX_POWER, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
708       len = 0U;
709       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
710       len = 3U;
711       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
712       len = 5U;
713       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_OK);
714       len = 4U;
715       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_OK);
716     } else {
717       not_suported |= 1U;
718       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_TX_POWER for Station is not supported");
719     }
720   }
721   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
722     len = 4U;
723     if (drv->GetOption (1U, ARM_WIFI_TX_POWER, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
724       len = 0U;
725       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_TX_POWER, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
726       len = 4U;
727       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_TX_POWER, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
728       len = 0U;
729       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
730       len = 3U;
731       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
732       len = 5U;
733       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_OK);
734       len = 4U;
735       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_OK);
736     } else {
737       not_suported |= 2U;
738       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_TX_POWER for Access Point is not supported");
739     }
740   }
741 #endif
742
743 #if ((WIFI_SETGETOPTION_TX_POWER_EN & 3) == 3)
744   // Check with Get that Set has written the correct values
745   if (((cap.station_ap != 0) || (cap.station != 0)) && ((not_suported & 1U) == 0U)) {   // Station test
746     power = WIFI_TX_POWER_STA;
747     len   = 4U;
748     memset((void *)data_buf, 0xCC, sizeof(data_buf));
749     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_TX_POWER, &power,   4U)   == ARM_DRIVER_OK);
750     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_OK);
751     TEST_ASSERT(len == 4U);
752     TEST_ASSERT(memcmp((const void *)&power, (const void *)data_buf, (size_t)len) == 0);
753   }
754   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
755     power = WIFI_TX_POWER_AP;
756     len   = 4U;
757     memset((void *)data_buf, 0xCC, sizeof(data_buf));
758     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_TX_POWER, &power,   4U)   == ARM_DRIVER_OK);
759     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_TX_POWER, data_buf, &len) == ARM_DRIVER_OK);
760     TEST_ASSERT(len == 4U);
761     TEST_ASSERT(memcmp((const void *)&power, (const void *)data_buf, (size_t)len) == 0);
762   }
763 #endif
764 }
765 #endif
766
767 #if (WIFI_SETGETOPTION_LP_TIMER_EN != 0)
768 static void WIFI_SetOption_GetOption_LP_TIMER (void) {
769 #if ((WIFI_SETGETOPTION_LP_TIMER_EN & 1) != 0)
770   uint32_t time;
771 #endif
772 #if ((WIFI_SETGETOPTION_LP_TIMER_EN & 2) != 0)
773   uint32_t len;
774 #endif
775   uint8_t  not_suported;
776
777   not_suported = 0U;
778
779   if (init_and_power_on () == 0) {
780     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
781     return;
782   }
783
784 #if ((WIFI_SETGETOPTION_LP_TIMER_EN & 1) != 0)
785   // Set tests
786   time = WIFI_LP_TIMER_STA;
787   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_LP_TIMER, &time, 4U) == ARM_DRIVER_ERROR_PARAMETER);
788   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_LP_TIMER, &time, 4U) == ARM_DRIVER_ERROR_PARAMETER);
789
790   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
791     time = WIFI_LP_TIMER_STA;
792     if (drv->SetOption (0U, ARM_WIFI_LP_TIMER, &time, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
793       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_LP_TIMER, NULL,  0U) == ARM_DRIVER_ERROR_PARAMETER);
794       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_LP_TIMER, NULL,  4U) == ARM_DRIVER_ERROR_PARAMETER);
795       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_LP_TIMER, &time, 0U) == ARM_DRIVER_ERROR_PARAMETER);
796       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_LP_TIMER, &time, 3U) == ARM_DRIVER_ERROR_PARAMETER);
797       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_LP_TIMER, &time, 5U) == ARM_DRIVER_OK);
798       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_LP_TIMER, &time, 4U) == ARM_DRIVER_OK);
799     } else {
800       not_suported |= 1U;
801       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_LP_TIMER for Station is not supported");
802     }
803   }
804   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
805     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_LP_TIMER, &time, 4U) == ARM_DRIVER_ERROR_UNSUPPORTED);
806   }
807 #endif
808
809 #if ((WIFI_SETGETOPTION_LP_TIMER_EN & 2) != 0)
810   // Get tests
811   len = 4U;
812   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_LP_TIMER, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
813   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_LP_TIMER, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
814
815   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
816     len = 4U;
817     if (drv->GetOption (0U, ARM_WIFI_LP_TIMER, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
818       len = 0U;
819       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_LP_TIMER, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
820       len = 4U;
821       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_LP_TIMER, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
822       len = 0U;
823       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_LP_TIMER, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
824       len = 3U;
825       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_LP_TIMER, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
826       len = 5U;
827       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_LP_TIMER, data_buf, &len) == ARM_DRIVER_OK);
828       len = 4U;
829       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_LP_TIMER, data_buf, &len) == ARM_DRIVER_OK);
830     } else {
831       not_suported |= 1U;
832       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_LP_TIMER for Station is not supported");
833     }
834   }
835   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
836     len = 4U;
837     TEST_ASSERT  (drv->GetOption (1U, ARM_WIFI_LP_TIMER, data_buf,  &len) == ARM_DRIVER_ERROR_UNSUPPORTED);
838   }
839 #endif
840
841 #if ((WIFI_SETGETOPTION_LP_TIMER_EN & 3) == 3)
842   // Check with Get that Set has written the correct values
843   if (((cap.station_ap != 0) || (cap.station != 0)) && ((not_suported & 1U) == 0U)) {   // Station test
844     time = WIFI_LP_TIMER_STA;
845     len  = 4U;
846     memset((void *)data_buf, 0xCC, sizeof(data_buf));
847     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_LP_TIMER, &time,    4U)   == ARM_DRIVER_OK);
848     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_LP_TIMER, data_buf, &len) == ARM_DRIVER_OK);
849     TEST_ASSERT(len == 4U);
850     TEST_ASSERT(memcmp((const void *)&time, (const void *)data_buf, (size_t)len) == 0);
851   }
852 #endif
853 }
854 #endif
855
856 #if (WIFI_SETGETOPTION_DTIM_EN != 0)
857 static void WIFI_SetOption_GetOption_DTIM (void) {
858 #if ((WIFI_SETGETOPTION_DTIM_EN & 1) != 0)
859   uint32_t dtim;
860 #endif
861 #if ((WIFI_SETGETOPTION_DTIM_EN & 2) != 0)
862   uint32_t len;
863 #endif
864   uint8_t  not_suported;
865
866   not_suported = 0U;
867
868   if (init_and_power_on () == 0) {
869     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
870     return;
871   }
872
873 #if ((WIFI_SETGETOPTION_DTIM_EN & 1) != 0)
874   // Set tests
875   dtim = WIFI_DTIM_STA;
876   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_DTIM, &dtim, 4U) == ARM_DRIVER_ERROR_PARAMETER);
877   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_DTIM, &dtim, 4U) == ARM_DRIVER_ERROR_PARAMETER);
878
879   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
880     dtim = WIFI_DTIM_STA;
881     if (drv->SetOption (0U, ARM_WIFI_DTIM, &dtim, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
882       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_DTIM, NULL,  0U) == ARM_DRIVER_ERROR_PARAMETER);
883       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_DTIM, NULL,  4U) == ARM_DRIVER_ERROR_PARAMETER);
884       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_DTIM, &dtim, 0U) == ARM_DRIVER_ERROR_PARAMETER);
885       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_DTIM, &dtim, 3U) == ARM_DRIVER_ERROR_PARAMETER);
886       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_DTIM, &dtim, 5U) == ARM_DRIVER_OK);
887       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_DTIM, &dtim, 4U) == ARM_DRIVER_OK);
888     } else {
889       not_suported |= 1U;
890       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_DTIM for Station is not supported");
891     }
892   }
893   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
894     dtim = WIFI_DTIM_AP;
895     if (drv->SetOption (1U, ARM_WIFI_DTIM, &dtim, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
896       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_DTIM, NULL,  0U) == ARM_DRIVER_ERROR_PARAMETER);
897       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_DTIM, NULL,  4U) == ARM_DRIVER_ERROR_PARAMETER);
898       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_DTIM, &dtim, 0U) == ARM_DRIVER_ERROR_PARAMETER);
899       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_DTIM, &dtim, 3U) == ARM_DRIVER_ERROR_PARAMETER);
900       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_DTIM, &dtim, 5U) == ARM_DRIVER_OK);
901       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_DTIM, &dtim, 4U) == ARM_DRIVER_OK);
902     } else {
903       not_suported |= 2U;
904       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_DTIM for Access Point is not supported");
905     }
906   }
907 #endif
908
909 #if ((WIFI_SETGETOPTION_DTIM_EN & 2) != 0)
910   // Get tests
911   len = 4U;
912   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
913   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
914
915   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
916     len = 4U;
917     if (drv->GetOption (0U, ARM_WIFI_DTIM, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
918       len = 0U;
919       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_DTIM, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
920       len = 4U;
921       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_DTIM, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
922       len = 0U;
923       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
924       len = 3U;
925       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
926       len = 5U;
927       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_OK);
928       len = 4U;
929       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_OK);
930     } else {
931       not_suported |= 1U;
932       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_DTIM for Station is not supported");
933     }
934   }
935   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
936     len = 4U;
937     if (drv->GetOption (1U, ARM_WIFI_DTIM, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
938       len = 0U;
939       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_DTIM, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
940       len = 4U;
941       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_DTIM, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
942       len = 0U;
943       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
944       len = 3U;
945       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
946       len = 5U;
947       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_OK);
948       len = 4U;
949       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_OK);
950     } else {
951       not_suported |= 2U;
952       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_DTIM for Access Point is not supported");
953     }
954   }
955 #endif
956
957 #if ((WIFI_SETGETOPTION_DTIM_EN & 3) == 3)
958   // Check with Get that Set has written the correct values
959   if (((cap.station_ap != 0) || (cap.station != 0)) && ((not_suported & 1U) == 0U)) {   // Station test
960     dtim = WIFI_DTIM_STA;
961     len  = 4U;
962     memset((void *)data_buf, 0xCC, sizeof(data_buf));
963     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_DTIM, &dtim,   4U)   == ARM_DRIVER_OK);
964     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_OK);
965     TEST_ASSERT(len == 4U);
966     TEST_ASSERT(memcmp((const void *)&dtim, (const void *)data_buf, (size_t)len) == 0);
967   }
968   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
969     dtim = WIFI_DTIM_AP;
970     len  = 4U;
971     memset((void *)data_buf, 0xCC, sizeof(data_buf));
972     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_DTIM, &dtim,   4U)   == ARM_DRIVER_OK);
973     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_DTIM, data_buf, &len) == ARM_DRIVER_OK);
974     TEST_ASSERT(len == 4U);
975     TEST_ASSERT(memcmp((const void *)&dtim, (const void *)data_buf, (size_t)len) == 0);
976   }
977 #endif
978 }
979 #endif
980
981 #if (WIFI_SETGETOPTION_BEACON_EN != 0)
982 static void WIFI_SetOption_GetOption_BEACON (void) {
983 #if ((WIFI_SETGETOPTION_BEACON_EN & 1) != 0)
984   uint32_t beacon;
985 #endif
986 #if ((WIFI_SETGETOPTION_BEACON_EN & 2) != 0)
987   uint32_t len;
988 #endif
989   uint8_t  not_suported;
990
991   not_suported = 0U;
992
993   if (init_and_power_on () == 0) {
994     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
995     return;
996   }
997
998 #if ((WIFI_SETGETOPTION_BEACON_EN & 1) != 0)
999   // Set tests
1000   beacon = WIFI_BEACON_AP;
1001   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_BEACON, &beacon, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1002   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_BEACON, &beacon, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1003
1004   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
1005     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_BEACON, &beacon, 4U) == ARM_DRIVER_ERROR_UNSUPPORTED);
1006   }
1007   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1008     beacon = WIFI_BEACON_AP;
1009     if (drv->SetOption (1U, ARM_WIFI_BEACON, &beacon, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1010       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BEACON, NULL,    0U) == ARM_DRIVER_ERROR_PARAMETER);
1011       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BEACON, NULL,    4U) == ARM_DRIVER_ERROR_PARAMETER);
1012       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BEACON, &beacon, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1013       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BEACON, &beacon, 3U) == ARM_DRIVER_ERROR_PARAMETER);
1014       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BEACON, &beacon, 5U) == ARM_DRIVER_OK);
1015       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BEACON, &beacon, 4U) == ARM_DRIVER_OK);
1016     } else {
1017       not_suported |= 2U;
1018       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_BEACON for Access Point is not supported");
1019     }
1020   }
1021 #endif
1022
1023 #if ((WIFI_SETGETOPTION_BEACON_EN & 2) != 0)
1024   // Get tests
1025   len = 4U;
1026   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_BEACON, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1027   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_BEACON, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1028
1029   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
1030     len = 4U;
1031     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_BEACON, data_buf,  &len) == ARM_DRIVER_ERROR_UNSUPPORTED);
1032   }
1033   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1034     len = 4U;
1035     if (drv->GetOption (1U, ARM_WIFI_BEACON, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1036       len = 0U;
1037       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BEACON, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1038       len = 4U;
1039       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BEACON, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1040       len = 0U;
1041       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BEACON, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1042       len = 3U;
1043       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BEACON, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1044       len = 5U;
1045       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BEACON, data_buf, &len) == ARM_DRIVER_OK);
1046       len = 4U;
1047       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BEACON, data_buf, &len) == ARM_DRIVER_OK);
1048     } else {
1049       not_suported |= 2U;
1050       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_BEACON for Access Point is not supported");
1051     }
1052   }
1053 #endif
1054
1055 #if ((WIFI_SETGETOPTION_BEACON_EN & 3) == 3)
1056   // Check with Get that Set has written the correct values
1057   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
1058     beacon = WIFI_BEACON_AP;
1059     len    = 4U;
1060     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1061     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_BEACON, &beacon,   4U)  == ARM_DRIVER_OK);
1062     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_BEACON, data_buf, &len) == ARM_DRIVER_OK);
1063     TEST_ASSERT(len == 4U);
1064     TEST_ASSERT(memcmp((const void *)&beacon, (const void *)data_buf, (size_t)len) == 0);
1065   }
1066 #endif
1067 }
1068 #endif
1069
1070 #if (WIFI_SETGETOPTION_MAC_EN != 0)
1071 static void WIFI_SetOption_GetOption_MAC (void) {
1072 #if ((WIFI_SETGETOPTION_MAC_EN & 1) != 0)
1073   uint8_t  u8_arr[8]      __ALIGNED(4);
1074   uint8_t  mac[7]         __ALIGNED(4);
1075   uint8_t  mac_ap_def[6]  __ALIGNED(4);
1076   uint8_t  mac_sta_def[6] __ALIGNED(4);
1077 #endif
1078 #if ((WIFI_SETGETOPTION_MAC_EN & 2) != 0)
1079   uint32_t len;
1080 #endif
1081   uint8_t  not_suported;
1082
1083   not_suported = 0U;
1084
1085   if (init_and_power_on () == 0) {
1086     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
1087     return;
1088   }
1089
1090 // Read default MAC so it can be restored at the end of this test function
1091 #if ((WIFI_SETGETOPTION_MAC_EN & 3) == 3)
1092   if (((cap.station_ap != 0) || (cap.station != 0))) {
1093     len = 6U;
1094     drv->GetOption (0U, ARM_WIFI_MAC, mac_sta_def, &len);
1095   }
1096   if ((cap.station_ap != 0) || (cap.ap != 0)) {
1097     len = 6U;
1098     drv->GetOption (1U, ARM_WIFI_MAC, mac_ap_def, &len);
1099   }
1100 #endif
1101
1102 #if ((WIFI_SETGETOPTION_MAC_EN & 1) != 0)
1103   // Set tests
1104   memset((void *)mac, 0x11, 7);
1105   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_MAC, mac, 6U) == ARM_DRIVER_ERROR_PARAMETER);
1106   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_MAC, mac, 6U) == ARM_DRIVER_ERROR_PARAMETER);
1107
1108   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
1109     TEST_ASSERT(sscanf((const char *)WIFI_MAC_STA, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6);
1110     memset((void *) u8_arr, 0xCC, 8);
1111     memcpy((void *)&u8_arr[1], (const void *)mac, 6);
1112     if (drv->SetOption (0U, ARM_WIFI_MAC, mac, 6U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1113       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_MAC, NULL,       0U) == ARM_DRIVER_ERROR_PARAMETER);
1114       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_MAC, NULL,       6U) == ARM_DRIVER_ERROR_PARAMETER);
1115       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_MAC, mac,        0U) == ARM_DRIVER_ERROR_PARAMETER);
1116       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_MAC, mac,        5U) == ARM_DRIVER_ERROR_PARAMETER);
1117       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_MAC, &u8_arr[1], 6U) == ARM_DRIVER_OK);
1118       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_MAC, &u8_arr[1], 7U) == ARM_DRIVER_OK);
1119       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_MAC, mac,        7U) == ARM_DRIVER_OK);
1120       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_MAC, mac,        6U) == ARM_DRIVER_OK);
1121     } else {
1122       not_suported |= 1U;
1123       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_MAC for Station is not supported");
1124     }
1125   }
1126   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1127     TEST_ASSERT(sscanf((const char *)WIFI_MAC_AP, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6);
1128     memset((void *) u8_arr, 0xCC, 8);
1129     memcpy((void *)&u8_arr[1], (const void *)mac, 6);
1130     if (drv->SetOption (1U, ARM_WIFI_MAC, mac, 6U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1131       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_MAC, NULL,       0U) == ARM_DRIVER_ERROR_PARAMETER);
1132       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_MAC, NULL,       6U) == ARM_DRIVER_ERROR_PARAMETER);
1133       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_MAC, mac,        0U) == ARM_DRIVER_ERROR_PARAMETER);
1134       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_MAC, mac,        5U) == ARM_DRIVER_ERROR_PARAMETER);
1135       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_MAC, &u8_arr[1], 6U) == ARM_DRIVER_OK);
1136       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_MAC, &u8_arr[1], 7U) == ARM_DRIVER_OK);
1137       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_MAC, mac,        7U) == ARM_DRIVER_OK);
1138       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_MAC, mac,        6U) == ARM_DRIVER_OK);
1139     } else {
1140       not_suported |= 2U;
1141       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_MAC for Access Point is not supported");
1142     }
1143   }
1144 #endif
1145
1146 #if ((WIFI_SETGETOPTION_MAC_EN & 2) != 0)
1147   // Get tests
1148   len = 6U;
1149   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_MAC, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1150   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_MAC, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1151
1152   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
1153     len = 6U;
1154     if (drv->GetOption (0U, ARM_WIFI_MAC, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1155       len = 0U;
1156       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_MAC, NULL,      &len) == ARM_DRIVER_ERROR_PARAMETER);
1157       len = 6U;
1158       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_MAC, NULL,      &len) == ARM_DRIVER_ERROR_PARAMETER);
1159       len = 0U;
1160       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_MAC, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1161       len = 5U;
1162       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_MAC, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1163       len = 6U;
1164       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_MAC, data_buf+1,&len) == ARM_DRIVER_OK);
1165       len = 7U;
1166       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_MAC, data_buf+1,&len) == ARM_DRIVER_OK);
1167       len = 7U;
1168       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_MAC, data_buf,  &len) == ARM_DRIVER_OK);
1169       len = 6U;
1170       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_MAC, data_buf,  &len) == ARM_DRIVER_OK);
1171     } else {
1172       not_suported |= 1U;
1173       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_MAC for Station is not supported");
1174     }
1175   }
1176   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1177     len = 6U;
1178     if (drv->GetOption (1U, ARM_WIFI_MAC, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1179       len = 0U;
1180       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_MAC, NULL,      &len) == ARM_DRIVER_ERROR_PARAMETER);
1181       len = 6U;
1182       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_MAC, NULL,      &len) == ARM_DRIVER_ERROR_PARAMETER);
1183       len = 0U;
1184       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_MAC, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1185       len = 5U;
1186       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_MAC, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1187       len = 6U;
1188       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_MAC, data_buf+1,&len) == ARM_DRIVER_OK);
1189       len = 7U;
1190       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_MAC, data_buf+1,&len) == ARM_DRIVER_OK);
1191       len = 7U;
1192       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_MAC, data_buf,  &len) == ARM_DRIVER_OK);
1193       len = 6U;
1194       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_MAC, data_buf,  &len) == ARM_DRIVER_OK);
1195     } else {
1196       not_suported |= 2U;
1197       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_MAC for Access Point is not supported");
1198     }
1199   }
1200 #endif
1201
1202 #if ((WIFI_SETGETOPTION_MAC_EN & 3) == 3)
1203   // Check with Get that Set has written the correct values
1204   if (((cap.station_ap != 0) || (cap.station != 0)) && ((not_suported & 1U) == 0U)) {   // Station test
1205     TEST_ASSERT(sscanf((const char *)WIFI_MAC_STA, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6);
1206     len = 6U;
1207     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1208     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_MAC, mac,      6U)   == ARM_DRIVER_OK);
1209     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_MAC, data_buf, &len) == ARM_DRIVER_OK);
1210     TEST_ASSERT(len == 6U);
1211     TEST_ASSERT(memcmp((const void *)mac, (const void *)data_buf, (size_t)len) == 0);
1212   }
1213   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
1214     TEST_ASSERT(sscanf((const char *)WIFI_MAC_AP, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6);
1215     len = 6U;
1216     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1217     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_MAC, mac,      6U)   == ARM_DRIVER_OK);
1218     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_MAC, data_buf, &len) == ARM_DRIVER_OK);
1219     TEST_ASSERT(len == 6U);
1220     TEST_ASSERT(memcmp((const void *)mac, (const void *)data_buf, (size_t)len) == 0);
1221   }
1222
1223   // Restore default MAC
1224   if (((cap.station_ap != 0) || (cap.station != 0)) && (memcmp((const void *)mac_sta_def, (const void *)"\0\0\0\0\0\0", 6) != 0)) {
1225     drv->SetOption (0U, ARM_WIFI_MAC, mac_sta_def, 6U);
1226   }
1227   if (((cap.station_ap != 0) || (cap.ap != 0))      && (memcmp((const void *)mac_ap_def,  (const void *)"\0\0\0\0\0\0", 6) != 0)) {
1228     drv->SetOption (1U, ARM_WIFI_MAC, mac_ap_def,  6U);
1229   }
1230 #endif
1231 }
1232 #endif
1233
1234 #if (WIFI_SETGETOPTION_IP_EN != 0)
1235 static void WIFI_SetOption_GetOption_IP (void) {
1236 #if ((WIFI_SETGETOPTION_IP_EN & 1) != 0)
1237   uint32_t u32_0, u32_1;
1238   uint8_t  ip[5] __ALIGNED(4);
1239 #endif
1240 #if ((WIFI_SETGETOPTION_IP_EN & 2) != 0)
1241   uint32_t len;
1242 #endif
1243   uint8_t  not_suported;
1244
1245   not_suported = 0U;
1246
1247   if (init_and_power_on () == 0) {
1248     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
1249     return;
1250   }
1251
1252 #if ((WIFI_SETGETOPTION_IP_EN & 1) != 0)
1253   // Set tests
1254   u32_0 = 0U;
1255   u32_1 = 1U;
1256   memset((void *)ip, 0, 5);
1257   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_IP, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1258   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_IP, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1259
1260   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
1261     TEST_ASSERT(sscanf((const char *)WIFI_IP_STA, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1262     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1263     if (drv->SetOption (0U, ARM_WIFI_IP, ip, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1264       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1265       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1266       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP, ip,   0U) == ARM_DRIVER_ERROR_PARAMETER);
1267       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP, ip,   3U) == ARM_DRIVER_ERROR_PARAMETER);
1268       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP, ip,   5U) == ARM_DRIVER_OK);
1269       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP, ip,   4U) == ARM_DRIVER_OK);
1270     } else {
1271       not_suported |= 1U;
1272       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP for Station is not supported");
1273     }
1274     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1275   }
1276   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1277     TEST_ASSERT(sscanf((const char *)WIFI_IP_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1278     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1279     if (drv->SetOption (1U, ARM_WIFI_IP, ip, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1280       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1281       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1282       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP, ip,   0U) == ARM_DRIVER_ERROR_PARAMETER);
1283       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP, ip,   3U) == ARM_DRIVER_ERROR_PARAMETER);
1284       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP, ip,   5U) == ARM_DRIVER_OK);
1285       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP, ip,   4U) == ARM_DRIVER_OK);
1286     } else {
1287       not_suported |= 2U;
1288       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP for Access Point is not supported");
1289     }
1290     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1291   }
1292 #endif
1293
1294 #if ((WIFI_SETGETOPTION_IP_EN & 2) != 0)
1295   // Get tests
1296   len = 4U;
1297   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_IP, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1298   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_IP, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1299
1300   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
1301     len = 4U;
1302     if (drv->GetOption (0U, ARM_WIFI_IP, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1303       len = 0U;
1304       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1305       len = 4U;
1306       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1307       len = 0U;
1308       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1309       len = 3U;
1310       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1311       len = 5U;
1312       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP, data_buf, &len) == ARM_DRIVER_OK);
1313       len = 4U;
1314       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP, data_buf, &len) == ARM_DRIVER_OK);
1315     } else {
1316       not_suported |= 1U;
1317       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP for Station is not supported");
1318     }
1319   }
1320   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1321     len = 4U;
1322     if (drv->GetOption (1U, ARM_WIFI_IP, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1323       len = 0U;
1324       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1325       len = 4U;
1326       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1327       len = 0U;
1328       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1329       len = 3U;
1330       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1331       len = 5U;
1332       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP, data_buf, &len) == ARM_DRIVER_OK);
1333       len = 4U;
1334       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP, data_buf, &len) == ARM_DRIVER_OK);
1335     } else {
1336       not_suported |= 2U;
1337       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP for Access Point is not supported");
1338     }
1339   }
1340 #endif
1341
1342 #if ((WIFI_SETGETOPTION_IP_EN & 3) == 3)
1343   // Check with Get that Set has written the correct values
1344   if (((cap.station_ap != 0) || (cap.station != 0)) && ((not_suported & 1U) == 0U)) {   // Station test
1345     TEST_ASSERT(sscanf((const char *)WIFI_IP_STA, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1346     len = 4U;
1347     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1348     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1349     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP, ip,       4U)   == ARM_DRIVER_OK);
1350     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP, data_buf, &len) == ARM_DRIVER_OK);
1351     TEST_ASSERT(len == 4U);
1352     TEST_ASSERT(memcmp((const void *)ip, (const void *)data_buf, (size_t)len) == 0);
1353     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1354   }
1355   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
1356     TEST_ASSERT(sscanf((const char *)WIFI_IP_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1357     len = 4U;
1358     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1359     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1360     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP, ip,       4U)   == ARM_DRIVER_OK);
1361     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP, data_buf, &len) == ARM_DRIVER_OK);
1362     TEST_ASSERT(len == 4U);
1363     TEST_ASSERT(memcmp((const void *)ip, (const void *)data_buf, (size_t)len) == 0);
1364     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1365   }
1366 #endif
1367 }
1368 #endif
1369
1370 #if (WIFI_SETGETOPTION_IP_SUBNET_MASK_EN != 0)
1371 static void WIFI_SetOption_GetOption_IP_SUBNET_MASK (void) {
1372 #if ((WIFI_SETGETOPTION_IP_SUBNET_MASK_EN & 1) != 0)
1373   uint32_t u32_0, u32_1;
1374   uint8_t  mask[5] __ALIGNED(4);
1375 #endif
1376 #if ((WIFI_SETGETOPTION_IP_SUBNET_MASK_EN & 2) != 0)
1377   uint32_t len;
1378 #endif
1379   uint8_t  not_suported;
1380
1381   not_suported = 0U;
1382
1383   if (init_and_power_on () == 0) {
1384     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
1385     return;
1386   }
1387
1388 #if ((WIFI_SETGETOPTION_IP_SUBNET_MASK_EN & 1) != 0)
1389   // Set tests
1390   u32_0 = 0U;
1391   u32_1 = 1U;
1392   memset((void *)mask, 0, 5);
1393   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_IP_SUBNET_MASK, mask, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1394   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_IP_SUBNET_MASK, mask, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1395
1396   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
1397     TEST_ASSERT(sscanf((const char *)WIFI_IP_SUBNET_MASK_STA, "%hhu.%hhu.%hhu.%hhu", &mask[0], &mask[1], &mask[2], &mask[3]) == 4);
1398     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1399     if (drv->SetOption (0U, ARM_WIFI_IP_SUBNET_MASK, mask, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1400       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_SUBNET_MASK, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1401       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_SUBNET_MASK, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1402       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_SUBNET_MASK, mask, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1403       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_SUBNET_MASK, mask, 3U) == ARM_DRIVER_ERROR_PARAMETER);
1404       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_SUBNET_MASK, mask, 5U) == ARM_DRIVER_OK);
1405       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_SUBNET_MASK, mask, 4U) == ARM_DRIVER_OK);
1406     } else {
1407       not_suported |= 1U;
1408       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_SUBNET_MASK for Station is not supported");
1409     }
1410     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1411   }
1412   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1413     TEST_ASSERT(sscanf((const char *)WIFI_IP_SUBNET_MASK_AP, "%hhu.%hhu.%hhu.%hhu", &mask[0], &mask[1], &mask[2], &mask[3]) == 4);
1414     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1415     if (drv->SetOption (1U, ARM_WIFI_IP_SUBNET_MASK, mask, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1416       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_SUBNET_MASK, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1417       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_SUBNET_MASK, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1418       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_SUBNET_MASK, mask, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1419       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_SUBNET_MASK, mask, 3U) == ARM_DRIVER_ERROR_PARAMETER);
1420       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_SUBNET_MASK, mask, 5U) == ARM_DRIVER_OK);
1421       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_SUBNET_MASK, mask, 4U) == ARM_DRIVER_OK);
1422     } else {
1423       not_suported |= 2U;
1424       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_SUBNET_MASK for Access Point is not supported");
1425     }
1426     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1427   }
1428 #endif
1429
1430 #if ((WIFI_SETGETOPTION_IP_SUBNET_MASK_EN & 2) != 0)
1431   // Get tests
1432   len = 4U;
1433   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1434   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1435
1436   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
1437     len = 4U;
1438     if (drv->GetOption (0U, ARM_WIFI_IP_SUBNET_MASK, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1439       len = 0U;
1440       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_SUBNET_MASK, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1441       len = 4U;
1442       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_SUBNET_MASK, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1443       len = 0U;
1444       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1445       len = 3U;
1446       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1447       len = 5U;
1448       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_OK);
1449       len = 4U;
1450       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_OK);
1451     } else {
1452       not_suported |= 1U;
1453       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_SUBNET_MASK for Station is not supported");
1454     }
1455   }
1456   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1457     len = 4U;
1458     if (drv->GetOption (1U, ARM_WIFI_IP_SUBNET_MASK, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1459       len = 0U;
1460       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_SUBNET_MASK, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1461       len = 4U;
1462       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_SUBNET_MASK, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1463       len = 0U;
1464       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1465       len = 3U;
1466       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1467       len = 5U;
1468       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_OK);
1469       len = 4U;
1470       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_OK);
1471     } else {
1472       not_suported |= 2U;
1473       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_SUBNET_MASK for Access Point is not supported");
1474     }
1475   }
1476 #endif
1477
1478 #if ((WIFI_SETGETOPTION_IP_SUBNET_MASK_EN & 3) == 3)
1479   // Check with Get that Set has written the correct values
1480   if (((cap.station_ap != 0) || (cap.station != 0)) && ((not_suported & 1U) == 0U)) {   // Station test
1481     TEST_ASSERT(sscanf((const char *)WIFI_IP_SUBNET_MASK_STA, "%hhu.%hhu.%hhu.%hhu", &mask[0], &mask[1], &mask[2], &mask[3]) == 4);
1482     len = 4U;
1483     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1484     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1485     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_SUBNET_MASK, mask,     4U)   == ARM_DRIVER_OK);
1486     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_OK);
1487     TEST_ASSERT(len == 4U);
1488     TEST_ASSERT(memcmp((const void *)mask, (const void *)data_buf, (size_t)len) == 0);
1489     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1490   }
1491   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
1492     TEST_ASSERT(sscanf((const char *)WIFI_IP_SUBNET_MASK_AP, "%hhu.%hhu.%hhu.%hhu", &mask[0], &mask[1], &mask[2], &mask[3]) == 4);
1493     len = 4U;
1494     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1495     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1496     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_SUBNET_MASK, mask,     4U)   == ARM_DRIVER_OK);
1497     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_SUBNET_MASK, data_buf, &len) == ARM_DRIVER_OK);
1498     TEST_ASSERT(len == 4U);
1499     TEST_ASSERT(memcmp((const void *)mask, (const void *)data_buf, (size_t)len) == 0);
1500     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1501   }
1502 #endif
1503 }
1504 #endif
1505
1506 #if (WIFI_SETGETOPTION_IP_GATEWAY_EN != 0)
1507 static void WIFI_SetOption_GetOption_IP_GATEWAY (void) {
1508 #if ((WIFI_SETGETOPTION_IP_GATEWAY_EN & 1) != 0)
1509   uint32_t u32_0, u32_1;
1510   uint8_t  ip[5] __ALIGNED(4);
1511 #endif
1512 #if ((WIFI_SETGETOPTION_IP_GATEWAY_EN & 2) != 0)
1513   uint32_t len;
1514 #endif
1515   uint8_t  not_suported;
1516
1517   not_suported = 0U;
1518
1519   if (init_and_power_on () == 0) {
1520     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
1521     return;
1522   }
1523
1524 #if ((WIFI_SETGETOPTION_IP_GATEWAY_EN & 1) != 0)
1525   // Set tests
1526   u32_0 = 0U;
1527   u32_1 = 1U;
1528   memset((void *)ip, 0, 5);
1529   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_IP_GATEWAY, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1530   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_IP_GATEWAY, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1531
1532   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
1533     TEST_ASSERT(sscanf((const char *)WIFI_IP_GATEWAY_STA, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1534     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1535     if (drv->SetOption (0U, ARM_WIFI_IP_GATEWAY, ip, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1536       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_GATEWAY, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1537       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_GATEWAY, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1538       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_GATEWAY, ip,   0U) == ARM_DRIVER_ERROR_PARAMETER);
1539       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_GATEWAY, ip,   3U) == ARM_DRIVER_ERROR_PARAMETER);
1540       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_GATEWAY, ip,   5U) == ARM_DRIVER_OK);
1541       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_GATEWAY, ip,   4U) == ARM_DRIVER_OK);
1542     } else {
1543       not_suported |= 1U;
1544       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_GATEWAY for Station is not supported");
1545     }
1546     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1547   }
1548   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1549     TEST_ASSERT(sscanf((const char *)WIFI_IP_GATEWAY_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1550     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1551     if (drv->SetOption (1U, ARM_WIFI_IP_GATEWAY, ip, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1552       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_GATEWAY, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1553       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_GATEWAY, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1554       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_GATEWAY, ip,   0U) == ARM_DRIVER_ERROR_PARAMETER);
1555       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_GATEWAY, ip,   3U) == ARM_DRIVER_ERROR_PARAMETER);
1556       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_GATEWAY, ip,   5U) == ARM_DRIVER_OK);
1557       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_GATEWAY, ip,   4U) == ARM_DRIVER_OK);
1558     } else {
1559       not_suported |= 2U;
1560       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_GATEWAY for Access Point is not supported");
1561     }
1562     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1563   }
1564 #endif
1565
1566 #if ((WIFI_SETGETOPTION_IP_GATEWAY_EN & 2) != 0)
1567   // Get tests
1568   len = 4U;
1569   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1570   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1571
1572   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
1573     len = 4U;
1574     if (drv->GetOption (0U, ARM_WIFI_IP_GATEWAY, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1575       len = 0U;
1576       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_GATEWAY, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1577       len = 4U;
1578       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_GATEWAY, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1579       len = 0U;
1580       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1581       len = 3U;
1582       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1583       len = 5U;
1584       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_OK);
1585       len = 4U;
1586       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_OK);
1587     } else {
1588       not_suported |= 1U;
1589       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_GATEWAY for Station is not supported");
1590     }
1591   }
1592   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1593     len = 4U;
1594     if (drv->GetOption (1U, ARM_WIFI_IP_GATEWAY, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1595       len = 0U;
1596       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_GATEWAY, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1597       len = 4U;
1598       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_GATEWAY, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1599       len = 0U;
1600       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1601       len = 3U;
1602       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1603       len = 5U;
1604       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_OK);
1605       len = 4U;
1606       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_OK);
1607     } else {
1608       not_suported |= 2U;
1609       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_GATEWAY for Access Point is not supported");
1610     }
1611   }
1612 #endif
1613
1614 #if ((WIFI_SETGETOPTION_IP_GATEWAY_EN & 3) == 3)
1615   // Check with Get that Set has written the correct values
1616   if (((cap.station_ap != 0) || (cap.station != 0)) && ((not_suported & 1U) == 0U)) {   // Station test
1617     TEST_ASSERT(sscanf((const char *)WIFI_IP_GATEWAY_STA, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1618     len = 4U;
1619     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1620     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1621     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_GATEWAY, ip,       4U)   == ARM_DRIVER_OK);
1622     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_OK);
1623     TEST_ASSERT(len == 4U);
1624     TEST_ASSERT(memcmp((const void *)ip, (const void *)data_buf, (size_t)len) == 0);
1625     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1626   }
1627   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
1628     TEST_ASSERT(sscanf((const char *)WIFI_IP_GATEWAY_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1629     len = 4U;
1630     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1631     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1632     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_GATEWAY, ip,       4U)   == ARM_DRIVER_OK);
1633     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_GATEWAY, data_buf, &len) == ARM_DRIVER_OK);
1634     TEST_ASSERT(len == 4U);
1635     TEST_ASSERT(memcmp((const void *)ip, (const void *)data_buf, (size_t)len) == 0);
1636     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1637   }
1638 #endif
1639 }
1640 #endif
1641
1642 #if (WIFI_SETGETOPTION_IP_DNS1_EN != 0)
1643 static void WIFI_SetOption_GetOption_IP_DNS1 (void) {
1644 #if ((WIFI_SETGETOPTION_IP_DNS1_EN & 1) != 0)
1645   uint32_t u32_0, u32_1;
1646   uint8_t  ip[5] __ALIGNED(4);
1647 #endif
1648 #if ((WIFI_SETGETOPTION_IP_DNS1_EN & 2) != 0)
1649   uint32_t len;
1650 #endif
1651   uint8_t  not_suported;
1652
1653   not_suported = 0U;
1654
1655   if (init_and_power_on () == 0) {
1656     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
1657     return;
1658   }
1659
1660 #if ((WIFI_SETGETOPTION_IP_DNS1_EN & 1) != 0)
1661   // Set tests
1662   u32_0 = 0U;
1663   u32_1 = 1U;
1664   memset((void *)ip, 0, 5);
1665   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_IP_DNS1, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1666   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_IP_DNS1, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1667
1668   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
1669     TEST_ASSERT(sscanf((const char *)WIFI_IP_DNS1_STA, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1670     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1671     if (drv->SetOption (0U, ARM_WIFI_IP_DNS1, ip, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1672       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS1, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1673       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS1, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1674       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS1, ip,   0U) == ARM_DRIVER_ERROR_PARAMETER);
1675       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS1, ip,   3U) == ARM_DRIVER_ERROR_PARAMETER);
1676       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS1, ip,   5U) == ARM_DRIVER_OK);
1677       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS1, ip,   4U) == ARM_DRIVER_OK);
1678     } else {
1679       not_suported |= 1U;
1680       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_DNS1 for Station is not supported");
1681     }
1682     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1683   }
1684   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1685     TEST_ASSERT(sscanf((const char *)WIFI_IP_DNS1_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1686     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1687     if (drv->SetOption (1U, ARM_WIFI_IP_DNS1, ip, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1688       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS1, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1689       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS1, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1690       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS1, ip,   0U) == ARM_DRIVER_ERROR_PARAMETER);
1691       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS1, ip,   3U) == ARM_DRIVER_ERROR_PARAMETER);
1692       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS1, ip,   5U) == ARM_DRIVER_OK);
1693       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS1, ip,   4U) == ARM_DRIVER_OK);
1694     } else {
1695       not_suported |= 2U;
1696       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_DNS1 for Access Point is not supported");
1697     }
1698     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1699   }
1700 #endif
1701
1702 #if ((WIFI_SETGETOPTION_IP_DNS1_EN & 2) != 0)
1703   // Get tests
1704   len = 4U;
1705   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1706   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1707
1708   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
1709     len = 4U;
1710     if (drv->GetOption (0U, ARM_WIFI_IP_DNS1, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1711       len = 0U;
1712       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS1, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1713       len = 4U;
1714       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS1, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1715       len = 0U;
1716       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1717       len = 3U;
1718       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1719       len = 5U;
1720       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_OK);
1721       len = 4U;
1722       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_OK);
1723     } else {
1724       not_suported |= 1U;
1725       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_DNS1 for Station is not supported");
1726     }
1727   }
1728   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1729     len = 4U;
1730     if (drv->GetOption (1U, ARM_WIFI_IP_DNS1, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1731       len = 0U;
1732       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS1, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1733       len = 4U;
1734       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS1, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1735       len = 0U;
1736       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1737       len = 3U;
1738       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1739       len = 5U;
1740       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_OK);
1741       len = 4U;
1742       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_OK);
1743     } else {
1744       not_suported |= 2U;
1745       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_DNS1 for Access Point is not supported");
1746     }
1747   }
1748 #endif
1749
1750 #if ((WIFI_SETGETOPTION_IP_DNS1_EN & 3) == 3)
1751   // Check with Get that Set has written the correct values
1752   if (((cap.station_ap != 0) || (cap.station != 0)) && ((not_suported & 1U) == 0U)) {   // Station test
1753     TEST_ASSERT(sscanf((const char *)WIFI_IP_DNS1_STA, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1754     len = 4U;
1755     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1756     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1757     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS1, ip,       4U)   == ARM_DRIVER_OK);
1758     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_OK);
1759     TEST_ASSERT(len == 4U);
1760     TEST_ASSERT(memcmp((const void *)ip, (const void *)data_buf, (size_t)len) == 0);
1761     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1762   }
1763   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
1764     TEST_ASSERT(sscanf((const char *)WIFI_IP_DNS1_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1765     len = 4U;
1766     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1767     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1768     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS1, ip,       4U)   == ARM_DRIVER_OK);
1769     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS1, data_buf, &len) == ARM_DRIVER_OK);
1770     TEST_ASSERT(len == 4U);
1771     TEST_ASSERT(memcmp((const void *)ip, (const void *)data_buf, (size_t)len) == 0);
1772     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1773   }
1774 #endif
1775 }
1776 #endif
1777
1778 #if (WIFI_SETGETOPTION_IP_DNS2_EN != 0)
1779 static void WIFI_SetOption_GetOption_IP_DNS2 (void) {
1780 #if ((WIFI_SETGETOPTION_IP_DNS2_EN & 1) != 0)
1781   uint32_t u32_0, u32_1;
1782   uint8_t  ip[5] __ALIGNED(4);
1783 #endif
1784 #if ((WIFI_SETGETOPTION_IP_DNS2_EN & 2) != 0)
1785   uint32_t len;
1786 #endif
1787   uint8_t  not_suported;
1788
1789   not_suported = 0U;
1790
1791   if (init_and_power_on () == 0) {
1792     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
1793     return;
1794   }
1795
1796 #if ((WIFI_SETGETOPTION_IP_DNS2_EN & 1) != 0)
1797   // Set tests
1798   u32_0 = 0U;
1799   u32_1 = 1U;
1800   memset((void *)ip, 0, 5);
1801   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_IP_DNS2, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1802   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_IP_DNS2, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1803
1804   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
1805     TEST_ASSERT(sscanf((const char *)WIFI_IP_DNS2_STA, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1806     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1807     if (drv->SetOption (0U, ARM_WIFI_IP_DNS2, ip, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1808       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS2, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1809       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS2, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1810       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS2, ip,   0U) == ARM_DRIVER_ERROR_PARAMETER);
1811       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS2, ip,   3U) == ARM_DRIVER_ERROR_PARAMETER);
1812       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS2, ip,   5U) == ARM_DRIVER_OK);
1813       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS2, ip,   4U) == ARM_DRIVER_OK);
1814     } else {
1815       not_suported |= 1U;
1816       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_DNS2 for Station is not supported");
1817     }
1818     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1819   }
1820   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1821     TEST_ASSERT(sscanf((const char *)WIFI_IP_DNS2_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1822     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1823     if (drv->SetOption (1U, ARM_WIFI_IP_DNS2, ip, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1824       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS2, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1825       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS2, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1826       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS2, ip,   0U) == ARM_DRIVER_ERROR_PARAMETER);
1827       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS2, ip,   3U) == ARM_DRIVER_ERROR_PARAMETER);
1828       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS2, ip,   5U) == ARM_DRIVER_OK);
1829       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS2, ip,   4U) == ARM_DRIVER_OK);
1830     } else {
1831       not_suported |= 2U;
1832       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_DNS2 for Access Point is not supported");
1833     }
1834     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1835   }
1836 #endif
1837
1838 #if ((WIFI_SETGETOPTION_IP_DNS2_EN & 2) != 0)
1839   // Get tests
1840   len = 4U;
1841   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_IP_DNS2, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1842   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_IP_DNS2, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1843
1844   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
1845     len = 4U;
1846     if (drv->GetOption (0U, ARM_WIFI_IP_DNS2, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1847       len = 0U;
1848       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS2, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1849       len = 4U;
1850       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS2, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1851       len = 0U;
1852       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS2, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1853       len = 3U;
1854       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS2, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1855       len = 5U;
1856       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS2, data_buf, &len) == ARM_DRIVER_OK);
1857       len = 4U;
1858       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS2, data_buf, &len) == ARM_DRIVER_OK);
1859     } else {
1860       not_suported |= 1U;
1861       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_DNS2 for Station is not supported");
1862     }
1863   }
1864   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1865     len = 4U;
1866     if (drv->GetOption (1U, ARM_WIFI_IP_DNS2, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1867       len = 0U;
1868       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS2, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1869       len = 4U;
1870       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS2, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1871       len = 0U;
1872       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS2, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1873       len = 3U;
1874       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS2, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1875       len = 5U;
1876       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS2, data_buf, &len) == ARM_DRIVER_OK);
1877       len = 4U;
1878       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS2, data_buf, &len) == ARM_DRIVER_OK);
1879     } else {
1880       not_suported |= 2U;
1881       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_DNS2 for Access Point is not supported");
1882     }
1883   }
1884 #endif
1885
1886 #if ((WIFI_SETGETOPTION_IP_DNS2_EN & 3) == 3)
1887   // Check with Get that Set has written the correct values
1888   if (((cap.station_ap != 0) || (cap.station != 0)) && ((not_suported & 1U) == 0U)) {   // Station test
1889     TEST_ASSERT(sscanf((const char *)WIFI_IP_DNS2_STA, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1890     len = 4U;
1891     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1892     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1893     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DNS2, ip,       4U)   == ARM_DRIVER_OK);
1894     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DNS2, data_buf, &len) == ARM_DRIVER_OK);
1895     TEST_ASSERT(len == 4U);
1896     TEST_ASSERT(memcmp((const void *)ip, (const void *)data_buf, (size_t)len) == 0);
1897     drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1898   }
1899   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
1900     TEST_ASSERT(sscanf((const char *)WIFI_IP_DNS2_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
1901     len = 4U;
1902     memset((void *)data_buf, 0xCC, sizeof(data_buf));
1903     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
1904     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DNS2, ip,       4U)   == ARM_DRIVER_OK);
1905     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DNS2, data_buf, &len) == ARM_DRIVER_OK);
1906     TEST_ASSERT(len == 4U);
1907     TEST_ASSERT(memcmp((const void *)ip, (const void *)data_buf, (size_t)len) == 0);
1908     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
1909   }
1910 #endif
1911 }
1912 #endif
1913
1914 #if (WIFI_SETGETOPTION_IP_DHCP_EN != 0)
1915 static void WIFI_SetOption_GetOption_IP_DHCP (void) {
1916 #if ((WIFI_SETGETOPTION_IP_DHCP_EN & 1) != 0)
1917   uint32_t u32_1, u32_0;
1918 #endif
1919 #if ((WIFI_SETGETOPTION_IP_DHCP_EN & 2) != 0)
1920   uint32_t len;
1921 #endif
1922   uint8_t  not_suported;
1923
1924   not_suported = 0U;
1925
1926   if (init_and_power_on () == 0) {
1927     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
1928     return;
1929   }
1930
1931 #if ((WIFI_SETGETOPTION_IP_DHCP_EN & 1) != 0)
1932   // Set tests
1933   u32_0 = 0U;
1934   u32_1 = 1U;
1935   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_IP_DHCP, &u32_0, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1936   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_IP_DHCP, &u32_0, 4U) == ARM_DRIVER_ERROR_PARAMETER);
1937
1938   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
1939     if (drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1940       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP, NULL,   0U) == ARM_DRIVER_ERROR_PARAMETER);
1941       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP, NULL,   4U) == ARM_DRIVER_ERROR_PARAMETER);
1942       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1943       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 3U) == ARM_DRIVER_ERROR_PARAMETER);
1944       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 5U) == ARM_DRIVER_OK);
1945       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0, 4U) == ARM_DRIVER_OK);
1946       TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1, 4U) == ARM_DRIVER_OK);
1947     } else {
1948       not_suported |= 1U;
1949       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_DHCP for Station is not supported");
1950     }
1951   }
1952   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1953     if (drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1954       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP, NULL,   0U) == ARM_DRIVER_ERROR_PARAMETER);
1955       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP, NULL,   4U) == ARM_DRIVER_ERROR_PARAMETER);
1956       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 0U) == ARM_DRIVER_ERROR_PARAMETER);
1957       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 3U) == ARM_DRIVER_ERROR_PARAMETER);
1958       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 5U) == ARM_DRIVER_OK);
1959       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U) == ARM_DRIVER_OK);
1960       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U) == ARM_DRIVER_OK);
1961     } else {
1962       not_suported |= 2U;
1963       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_DHCP for Access Point is not supported");
1964     }
1965   }
1966 #endif
1967
1968 #if ((WIFI_SETGETOPTION_IP_DHCP_EN & 2) != 0)
1969   // Get tests
1970   len = 4U;
1971   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_IP_DHCP, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1972   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_IP_DHCP, data_buf,  &len) == ARM_DRIVER_ERROR_PARAMETER);
1973
1974   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
1975     len = 4U;
1976     if (drv->GetOption (0U, ARM_WIFI_IP_DHCP, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1977       len = 0U;
1978       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DHCP, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1979       len = 4U;
1980       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DHCP, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1981       len = 0U;
1982       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1983       len = 3U;
1984       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
1985       len = 5U;
1986       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_OK);
1987       len = 4U;
1988       TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_OK);
1989     } else {
1990       not_suported |= 1U;
1991       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_DHCP for Station is not supported");
1992     }
1993   }
1994   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
1995     len = 4U;
1996     if (drv->GetOption (1U, ARM_WIFI_IP_DHCP, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
1997       len = 0U;
1998       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
1999       len = 4U;
2000       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
2001       len = 0U;
2002       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2003       len = 3U;
2004       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2005       len = 5U;
2006       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_OK);
2007       len = 4U;
2008       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_OK);
2009     } else {
2010       not_suported |= 2U;
2011       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_DHCP for Access Point is not supported");
2012     }
2013   }
2014 #endif
2015
2016 #if ((WIFI_SETGETOPTION_IP_DHCP_EN & 3) == 3)
2017   // Check with Get that Set has written the correct values
2018   if (((cap.station_ap != 0) || (cap.station != 0)) && ((not_suported & 1U) == 0U)) {   // Station test
2019     len = 4U;
2020     memset((void *)data_buf, 0xCC, sizeof(data_buf));
2021     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_0,   4U)   == ARM_DRIVER_OK);
2022     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_OK);
2023     TEST_ASSERT(len == 4U);
2024     TEST_ASSERT(memcmp((const void *)&u32_0, (const void *)data_buf, (size_t)len) == 0);
2025     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP, &u32_1,   4U)   == ARM_DRIVER_OK);
2026     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_OK);
2027     TEST_ASSERT(len == 4U);
2028     TEST_ASSERT(memcmp((const void *)&u32_1, (const void *)data_buf, (size_t)len) == 0);
2029   }
2030   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
2031     len = 4U;
2032     memset((void *)data_buf, 0xCC, sizeof(data_buf));
2033     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0,   4U)   == ARM_DRIVER_OK);
2034     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_OK);
2035     TEST_ASSERT(len == 4U);
2036     TEST_ASSERT(memcmp((const void *)&u32_0, (const void *)data_buf, (size_t)len) == 0);
2037     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1,   4U)   == ARM_DRIVER_OK);
2038     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP, data_buf, &len) == ARM_DRIVER_OK);
2039     TEST_ASSERT(len == 4U);
2040     TEST_ASSERT(memcmp((const void *)&u32_1, (const void *)data_buf, (size_t)len) == 0);
2041   }
2042 #endif
2043 }
2044 #endif
2045
2046 #if (WIFI_SETGETOPTION_IP_DHCP_POOL_BEGIN_EN != 0)
2047 static void WIFI_SetOption_GetOption_IP_DHCP_POOL_BEGIN (void) {
2048 #if ((WIFI_SETGETOPTION_IP_DHCP_POOL_BEGIN_EN & 1) != 0)
2049   uint32_t u32_1, u32_0;
2050   uint8_t  ip[5] __ALIGNED(4);
2051 #endif
2052 #if ((WIFI_SETGETOPTION_IP_DHCP_POOL_BEGIN_EN & 2) != 0)
2053   uint32_t len;
2054 #endif
2055   uint8_t  not_suported;
2056
2057   not_suported = 0U;
2058
2059   if (init_and_power_on () == 0) {
2060     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2061     return;
2062   }
2063
2064 #if ((WIFI_SETGETOPTION_IP_DHCP_POOL_BEGIN_EN & 1) != 0)
2065   // Set tests
2066   memset((void *)ip, 0, 5);
2067   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_IP_DHCP_POOL_BEGIN, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
2068   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_IP_DHCP_POOL_BEGIN, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
2069
2070   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
2071     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP_POOL_BEGIN, ip, 4U) == ARM_DRIVER_ERROR_UNSUPPORTED);
2072   }
2073   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
2074     TEST_ASSERT(sscanf((const char *)WIFI_IP_DHCP_POOL_BEGIN_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
2075     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
2076     if (drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, ip, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
2077       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
2078       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
2079       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, ip,   0U) == ARM_DRIVER_ERROR_PARAMETER);
2080       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, ip,   3U) == ARM_DRIVER_ERROR_PARAMETER);
2081       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, ip,   5U) == ARM_DRIVER_OK);
2082       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, ip,   4U) == ARM_DRIVER_OK);
2083     } else {
2084       not_suported |= 2U;
2085       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_DHCP_POOL_BEGIN for Access Point is not supported");
2086     }
2087     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
2088   }
2089 #endif
2090
2091 #if ((WIFI_SETGETOPTION_IP_DHCP_POOL_BEGIN_EN & 2) != 0)
2092   // Get tests
2093   len = 4U;
2094   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_IP_DHCP_POOL_BEGIN, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2095   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_IP_DHCP_POOL_BEGIN, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2096
2097   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
2098     len = 4U;
2099     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DHCP_POOL_BEGIN, data_buf, &len) == ARM_DRIVER_ERROR_UNSUPPORTED);
2100   }
2101   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
2102     len = 4U;
2103     if (drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
2104       len = 0U;
2105       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
2106       len = 4U;
2107       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
2108       len = 0U;
2109       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2110       len = 3U;
2111       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2112       len = 5U;
2113       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, data_buf, &len) == ARM_DRIVER_OK);
2114       len = 4U;
2115       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, data_buf, &len) == ARM_DRIVER_OK);
2116     } else {
2117       not_suported |= 2U;
2118       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_DHCP_POOL_BEGIN for Access Point is not supported");
2119     }
2120   }
2121 #endif
2122
2123 #if ((WIFI_SETGETOPTION_IP_DHCP_POOL_BEGIN_EN & 3) == 3)
2124   // Check with Get that Set has written the correct values
2125   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
2126     TEST_ASSERT(sscanf((const char *)WIFI_IP_DHCP_POOL_BEGIN_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
2127     len = 4U;
2128     memset((void *)data_buf, 0xCC, sizeof(data_buf));
2129     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
2130     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, ip,       4U)   == ARM_DRIVER_OK);
2131     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_BEGIN, data_buf, &len) == ARM_DRIVER_OK);
2132     TEST_ASSERT(len == 4U);
2133     TEST_ASSERT(memcmp((const void *)ip, (const void *)data_buf, (size_t)len) == 0);
2134     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
2135   }
2136 #endif
2137 }
2138 #endif
2139
2140 #if (WIFI_SETGETOPTION_IP_DHCP_POOL_END_EN != 0)
2141 static void WIFI_SetOption_GetOption_IP_DHCP_POOL_END (void) {
2142 #if ((WIFI_SETGETOPTION_IP_DHCP_POOL_END_EN & 1) != 0)
2143   uint32_t u32_1, u32_0;
2144   uint8_t  ip[5] __ALIGNED(4);
2145 #endif
2146 #if ((WIFI_SETGETOPTION_IP_DHCP_POOL_END_EN & 2) != 0)
2147   uint32_t len;
2148 #endif
2149   uint8_t  not_suported;
2150
2151   not_suported = 0U;
2152
2153   if (init_and_power_on () == 0) {
2154     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2155     return;
2156   }
2157
2158 #if ((WIFI_SETGETOPTION_IP_DHCP_POOL_END_EN & 1) != 0)
2159   // Set tests
2160   memset((void *)ip, 0, 5);
2161   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_IP_DHCP_POOL_END, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
2162   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_IP_DHCP_POOL_END, ip, 4U) == ARM_DRIVER_ERROR_PARAMETER);
2163
2164   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
2165     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP_POOL_END, ip, 4U) == ARM_DRIVER_ERROR_UNSUPPORTED);
2166   }
2167   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
2168     TEST_ASSERT(sscanf((const char *)WIFI_IP_DHCP_POOL_END_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
2169     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);  // Turn DHCP off
2170     if (drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, ip, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
2171       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, NULL, 0U) == ARM_DRIVER_ERROR_PARAMETER);
2172       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, NULL, 4U) == ARM_DRIVER_ERROR_PARAMETER);
2173       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, ip,   0U) == ARM_DRIVER_ERROR_PARAMETER);
2174       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, ip,   3U) == ARM_DRIVER_ERROR_PARAMETER);
2175       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, ip,   5U) == ARM_DRIVER_OK);
2176       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, ip,   4U) == ARM_DRIVER_OK);
2177     } else {
2178       not_suported |= 2U;
2179       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_DHCP_POOL_END for Access Point is not supported");
2180     }
2181     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);  // Turn DHCP on
2182   }
2183 #endif
2184
2185 #if ((WIFI_SETGETOPTION_IP_DHCP_POOL_END_EN & 2) != 0)
2186   // Get tests
2187   len = 4U;
2188   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_IP_DHCP_POOL_END, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2189   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_IP_DHCP_POOL_END, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2190
2191   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
2192     len = 4U;
2193     TEST_ASSERT(drv->GetOption (0U, ARM_WIFI_IP_DHCP_POOL_END, data_buf, &len) == ARM_DRIVER_ERROR_UNSUPPORTED);
2194   }
2195   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
2196     len = 4U;
2197     if (drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
2198       len = 0U;
2199       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
2200       len = 4U;
2201       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
2202       len = 0U;
2203       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2204       len = 3U;
2205       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2206       len = 5U;
2207       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, data_buf, &len) == ARM_DRIVER_OK);
2208       len = 4U;
2209       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, data_buf, &len) == ARM_DRIVER_OK);
2210     } else {
2211       not_suported |= 2U;
2212       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_DHCP_POOL_END for Access Point is not supported");
2213     }
2214   }
2215 #endif
2216
2217 #if ((WIFI_SETGETOPTION_IP_DHCP_POOL_END_EN & 3) == 3)
2218   // Check with Get that Set has written the correct values
2219   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
2220     TEST_ASSERT(sscanf((const char *)WIFI_IP_DHCP_POOL_END_AP, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
2221     len = 4U;
2222     memset((void *)data_buf, 0xCC, sizeof(data_buf));
2223     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_0, 4U);          // Turn DHCP off
2224     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, ip,       4U)   == ARM_DRIVER_OK);
2225     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_POOL_END, data_buf, &len) == ARM_DRIVER_OK);
2226     TEST_ASSERT(len == 4U);
2227     TEST_ASSERT(memcmp((const void *)ip, (const void *)data_buf, (size_t)len) == 0);
2228     drv->SetOption (1U, ARM_WIFI_IP_DHCP, &u32_1, 4U);          // Turn DHCP on
2229   }
2230 #endif
2231 }
2232 #endif
2233
2234 #if (WIFI_SETGETOPTION_IP_DHCP_LEASE_TIME_EN != 0)
2235 static void WIFI_SetOption_GetOption_IP_DHCP_LEASE_TIME (void) {
2236 #if ((WIFI_SETGETOPTION_IP_DHCP_LEASE_TIME_EN & 1) != 0)
2237   uint32_t time;
2238 #endif
2239 #if ((WIFI_SETGETOPTION_IP_DHCP_LEASE_TIME_EN & 2) != 0)
2240   uint32_t len;
2241 #endif
2242   uint8_t  not_suported;
2243
2244   not_suported = 0U;
2245
2246   if (init_and_power_on () == 0) {
2247     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2248     return;
2249   }
2250
2251 #if ((WIFI_SETGETOPTION_IP_DHCP_LEASE_TIME_EN & 1) != 0)
2252   // Set tests
2253   time = WIFI_IP_DHCP_LEASE_TIME_AP;
2254   TEST_ASSERT(drv->SetOption (  2U, ARM_WIFI_IP_DHCP_LEASE_TIME, &time, 4U) == ARM_DRIVER_ERROR_PARAMETER);
2255   TEST_ASSERT(drv->SetOption (255U, ARM_WIFI_IP_DHCP_LEASE_TIME, &time, 4U) == ARM_DRIVER_ERROR_PARAMETER);
2256
2257   if (((cap.station_ap != 0) || (cap.station != 0))) {  // Station test
2258     TEST_ASSERT(drv->SetOption (0U, ARM_WIFI_IP_DHCP_LEASE_TIME, &time, 4U) == ARM_DRIVER_ERROR_UNSUPPORTED);
2259   }
2260   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
2261     time = WIFI_IP_DHCP_LEASE_TIME_AP;
2262     if (drv->SetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, &time, 4U) != ARM_DRIVER_ERROR_UNSUPPORTED) {
2263       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, NULL,  0U) == ARM_DRIVER_ERROR_PARAMETER);
2264       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, NULL,  4U) == ARM_DRIVER_ERROR_PARAMETER);
2265       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, &time, 0U) == ARM_DRIVER_ERROR_PARAMETER);
2266       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, &time, 3U) == ARM_DRIVER_ERROR_PARAMETER);
2267       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, &time, 5U) == ARM_DRIVER_OK);
2268       TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, &time, 4U) == ARM_DRIVER_OK);
2269     } else {
2270       not_suported |= 2U;
2271       TEST_MESSAGE("[WARNING] SetOption ARM_WIFI_IP_DHCP_LEASE_TIME for Access Point is not supported");
2272     }
2273   }
2274 #endif
2275
2276 #if ((WIFI_SETGETOPTION_IP_DHCP_LEASE_TIME_EN & 2) != 0)
2277   // Get tests
2278   len = 4U;
2279   TEST_ASSERT(drv->GetOption (  2U, ARM_WIFI_IP_DHCP_LEASE_TIME, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2280   TEST_ASSERT(drv->GetOption (255U, ARM_WIFI_IP_DHCP_LEASE_TIME, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2281
2282   if ((cap.station_ap != 0) || (cap.station != 0)) {    // Station test
2283     len = 4U;
2284     TEST_ASSERT  (drv->GetOption (0U, ARM_WIFI_IP_DHCP_LEASE_TIME, data_buf,  &len) == ARM_DRIVER_ERROR_UNSUPPORTED);
2285   }
2286   if ((cap.station_ap != 0) || (cap.ap != 0)) {         // AP test
2287     len = 4U;
2288     if (drv->GetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, data_buf,  &len) != ARM_DRIVER_ERROR_UNSUPPORTED) {
2289       len = 0U;
2290       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
2291       len = 4U;
2292       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, NULL,     &len) == ARM_DRIVER_ERROR_PARAMETER);
2293       len = 0U;
2294       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2295       len = 3U;
2296       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, data_buf, &len) == ARM_DRIVER_ERROR_PARAMETER);
2297       len = 5U;
2298       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, data_buf, &len) == ARM_DRIVER_OK);
2299       len = 4U;
2300       TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, data_buf, &len) == ARM_DRIVER_OK);
2301     } else {
2302       not_suported |= 2U;
2303       TEST_MESSAGE("[WARNING] GetOption ARM_WIFI_IP_DHCP_LEASE_TIME for Access Point is not supported");
2304     }
2305   }
2306 #endif
2307
2308 #if ((WIFI_SETGETOPTION_IP_DHCP_LEASE_TIME_EN & 3) == 3)
2309   // Check with Get that Set has written the correct values
2310   if (((cap.station_ap != 0) || (cap.ap != 0)) && ((not_suported & 2U) == 0U)) {        // AP test
2311     time = WIFI_IP_DHCP_LEASE_TIME_AP;
2312     len  = 4U;
2313     memset((void *)data_buf, 0xCC, sizeof(data_buf));
2314     TEST_ASSERT(drv->SetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, &time,    4U)   == ARM_DRIVER_OK);
2315     TEST_ASSERT(drv->GetOption (1U, ARM_WIFI_IP_DHCP_LEASE_TIME, data_buf, &len) == ARM_DRIVER_OK);
2316     TEST_ASSERT(len == 4U);
2317     TEST_ASSERT(memcmp((const void *)&time, (const void *)data_buf, (size_t)len) == 0);
2318   }
2319 #endif
2320 }
2321 #endif
2322
2323 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2324 /**
2325 \brief Function: WIFI_SetOption_GetOption
2326 \details
2327 The test function \b WIFI_SetOption_GetOption verifies the WiFi Driver \b SetOption and \b GetOption functions.
2328 (Options: ARM_WIFI_BSSID, ARM_WIFI_MAC, ARM_WIFI_IP, ARM_WIFI_IP_SUBNET_MASK, ARM_WIFI_IP_GATEWAY, ARM_WIFI_IP_DNS1,
2329 ARM_WIFI_IP_DNS2, ARM_WIFI_IP_DHCP_POOL_BEGIN, ARM_WIFI_IP_DHCP_POOL_END are checked with buffer not aligned to 4 bytes).<br>
2330 Tests for each option is conditionally executed depending on WIFI_SETGETOPTION_... settings in DV_WiFi_Config.h file.
2331 \code
2332   int32_t (*SetOption) (uint32_t interface, uint32_t option, const void *data, uint32_t len);
2333 \endcode
2334 and
2335 \code
2336   int32_t (*GetOption) (uint32_t interface, uint32_t option, void *data, uint32_t *len);
2337 \endcode
2338 Function \b WIFI_SetOption_GetOption_BSSID              tests \b ARM_WIFI_BSSID option.<br>
2339 Function \b WIFI_SetOption_GetOption_TX_POWER           tests \b ARM_WIFI_TX_POWER option.<br>
2340 Function \b WIFI_SetOption_GetOption_LP_TIMER           tests \b ARM_WIFI_LP_TIMER option.<br>
2341 Function \b WIFI_SetOption_GetOption_DTIM               tests \b ARM_WIFI_DTIM option.<br>
2342 Function \b WIFI_SetOption_GetOption_BEACON             tests \b ARM_WIFI_BEACON option.<br>
2343 Function \b WIFI_SetOption_GetOption_MAC                tests \b ARM_WIFI_MAC option.<br>
2344 Function \b WIFI_SetOption_GetOption_IP                 tests \b ARM_WIFI_IP option.<br>
2345 Function \b WIFI_SetOption_GetOption_IP_SUBNET_MASK     tests \b ARM_WIFI_IP_SUBNET_MASK option.<br>
2346 Function \b WIFI_SetOption_GetOption_IP_GATEWAY         tests \b ARM_WIFI_IP_GATEWAY option.<br>
2347 Function \b WIFI_SetOption_GetOption_IP_DNS1            tests \b ARM_WIFI_IP_DNS1 option.<br>
2348 Function \b WIFI_SetOption_GetOption_IP_DNS2            tests \b ARM_WIFI_IP_DNS2 option.<br>
2349 Function \b WIFI_SetOption_GetOption_IP_DHCP            tests \b ARM_WIFI_IP_DHCP option.<br>
2350 Function \b WIFI_SetOption_GetOption_IP_DHCP_POOL_BEGIN tests \b ARM_WIFI_IP_DHCP_POOL_BEGIN option.<br>
2351 Function \b WIFI_SetOption_GetOption_IP_DHCP_POOL_END   tests \b ARM_WIFI_IP_DHCP_POOL_END option.<br>
2352 Function \b WIFI_SetOption_GetOption_IP_DHCP_LEASE_TIME tests \b ARM_WIFI_IP_DHCP_LEASE_TIME option.
2353 */
2354 void WIFI_SetOption_GetOption (void) {
2355
2356 #if (WIFI_SETGETOPTION_BSSID_EN != 0)
2357   WIFI_SetOption_GetOption_BSSID ();
2358 #endif
2359 #if (WIFI_SETGETOPTION_TX_POWER_EN != 0)
2360   WIFI_SetOption_GetOption_TX_POWER ();
2361 #endif
2362 #if (WIFI_SETGETOPTION_LP_TIMER_EN != 0)
2363   WIFI_SetOption_GetOption_LP_TIMER ();
2364 #endif
2365 #if (WIFI_SETGETOPTION_DTIM_EN != 0)
2366   WIFI_SetOption_GetOption_DTIM ();
2367 #endif
2368 #if (WIFI_SETGETOPTION_BEACON_EN != 0)
2369   WIFI_SetOption_GetOption_BEACON ();
2370 #endif
2371 #if (WIFI_SETGETOPTION_MAC_EN != 0)
2372   WIFI_SetOption_GetOption_MAC ();
2373 #endif
2374 #if (WIFI_SETGETOPTION_IP_EN != 0)
2375   WIFI_SetOption_GetOption_IP ();
2376 #endif
2377 #if (WIFI_SETGETOPTION_IP_SUBNET_MASK_EN != 0)
2378   WIFI_SetOption_GetOption_IP_SUBNET_MASK ();
2379 #endif
2380 #if (WIFI_SETGETOPTION_IP_GATEWAY_EN != 0)
2381   WIFI_SetOption_GetOption_IP_GATEWAY ();
2382 #endif
2383 #if (WIFI_SETGETOPTION_IP_DNS1_EN != 0)
2384   WIFI_SetOption_GetOption_IP_DNS1 ();
2385 #endif
2386 #if (WIFI_SETGETOPTION_IP_DNS2_EN != 0)
2387   WIFI_SetOption_GetOption_IP_DNS2 ();
2388 #endif
2389 #if (WIFI_SETGETOPTION_IP_DHCP_EN != 0)
2390   WIFI_SetOption_GetOption_IP_DHCP ();
2391 #endif
2392 #if (WIFI_SETGETOPTION_IP_DHCP_POOL_BEGIN_EN != 0)
2393   WIFI_SetOption_GetOption_IP_DHCP_POOL_BEGIN ();
2394 #endif
2395 #if (WIFI_SETGETOPTION_IP_DHCP_POOL_END_EN != 0)
2396   WIFI_SetOption_GetOption_IP_DHCP_POOL_END ();
2397 #endif
2398 #if (WIFI_SETGETOPTION_IP_DHCP_LEASE_TIME_EN != 0)
2399   WIFI_SetOption_GetOption_IP_DHCP_LEASE_TIME ();
2400 #endif
2401 }
2402
2403 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2404 /**
2405 \brief Function: WIFI_Scan
2406 \details
2407 The test function \b WIFI_Scan verifies the WiFi Driver \b Scan function.
2408 \code
2409 int32_t (*Scan) (ARM_WIFI_SCAN_INFO_t scan_info[], uint32_t max_num);
2410 \endcode
2411 */
2412 void WIFI_Scan (void) {
2413   int32_t ret;
2414
2415   if (init_and_power_on () == 0) {
2416     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2417     return;
2418   }
2419
2420   TEST_ASSERT(drv->Scan(NULL,      WIFI_SCAN_MAX_NUM) == ARM_DRIVER_ERROR_PARAMETER);
2421   TEST_ASSERT(drv->Scan(scan_info, 0U)                == ARM_DRIVER_ERROR_PARAMETER);
2422
2423   memset((void *)scan_info, 0xCC, sizeof(scan_info));
2424   ret = drv->Scan(scan_info, 10U);
2425   if (ret == 0) {
2426     TEST_MESSAGE("[WARNING] Scan (..) found no networks");
2427   } else {
2428     TEST_ASSERT((ret > 0) && (ret <= WIFI_SCAN_MAX_NUM));
2429   }
2430 }
2431
2432 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2433 /**
2434 \brief Function: WIFI_Activate_Deactivate
2435 \details
2436 The test function \b WIFI_Activate_Deactivate verifies the WiFi Driver \b Activate and \b Deactivate functions.
2437 \code
2438 int32_t (*Activate) (uint32_t interface, const ARM_WIFI_CONFIG_t *config);
2439 \endcode
2440 and
2441 \code
2442 int32_t (*Deactivate) (uint32_t interface);
2443 \endcode
2444 Testing sequence (for Station and Access Point):
2445  - if not initialized and powered initialize and power on
2446  - Deactivate
2447  - Activate (with invalid parameters)
2448  - Activate (with valid parameters)
2449  - Deactivate
2450  - Activate (with invalid WPS parameters)
2451 */
2452 void WIFI_Activate_Deactivate (void) {
2453   int32_t ret;
2454
2455   if (init_and_power_on () == 0) {
2456     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2457     return;
2458   }
2459
2460   /* Test Station configuration setup */
2461   if ((cap.station != 0) || (cap.station_ap != 0)) {
2462
2463     TEST_ASSERT(drv->Deactivate (0U) == ARM_DRIVER_OK);
2464
2465     /* Test function with invalid parameters */
2466     TEST_ASSERT(drv->Activate(0U, NULL)    == ARM_DRIVER_ERROR_PARAMETER);
2467
2468     config.ssid       = NULL;
2469     config.pass       = NULL;
2470     config.security   = 0U;
2471     config.ch         = 0U;
2472     config.wps_method = 0U;
2473     config.wps_pin    = NULL;
2474     TEST_ASSERT(drv->Activate(0U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2475
2476     config.ssid       = WIFI_STA_SSID;
2477     config.pass       = NULL;
2478     config.security   = WIFI_STA_SECURITY;
2479     config.ch         = 0U;
2480     config.wps_method = 0U;
2481     config.wps_pin    = NULL;
2482     TEST_ASSERT(drv->Activate(0U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2483
2484     config.ssid       = WIFI_STA_SSID;
2485     config.pass       = WIFI_STA_PASS;
2486     config.security   = ARM_WIFI_SECURITY_UNKNOWN;
2487     config.ch         = WIFI_STA_CH;
2488     config.wps_method = 0U;
2489     config.wps_pin    = NULL;
2490     TEST_ASSERT(drv->Activate(0U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2491
2492     config.ssid       = WIFI_STA_SSID;
2493     config.pass       = WIFI_STA_PASS;
2494     config.security   = WIFI_STA_SECURITY;
2495     config.ch         = 255U;
2496     config.wps_method = 0U;
2497     config.wps_pin    = NULL;
2498     TEST_ASSERT(drv->Activate(0U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2499
2500     config.ssid       = WIFI_STA_SSID;
2501     config.pass       = WIFI_STA_PASS;
2502     config.security   = WIFI_STA_SECURITY;
2503     config.ch         = WIFI_STA_CH;
2504     config.wps_method = 0U;
2505     config.wps_pin    = NULL;
2506     TEST_ASSERT(drv->Activate(3U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2507
2508     /* Test function with autodetect channel, can return unsupported or succeed */
2509     config.ssid       = WIFI_STA_SSID;
2510     config.pass       = WIFI_STA_PASS;
2511     config.security   = WIFI_STA_SECURITY;
2512     config.ch         = 0U;
2513     config.wps_method = 0U;
2514     config.wps_pin    = NULL;
2515     ret = drv->Activate(0U, &config);
2516     if (ret == ARM_DRIVER_ERROR_UNSUPPORTED) {
2517       TEST_MESSAGE("[WARNING] Activate (0, ...) with autodetect channel not supported");
2518     } else {
2519       TEST_ASSERT(ret == ARM_DRIVER_OK);
2520     }
2521
2522     if (ret == ARM_DRIVER_OK) {
2523       TEST_ASSERT(drv->Deactivate (0U) == ARM_DRIVER_OK);
2524     }
2525
2526     /* Test function with valid parameters -> must succeed */
2527     config.ssid       = WIFI_STA_SSID;
2528     config.pass       = WIFI_STA_PASS;
2529     config.security   = WIFI_STA_SECURITY;
2530     config.ch         = WIFI_STA_CH;
2531     config.wps_method = 0U;
2532     config.wps_pin    = NULL;
2533     TEST_ASSERT(drv->Activate(0U, &config) == ARM_DRIVER_OK);
2534
2535     if (ret == ARM_DRIVER_OK) {
2536       TEST_ASSERT(drv->Deactivate (0U) == ARM_DRIVER_OK);
2537     }
2538
2539     if (cap.wps_station != 0U) {
2540       /* Test function with invalid WPS configurations */
2541       config.ssid       = WIFI_STA_SSID;
2542       config.pass       = WIFI_STA_PASS;
2543       config.security   = WIFI_STA_SECURITY;
2544       config.ch         = WIFI_STA_CH;
2545       config.wps_method = 255U;
2546       config.wps_pin    = NULL;
2547       TEST_ASSERT(drv->Activate(0U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2548
2549       config.ssid       = WIFI_STA_SSID;
2550       config.pass       = WIFI_STA_PASS;
2551       config.security   = WIFI_STA_SECURITY;
2552       config.ch         = WIFI_STA_CH;
2553       config.wps_method = ARM_WIFI_WPS_METHOD_PIN;
2554       config.wps_pin    = NULL;
2555       TEST_ASSERT(drv->Activate(0U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2556     }
2557   }
2558
2559   /* Test Access Point configuration setup */
2560   if ((cap.ap != 0) || (cap.station_ap != 0)) {
2561
2562     TEST_ASSERT(drv->Deactivate (1U) == ARM_DRIVER_OK);
2563
2564     /* Test function with invalid parameters */
2565     TEST_ASSERT(drv->Activate(1U, NULL)    == ARM_DRIVER_ERROR_PARAMETER);
2566
2567     config.ssid       = NULL;
2568     config.pass       = NULL;
2569     config.security   = 0U;
2570     config.ch         = 0U;
2571     config.wps_method = 0U;
2572     config.wps_pin    = NULL;
2573     TEST_ASSERT(drv->Activate(1U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2574
2575     config.ssid       = WIFI_STA_SSID;
2576     config.pass       = NULL;
2577     config.security   = WIFI_AP_SECURITY;
2578     config.ch         = 0U;
2579     config.wps_method = 0U;
2580     config.wps_pin    = NULL;
2581     TEST_ASSERT(drv->Activate(1U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2582
2583     config.ssid       = WIFI_AP_SSID;
2584     config.pass       = WIFI_AP_PASS;
2585     config.security   = ARM_WIFI_SECURITY_UNKNOWN;
2586     config.ch         = WIFI_AP_CH;
2587     config.wps_method = 0U;
2588     config.wps_pin    = NULL;
2589     TEST_ASSERT(drv->Activate(1U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2590
2591     config.ssid       = WIFI_AP_SSID;
2592     config.pass       = WIFI_AP_PASS;
2593     config.security   = WIFI_AP_SECURITY;
2594     config.ch         = 255U;
2595     config.wps_method = 0U;
2596     config.wps_pin    = NULL;
2597     TEST_ASSERT(drv->Activate(1U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2598
2599     config.ssid       = WIFI_AP_SSID;
2600     config.pass       = WIFI_AP_PASS;
2601     config.security   = WIFI_AP_SECURITY;
2602     config.ch         = WIFI_AP_CH;
2603     config.wps_method = 0U;
2604     config.wps_pin    = NULL;
2605     TEST_ASSERT(drv->Activate(3U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2606
2607     /* Test function with autodetect channel, can return unsupported or succeed */
2608     config.ssid       = WIFI_AP_SSID;
2609     config.pass       = WIFI_AP_PASS;
2610     config.security   = WIFI_AP_SECURITY;
2611     config.ch         = 0U;
2612     config.wps_method = 0U;
2613     config.wps_pin    = NULL;
2614     ret = drv->Activate(1U, &config);
2615     if (ret == ARM_DRIVER_ERROR_UNSUPPORTED) {
2616       TEST_MESSAGE("[WARNING] Activate (1, ...) with autodetect channel not supported");
2617     } else {
2618       TEST_ASSERT(ret == ARM_DRIVER_OK);
2619     }
2620
2621     if (ret == ARM_DRIVER_OK) {
2622       TEST_ASSERT(drv->Deactivate (1U) == ARM_DRIVER_OK);
2623     }
2624
2625     /* Test function with valid parameters -> must succeed */
2626     config.ssid       = WIFI_AP_SSID;
2627     config.pass       = WIFI_AP_PASS;
2628     config.security   = WIFI_AP_SECURITY;
2629     config.ch         = WIFI_AP_CH;
2630     config.wps_method = 0U;
2631     config.wps_pin    = NULL;
2632     TEST_ASSERT(drv->Activate(1U, &config) == ARM_DRIVER_OK);
2633
2634     if (ret == ARM_DRIVER_OK) {
2635       TEST_ASSERT(drv->Deactivate (1U) == ARM_DRIVER_OK);
2636     }
2637
2638     if (cap.wps_ap != 0U) {
2639       /* Test function with invalid WPS configurations */
2640       config.ssid       = WIFI_AP_SSID;
2641       config.pass       = WIFI_AP_PASS;
2642       config.security   = WIFI_AP_SECURITY;
2643       config.ch         = WIFI_AP_CH;
2644       config.wps_method = 255U;
2645       config.wps_pin    = NULL;
2646       TEST_ASSERT(drv->Activate(1U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2647
2648       config.ssid       = WIFI_AP_SSID;
2649       config.pass       = WIFI_AP_PASS;
2650       config.security   = WIFI_AP_SECURITY;
2651       config.ch         = WIFI_AP_CH;
2652       config.wps_method = ARM_WIFI_WPS_METHOD_PIN;
2653       config.wps_pin    = NULL;
2654       TEST_ASSERT(drv->Activate(1U, &config) == ARM_DRIVER_ERROR_PARAMETER);
2655     }
2656   }
2657 }
2658
2659 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2660 /**
2661 \brief Function: WIFI_IsConnected
2662 \details
2663 The test function \b WIFI_IsConnected verifies the WiFi Driver \b IsConnected function.
2664 \code
2665 uint32_t (*IsConnected) (void);
2666 \endcode
2667 */
2668 void WIFI_IsConnected (void) {
2669
2670   if (init_and_power_on () == 0) {
2671     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2672     return;
2673   }
2674
2675   TEST_ASSERT(drv->IsConnected () == 0U);
2676
2677   /* Test function with valid Station configuration */
2678   if ((cap.station != 0) || (cap.station_ap != 0)) {
2679     memset((void *)&config, 0, sizeof(config));
2680     config.ssid     = WIFI_STA_SSID;
2681     config.pass     = WIFI_STA_PASS;
2682     config.security = WIFI_STA_SECURITY;
2683     config.ch       = WIFI_STA_CH;
2684
2685     drv->Activate(0U, &config);
2686     TEST_ASSERT(drv->IsConnected () != 0U);
2687
2688     drv->Deactivate (0U);
2689     TEST_ASSERT(drv->IsConnected () == 0U);
2690   }
2691 }
2692
2693 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2694 /**
2695 \brief Function: WIFI_GetNetInfo
2696 \details
2697 The test function \b WIFI_GetNetInfo verifies the WiFi Driver \b GetNetInfo function.
2698 \code
2699 int32_t (*GetNetInfo) (ARM_WIFI_NET_INFO_t *net_info);
2700 \endcode
2701 */
2702 void WIFI_GetNetInfo (void) {
2703
2704   if (init_and_power_on () == 0) {
2705     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2706     return;
2707   }
2708
2709   /* Test function with invalid pointer */
2710   TEST_ASSERT(drv->GetNetInfo (NULL) == ARM_DRIVER_ERROR_PARAMETER);
2711
2712   /* Test function with valid Station configuration */
2713   if ((cap.station != 0) || (cap.station_ap != 0)) {
2714     memset((void *)&config, 0, sizeof(config));
2715     config.ssid     = WIFI_STA_SSID;
2716     config.pass     = WIFI_STA_PASS;
2717     config.security = WIFI_STA_SECURITY;
2718     config.ch       = WIFI_STA_CH;
2719
2720     drv->Activate(0U, &config);
2721
2722     memset((void *)&net_info, 0xCC, sizeof(net_info));
2723     TEST_ASSERT(drv->GetNetInfo (&net_info) == ARM_DRIVER_OK);
2724
2725     /* Check returned info */
2726     TEST_ASSERT(net_info.security == config.security);
2727     if (config.ch != 0U) {
2728       TEST_ASSERT(net_info.ch == config.ch);
2729     }
2730     TEST_ASSERT(net_info.rssi != 0U);
2731
2732     drv->Deactivate (0U);
2733   }
2734 }
2735
2736 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2737 /**
2738 \brief Function: WIFI_Activate_AP
2739 \details
2740 The test function \b WIFI_Activate_AP verifies the WiFi Driver \b Activate function AP operation.
2741 Test result is checked by connecting WiFi client to AP.
2742 */
2743 void WIFI_Activate_AP (void) {
2744   int32_t ret, tout;
2745
2746   if (init_and_power_on () == 0) {
2747     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2748     return;
2749   }
2750
2751   if ((cap.event_ap_connect != 0U) && (event_func != NULL)) {
2752     event = 0U;
2753   }
2754
2755   /* Test Access Point configuration setup */
2756   if ((cap.ap != 0) || (cap.station_ap != 0)) {
2757     memset((void *)&config, 0, sizeof(config));
2758     config.ssid     = WIFI_AP_SSID;
2759     config.pass     = WIFI_AP_PASS;
2760     config.security = WIFI_AP_SECURITY;
2761     config.ch       = WIFI_AP_CH;
2762     ret = drv->Activate(1U, &config);
2763     TEST_ASSERT(ret == ARM_DRIVER_OK);
2764
2765     if (ret == ARM_DRIVER_OK) {
2766       // Wait for WIFI_AP_CLIENT_CON_TIMEOUT in ms for client to connect
2767       // If event for connect is supported, loop will end when connect is detected
2768       // otherwise result of test is result of client connection status.
2769       for (tout = WIFI_AP_CLIENT_CON_TIMEOUT / 128; tout > 0; tout--) {
2770         osDelay(128U);
2771         if ((cap.event_ap_connect != 0U) && (event_func != NULL)) {
2772           if (event & ARM_WIFI_EVENT_AP_CONNECT) {
2773             break;
2774           }
2775         }
2776       }
2777     }
2778
2779     if ((cap.event_ap_connect != 0U) && (event_func != NULL)) {
2780       TEST_ASSERT((event & ARM_WIFI_EVENT_AP_CONNECT) != 0U);
2781       event = 0U;
2782     }
2783
2784     // Stop AP
2785     drv->Deactivate (1U);
2786   }
2787 }
2788
2789 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2790 /**
2791 \brief Function: WIFI_Activate_Station_WPS_PBC
2792 \details
2793 The test function \b WIFI_Activate_Station_WPS_PBC verifies the WiFi Driver \b Activate function Station connection with WPS 
2794 and Push-Button Configuration method.
2795 This test function requires that test Access Point has active Push-button WPS method when test is started.
2796 Usually started on the WiFi AP (router) by pressing the WPS button.
2797 */
2798 void WIFI_Activate_Station_WPS_PBC (void) {
2799   int32_t ret;
2800
2801   if (init_and_power_on () == 0) {
2802     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2803     return;
2804   }
2805
2806   /* Test Station WPS PBC connection */
2807   if ((cap.wps_station != 0U) && ((cap.station != 0) || (cap.station_ap != 0))) {
2808     memset((void *)&config, 0, sizeof(config));
2809
2810     /* Connect with valid WPS configuration - Push-Button Configuration method -> should succeed */
2811     config.wps_method = ARM_WIFI_WPS_METHOD_PBC;
2812     ret = drv->Activate(0U, &config);
2813     TEST_ASSERT(ret == ARM_DRIVER_OK);
2814
2815     if (ret == ARM_DRIVER_OK) {
2816       // Check connect information is as expected
2817       memset((void *)&net_info, 0xCC, sizeof(net_info));
2818       drv->GetNetInfo (&net_info);
2819
2820       TEST_ASSERT(memcmp((const void *)net_info.ssid, (const void *)WIFI_STA_SSID, sizeof(WIFI_STA_SSID)) == 0);
2821       TEST_ASSERT(memcmp((const void *)net_info.pass, (const void *)WIFI_STA_PASS, sizeof(WIFI_STA_PASS)) == 0);
2822       TEST_ASSERT(net_info.security == WIFI_STA_SECURITY);
2823       if (WIFI_STA_CH != 0) {
2824         TEST_ASSERT(net_info.ch == WIFI_STA_CH);
2825       }
2826
2827       // Disconnect
2828       drv->Deactivate (0U);
2829     }
2830   }
2831 }
2832
2833 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2834 /**
2835 \brief Function: WIFI_Activate_Station_WPS_PIN
2836 \details
2837 The test function \b WIFI_Activate_Station_WPS_PIN verifies the WiFi Driver \b Activate function Station connection with WPS 
2838 and PIN method.
2839 This test function requires that test Access Point has active PIN WPS method when test is started.
2840 Usually needs to be configured on the WiFi AP (router).
2841 */
2842 void WIFI_Activate_Station_WPS_PIN (void) {
2843   int32_t ret;
2844
2845   if (init_and_power_on () == 0) {
2846     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2847     return;
2848   }
2849
2850   /* Test Station WPS PIN connection */
2851   if ((cap.wps_station != 0U) && ((cap.station != 0) || (cap.station_ap != 0))) {
2852     memset((void *)&config, 0, sizeof(config));
2853
2854     /* Connect with valid WPS configuration - PIN method -> should succeed */
2855     config.wps_method = ARM_WIFI_WPS_METHOD_PIN;
2856     config.wps_pin    = WIFI_STA_WPS_PIN;
2857     ret = drv->Activate(0U, &config);
2858     TEST_ASSERT(ret == ARM_DRIVER_OK);
2859
2860     if (ret == ARM_DRIVER_OK) {
2861       // Check connect information is as expected
2862       memset((void *)&net_info, 0xCC, sizeof(net_info));
2863       drv->GetNetInfo (&net_info);
2864
2865       TEST_ASSERT(memcmp((const void *)net_info.ssid, (const void *)WIFI_STA_SSID, sizeof(WIFI_STA_SSID)) == 0);
2866       TEST_ASSERT(memcmp((const void *)net_info.pass, (const void *)WIFI_STA_PASS, sizeof(WIFI_STA_PASS)) == 0);
2867       TEST_ASSERT(net_info.security == WIFI_STA_SECURITY);
2868       if (WIFI_STA_CH != 0) {
2869         TEST_ASSERT(net_info.ch == WIFI_STA_CH);
2870       }
2871
2872       // Disconnect
2873       drv->Deactivate (0U);
2874     }
2875   }
2876 }
2877
2878 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2879 /**
2880 \brief Function: WIFI_Activate_AP_WPS_PBC
2881 \details
2882 The test function \b WIFI_Activate_AP_WPS_PBC verifies the WiFi Driver \b Activate function AP WPS 
2883 and Push-Button Configuration method functionality.
2884 Test result is checked by connecting the WiFi client to AP with WPS Push-Button Configuration method.
2885 */
2886 void WIFI_Activate_AP_WPS_PBC (void) {
2887   int32_t ret;
2888
2889   if (init_and_power_on () == 0) {
2890     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2891     return;
2892   }
2893
2894   /* Test AP WPS PBC */
2895   if ((cap.wps_ap != 0U) && ((cap.ap != 0) || (cap.station_ap != 0))) {
2896     memset((void *)&config, 0, sizeof(config));
2897     config.ssid     = WIFI_AP_SSID;
2898     config.pass     = WIFI_AP_PASS;
2899     config.security = WIFI_AP_SECURITY;
2900     config.ch       = WIFI_AP_CH;
2901
2902     /* Start AP with WPS configuration - Push-Button Configuration method -> should succeed */
2903     config.wps_method = ARM_WIFI_WPS_METHOD_PBC;
2904     ret = drv->Activate(1U, &config);
2905     TEST_ASSERT(ret == ARM_DRIVER_OK);
2906
2907     if (ret == ARM_DRIVER_OK) {
2908       // Wait predefined time for Client to connect
2909       osDelay(WIFI_AP_CLIENT_CON_TIMEOUT);
2910     }
2911
2912     // Stop AP
2913     drv->Deactivate (1U);
2914   }
2915 }
2916
2917 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2918 /**
2919 \brief Function: WIFI_Activate_AP_WPS_PIN
2920 \details
2921 The test function \b WIFI_Activate_AP_WPS_PIN verifies the WiFi Driver \b Activate function AP WPS 
2922 PIN method functionality.
2923 Test result is checked by connecting the WiFi client to AP with WPS PIN method.
2924 */
2925 void WIFI_Activate_AP_WPS_PIN (void) {
2926   int32_t ret;
2927
2928   if (init_and_power_on () == 0) {
2929     TEST_ASSERT_MESSAGE(0,"[FAILED] Driver initialization and power on failed");
2930     return;
2931   }
2932
2933   /* Test AP WPS PIN */
2934   if ((cap.wps_ap != 0U) && ((cap.ap != 0) || (cap.station_ap != 0))) {
2935     memset((void *)&config, 0, sizeof(config));
2936     config.ssid     = WIFI_AP_SSID;
2937     config.pass     = WIFI_AP_PASS;
2938     config.security = WIFI_AP_SECURITY;
2939     config.ch       = WIFI_AP_CH;
2940
2941     /* Start AP with WPS configuration - PIN method -> should succeed */
2942     config.wps_method = ARM_WIFI_WPS_METHOD_PIN;
2943     config.wps_pin    = WIFI_AP_WPS_PIN;
2944     ret = drv->Activate(1U, &config);
2945     TEST_ASSERT(ret == ARM_DRIVER_OK);
2946
2947     if (ret == ARM_DRIVER_OK) {
2948       // Wait predefined time for Client to connect
2949       osDelay(WIFI_AP_CLIENT_CON_TIMEOUT);
2950     }
2951
2952     // Stop AP
2953     drv->Deactivate (1U);
2954   }
2955 }
2956 /**
2957 @}
2958 */
2959 // End of wifi_mgmt
2960
2961 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2962 /* WiFi Socket tests */
2963 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2964
2965 /**
2966 \defgroup wifi_sock_api Socket API
2967 \ingroup wifi_tests
2968 \details 
2969 These tests verify API and operation of the WiFi socket functions.
2970 */
2971
2972 /* Helper function that initialize and connects to WiFi Access Point */
2973 static int32_t station_init (uint32_t con) {
2974
2975   if (cap.station == 0U) {
2976     return 0;
2977   }
2978
2979   if (powered == 0U) {
2980     if ((drv->Initialize   (event_func)     == ARM_DRIVER_OK) && 
2981         (drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK)) {
2982       powered = 1U;
2983     } else {
2984       return 0;
2985     }
2986   }
2987
2988   if (connected != con) {
2989     if (con != 0) {
2990       memset((void *)&config, 0, sizeof(config));
2991       config.ssid     = WIFI_STA_SSID;
2992       config.pass     = WIFI_STA_PASS;
2993       config.security = WIFI_STA_SECURITY;
2994       config.ch       = WIFI_STA_CH;
2995       if (drv->Activate(0U, &config) != ARM_DRIVER_OK) {
2996         return 0;
2997       }
2998     } else {
2999       if (drv->Deactivate(0U) != ARM_DRIVER_OK) {
3000         return 0;
3001       }
3002     }
3003
3004     connected = (uint8_t)con;
3005   }
3006
3007   return 1;
3008 }
3009
3010 /* Helper function that disconnects and uninitializes Station */
3011 static void station_uninit (void) {
3012
3013   drv->Deactivate (0U);
3014   connected = 0U;
3015
3016   drv->PowerControl (ARM_POWER_OFF);
3017   drv->Uninitialize ();
3018   powered = 0U;
3019 }
3020
3021 /* Helper function for execution of socket test function in the worker thread */
3022 static int32_t th_execute (osThreadId_t *id, uint32_t sig, uint32_t tout) {
3023   osThreadFlagsSet (id, sig);
3024   if (osThreadFlagsWait (TH_OK | TH_TOUT, osFlagsWaitAny, tout) == TH_OK) {
3025     /* Success, completed in time */
3026     return (1);
3027   }
3028   /* If function timeout expired prepare output message */
3029   snprintf(msg_buf, sizeof(msg_buf), "[FAILED] Execution timeout (%d ms)", tout);
3030   return (0);
3031 }
3032
3033 /* Helper function for preparing output message for TH_ASSERT2 macro */
3034 static void th_assert2_msg (const char *s1, int32_t r1, int32_t r2) {
3035   snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Non BSD-strict, %s (result %s, expected %s)", s1, str_sock_ret[-r1], str_sock_ret[-r2]);
3036 }
3037
3038 #define TH_EXECUTE(sig,tout) do {                                               \
3039                                io.xid++;                                        \
3040                                rval = th_execute (worker, sig, tout);           \
3041                                if (rval == 0) {                                 \
3042                                  /* Msg was prepared in th_execute function */  \
3043                                  TEST_ASSERT_MESSAGE(0,msg_buf);                \
3044                                }                                                \
3045                              } while (0)
3046
3047 #define TH_ASSERT(cond)      do {                                               \
3048                                if (rval) { TEST_ASSERT(cond); }                 \
3049                              } while (0)
3050
3051 #define TH_ASSERT2(c1,c2,s1,r1,r2) do {                                         \
3052                                if (rval) {                                      \
3053                                  if (!c2) { TEST_ASSERT(c1); }                  \
3054                                  else {                                         \
3055                                    th_assert2_msg(s1, r1, r2); /* Prep msg */   \
3056                                    TEST_MESSAGE(msg_buf);                       \
3057                                  }                                              \
3058                                }                                                \
3059                              } while (0)
3060
3061 #define ARG_INIT()           do {                                               \
3062                                io.owner = osThreadGetId ();                     \
3063                                io.xid   = 0;                                    \
3064                              } while (0)
3065
3066 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
3067
3068 /* Create IO parameters */
3069 #ifndef __DOXYGEN__                     // Exclude form the documentation
3070 typedef struct {
3071   int32_t      sock;
3072   int32_t      af;
3073   int32_t      type;
3074   int32_t      protocol;
3075   int32_t      rc;
3076   /* Control */
3077   osThreadId_t owner;
3078   uint32_t     xid;
3079 } IO_CREATE;
3080 #endif
3081
3082 /* Assign arguments */
3083 #define ARG_CREATE(_af,_type,_proto) do {                     \
3084                                        io.af       = _af;     \
3085                                        io.type     = _type;   \
3086                                        io.protocol = _proto;  \
3087                                      } while (0)
3088
3089 /* Create worker thread */
3090 __NO_RETURN static void Th_Create (IO_CREATE *io) {
3091   uint32_t flags, xid;
3092
3093   for (;;) {
3094     flags = osThreadFlagsWait (F_CREATE | F_CLOSE, osFlagsWaitAny, osWaitForever);
3095     xid   = io->xid;
3096     switch (flags) {
3097       case F_CREATE:
3098         /* Create socket */
3099         io->rc = drv->SocketCreate (io->af, io->type, io->protocol);
3100         break;
3101
3102       case F_CLOSE:
3103         /* Close socket */
3104         io->rc = drv->SocketClose (io->sock);
3105         break;
3106     }
3107     /* Done, send signal to owner thread */
3108     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
3109     osDelay(1);
3110     osThreadFlagsSet (io->owner, flags);
3111     osThreadFlagsClear (F_ALL);
3112   }
3113 }
3114
3115 /**
3116 \brief  Function: WIFI_SocketCreate
3117 \ingroup wifi_sock_api
3118 \details
3119 The test function \b WIFI_SocketCreate verifies the WiFi Driver \b SocketCreate function:
3120 \code
3121 int32_t (*SocketCreate) (int32_t af, int32_t type, int32_t protocol);
3122 \endcode
3123
3124 Create socket test:
3125  - Check function parameters 
3126  - Create multiple stream sockets
3127  - Gradually close stream sockets and create datagram sockets
3128  - Close datagram sockets
3129 */
3130 void WIFI_SocketCreate (void) { 
3131   osThreadId_t worker;
3132   int32_t      rval;
3133   IO_CREATE    io;
3134   int32_t      sock[WIFI_SOCKET_MAX_NUM], i;
3135
3136   if (socket_funcs_exist == 0U) {
3137     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
3138     return;
3139   }
3140
3141   if (station_init (1) == 0) {
3142     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
3143     return;
3144   }
3145
3146   /* Create worker thread */
3147   worker = osThreadNew ((osThreadFunc_t)Th_Create, &io, NULL);
3148   if (worker == NULL) {
3149     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
3150     return;
3151   }
3152
3153   ARG_INIT();
3154
3155   /* Check parameter (af = -1) */
3156   ARG_CREATE (-1, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3157   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3158   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3159
3160   /* Check parameter (af = INT32_MIN) */
3161   ARG_CREATE (INT32_MIN, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3162   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3163   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3164
3165   /* Check parameter (af = INT32_MAX) */
3166   ARG_CREATE (INT32_MAX, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3167   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3168   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3169
3170   /* Check parameter (type = -1) */
3171   ARG_CREATE (ARM_SOCKET_AF_INET, -1, ARM_SOCKET_IPPROTO_TCP);
3172   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3173   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3174
3175   /* Check parameter (type = INT32_MIN) */
3176   ARG_CREATE (ARM_SOCKET_AF_INET, INT32_MIN, ARM_SOCKET_IPPROTO_TCP);
3177   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3178   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3179
3180   /* Check parameter (type = INT32_MAX) */
3181   ARG_CREATE (ARM_SOCKET_AF_INET, INT32_MAX, ARM_SOCKET_IPPROTO_TCP);
3182   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3183   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3184
3185   /* Check parameter, stream socket (protocol = -1) */
3186   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, -1);
3187   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3188   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3189
3190   /* Check parameter, stream socket (protocol = INT32_MIN) */
3191   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, INT32_MIN);
3192   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3193   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3194
3195   /* Check parameter, stream socket (protocol = INT32_MAX) */
3196   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, INT32_MAX);
3197   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3198   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3199
3200   /* Check parameter, datagram socket (protocol = -1) */
3201   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, -1);
3202   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3203   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3204
3205   /* Check parameter, datagram socket (protocol = INT32_MIN) */
3206   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, INT32_MIN);
3207   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3208   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3209
3210   /* Check parameter, datagram socket (protocol = INT32_MAX) */
3211   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, INT32_MAX);
3212   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3213   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3214
3215   /* Check parameter, stream socket (protocol = ARM_SOCKET_IPPROTO_UDP) */
3216   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_UDP);
3217   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3218   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3219
3220   /* Check parameter, datagram socket (protocol = ARM_SOCKET_IPPROTO_TCP) */
3221   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_TCP);
3222   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3223   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3224
3225   /* Create multiple stream sockets */
3226   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3227   for (i = 0; i < WIFI_SOCKET_MAX_NUM; i++) {
3228     TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3229     TH_ASSERT  (io.rc >= 0);
3230     sock[i] = io.rc;
3231   }
3232   osDelay (10);
3233
3234   /* Gradually close stream sockets, create datagram sockets */
3235   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
3236   for (i = 0; i < WIFI_SOCKET_MAX_NUM; i++) {
3237     /* Close stream socket */
3238     io.sock = sock[i];
3239     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3240     TH_ASSERT  (io.rc == 0);
3241
3242     /* Create datagram socket */
3243     TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3244     TH_ASSERT  (io.rc >= 0);
3245     sock[i] = io.rc;
3246   }
3247   osDelay (10);
3248
3249   /* Close datagram sockets */
3250   for (i = 0; i < WIFI_SOCKET_MAX_NUM; i++) {
3251     io.sock = sock[i];
3252     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3253     TH_ASSERT  (io.rc == 0);
3254   }
3255   osDelay (10);
3256
3257   if (rval == 0) {
3258     station_uninit ();
3259   }
3260
3261   /* Terminate worker thread */
3262   osThreadTerminate (worker);
3263 }
3264
3265 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
3266
3267 /* Bind IO parameters */
3268 #ifndef __DOXYGEN__                     // Exclude form the documentation
3269 typedef struct {
3270   int32_t        sock;
3271   const uint8_t *ip;
3272   uint32_t       ip_len;
3273   uint16_t       port;
3274   uint16_t       reserved;
3275   int32_t        rc;
3276   /* Control */
3277   osThreadId_t   owner;
3278   uint32_t       xid;
3279 } IO_BIND;
3280 #endif
3281
3282 /* Assign arguments */
3283 #define ARG_BIND(_sock,_ip,_ip_len,_port) do {                   \
3284                                             io.sock   = _sock;   \
3285                                             io.ip     = _ip;     \
3286                                             io.ip_len = _ip_len; \
3287                                             io.port   = _port;   \
3288                                           } while (0)
3289
3290 /* Bind worker thread */
3291 __NO_RETURN static void Th_Bind (IO_BIND *io) {
3292   uint32_t flags,xid;
3293
3294   for (;;) {
3295     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_BIND | F_CLOSE, osFlagsWaitAny, osWaitForever);
3296     xid   = io->xid;
3297     switch (flags) {
3298       case F_CREATE_TCP:
3299         /* Create stream socket */
3300         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3301         break;
3302
3303       case F_CREATE_UDP:
3304         /* Create datagram socket */
3305         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
3306         break;
3307
3308       case F_BIND:
3309         /* Bind socket */
3310         io->rc = drv->SocketBind (io->sock, io->ip, io->ip_len, io->port);
3311         break;
3312
3313       case F_CLOSE:
3314         /* Close socket */
3315         io->rc = drv->SocketClose (io->sock);
3316         break;
3317     }
3318     /* Done, send signal to owner thread */
3319     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
3320     osDelay(1);
3321     osThreadFlagsSet (io->owner, flags);
3322     osThreadFlagsClear (F_ALL);
3323   }
3324 }
3325
3326 /**
3327 \brief  Function: WIFI_SocketBind
3328 \ingroup wifi_sock_api
3329 \details
3330 The test function \b WIFI_SocketBind verifies the WiFi Driver \b SocketBind function:
3331 \code
3332 int32_t (*SocketBind) (int32_t socket, const uint8_t *ip, uint32_t  ip_len, uint16_t  port);
3333 \endcode
3334
3335 Stream socket test:
3336  - Create stream socket
3337  - Check function parameters 
3338  - Bind stream socket
3339  - Bind socket second time
3340  - Create 2nd stream socket
3341  - Bind 2nd socket, used port
3342  - Bind 2nd socket, unused port
3343  - Close stream sockets
3344  - Bind closed socket
3345
3346 Datagram socket test: 
3347  - Create datagram socket
3348  - Bind datagram socket
3349  - Bind socket second time
3350  - Create 2nd datagram socket
3351  - Bind 2nd socket, used port
3352  - Bind 2nd socket, unused port
3353  - Close datagram socket
3354  - Bind closed socket
3355 */
3356 void WIFI_SocketBind (void) { 
3357   osThreadId_t worker;
3358   int32_t      rval;
3359   IO_BIND      io;
3360   int32_t      sock,sock2;
3361
3362   if (socket_funcs_exist == 0U) {
3363     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
3364     return;
3365   }
3366
3367   if (station_init (1) == 0) {
3368     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
3369     return;
3370   }
3371
3372   /* Create worker thread */
3373   worker = osThreadNew ((osThreadFunc_t)Th_Bind, &io, NULL);
3374   if (worker == NULL) {
3375     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
3376     return;
3377   }
3378
3379   ARG_INIT();
3380
3381   /* Create stream socket */
3382   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
3383   if (io.rc < 0) {
3384     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
3385   } else {
3386     sock = io.rc;
3387
3388     /* Check parameter (socket = -1) */
3389     ARG_BIND   (-1, ip_unspec, 4, DISCARD_PORT);
3390     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3391     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3392
3393     /* Check parameter (socket = INT32_MIN) */
3394     ARG_BIND (INT32_MIN, ip_unspec, 4, DISCARD_PORT);
3395     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3396     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3397
3398     /* Check parameter (socket = INT32_MAX) */
3399     ARG_BIND (INT32_MAX, ip_unspec, 4, DISCARD_PORT);
3400     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3401     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3402
3403     /* Check parameter (ip = NULL) */
3404     ARG_BIND (sock, NULL, 4, DISCARD_PORT);
3405     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3406     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3407
3408     /* Check parameter (ip_len = 0) */
3409     ARG_BIND (sock, ip_unspec, 0, DISCARD_PORT);
3410     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3411     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3412
3413     /* Check parameter (ip_len = UINT32_MAX) */
3414     ARG_BIND (sock, ip_unspec, UINT32_MAX, DISCARD_PORT);
3415     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3416     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3417
3418     /* Check parameter (port = 0) */
3419     ARG_BIND (sock, ip_unspec, 4, 0);
3420     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3421     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3422
3423     /* Bind socket */
3424     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3425     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3426     TH_ASSERT  (io.rc == 0);
3427
3428     /* Bind socket 2nd time */
3429     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3430     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3431     /* Should return error (socket already bound) */
3432     /* Strict: EINVAL, valid non-strict: OK, ERROR */
3433     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), ((io.rc == 0) || (io.rc == ARM_SOCKET_ERROR)), "bind socket to same address again", io.rc, ARM_SOCKET_EINVAL);
3434
3435     /* Create 2nd stream socket */
3436     TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
3437     if (io.rc < 0) {
3438       TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
3439     }
3440     sock2 = io.rc;
3441
3442     /* Bind 2nd socket, used port */
3443     ARG_BIND (sock2, ip_unspec, 4, DISCARD_PORT);
3444     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3445     /* Should return error (address already used) */
3446     /* Strict: EADDRINUSE, valid non-strict: ERROR */
3447     TH_ASSERT2 ((io.rc == ARM_SOCKET_EADDRINUSE), (io.rc == ARM_SOCKET_ERROR), "bind another socket to used address", io.rc, ARM_SOCKET_EADDRINUSE);
3448
3449     /* Bind 2nd socket, unused port */
3450     ARG_BIND (sock2, ip_unspec, 4, ECHO_PORT);
3451     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3452     TH_ASSERT  (io.rc == 0);
3453
3454     /* Close sockets */
3455     io.sock = sock2;
3456     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3457     TH_ASSERT  (io.rc == 0);
3458
3459     io.sock = sock;
3460     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3461     TH_ASSERT  (io.rc == 0);
3462
3463     /* Bind again, closed socket */
3464     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3465     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3466     /* Should return error (socket not created) */
3467     /* Strict: ESOCK, valid non-strict: ERROR */
3468     /* Return code strict: ESOCK, non-strict: ERROR */
3469     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "bind on closed socket", io.rc, ARM_SOCKET_ESOCK);
3470
3471     osDelay (10);
3472   }
3473
3474   /* Create datagram socket */
3475   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
3476   if (io.rc < 0) {
3477     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
3478   } else {
3479     sock = io.rc;
3480
3481     /* Check parameter (socket = -1) */
3482     ARG_BIND (-1, ip_unspec, 4, DISCARD_PORT);
3483     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3484     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3485
3486     /* Check parameter (socket = INT32_MIN) */
3487     ARG_BIND (INT32_MIN, ip_unspec, 4, DISCARD_PORT);
3488     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3489     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3490
3491     /* Check parameter (socket = INT32_MAX) */
3492     ARG_BIND (INT32_MAX, ip_unspec, 4, DISCARD_PORT);
3493     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3494     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3495
3496     /* Check parameter (ip = NULL) */
3497     ARG_BIND (sock, NULL, 4, DISCARD_PORT);
3498     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3499     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3500
3501     /* Check parameter (ip_len = 0) */
3502     ARG_BIND (sock, ip_unspec, 0, DISCARD_PORT);
3503     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3504     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3505
3506     /* Check parameter (ip_len = UINT32_MAX) */
3507     ARG_BIND (sock, ip_unspec, UINT32_MAX, DISCARD_PORT);
3508     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3509     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3510
3511     /* Check parameter (port = 0) */
3512     ARG_BIND (sock, ip_unspec, 4, 0);
3513     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3514     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3515
3516     /* Bind socket */
3517     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3518     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3519     TH_ASSERT  (io.rc == 0);
3520
3521     /* Bind socket 2nd time */
3522     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3523     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3524     /* Should return error (socket already bound) */
3525     /* Strict: EINVAL, valid non-strict: OK, ERROR */
3526     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), ((io.rc == 0) || (io.rc == ARM_SOCKET_ERROR)), "bind socket to same address again", io.rc, ARM_SOCKET_EINVAL);
3527
3528     /* Create 2nd datagram socket */
3529     TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
3530     if (io.rc < 0) {
3531       TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
3532     }
3533     sock2 = io.rc;
3534
3535     /* Bind 2nd socket, used port */
3536     ARG_BIND (sock2, ip_unspec, 4, DISCARD_PORT);
3537     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3538     /* Should return error (address already used) */
3539     /* Strict: EADDRINUSE, valid non-strict: ERROR */
3540     TH_ASSERT2 ((io.rc == ARM_SOCKET_EADDRINUSE), (io.rc == ARM_SOCKET_ERROR), "bind another socket to used address", io.rc, ARM_SOCKET_EADDRINUSE);
3541
3542     /* Bind 2nd socket, unused port */
3543     ARG_BIND (sock2, ip_unspec, 4, ECHO_PORT);
3544     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3545     TH_ASSERT  (io.rc == 0);
3546
3547     /* Close sockets */
3548     io.sock = sock2;
3549     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3550     TH_ASSERT  (io.rc == 0);
3551
3552     io.sock = sock;
3553     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3554     TH_ASSERT  (io.rc == 0);
3555
3556     /* Bind again, closed socket */
3557     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3558     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3559     /* Should return error (socket not created) */
3560     /* Strict: ESOCK, valid non-strict: ERROR */
3561     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "bind on closed socket", io.rc, ARM_SOCKET_ESOCK);
3562
3563     osDelay (10);
3564   }
3565
3566   if (rval == 0) {
3567     station_uninit ();
3568   }
3569
3570   /* Terminate worker thread */
3571   osThreadTerminate (worker);
3572 }
3573
3574 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
3575
3576 /* Listen IO parameters */
3577 #ifndef __DOXYGEN__                     // Exclude form the documentation
3578 typedef struct {
3579   int32_t      sock;
3580   int32_t      backlog;
3581   int32_t      rc;
3582   /* Control */
3583   osThreadId_t owner;
3584   uint32_t     xid;
3585 } IO_LISTEN;
3586 #endif
3587
3588 /* Assign arguments */
3589 #define ARG_LISTEN(_sock,_backlog) do {                     \
3590                                      io.sock    = _sock;    \
3591                                      io.backlog = _backlog; \
3592                                    } while (0)
3593
3594 /* Listen worker thread */
3595 __NO_RETURN static void Th_Listen (IO_LISTEN *io) {
3596   uint32_t flags,xid;
3597
3598   for (;;) {
3599     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP |
3600                                F_BIND       | F_LISTEN     | F_CLOSE, osFlagsWaitAny, osWaitForever);
3601     xid   = io->xid;
3602     switch (flags) {
3603       case F_CREATE_TCP:
3604         /* Create stream socket */
3605         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3606         break;
3607
3608       case F_CREATE_UDP:
3609         /* Create datagram socket */
3610         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
3611         break;
3612
3613       case F_BIND:
3614         /* Bind socket */
3615         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
3616         break;
3617
3618       case F_LISTEN:
3619         /* Listen on socket */
3620         io->rc = drv->SocketListen (io->sock, io->backlog);
3621         break;
3622
3623       case F_CLOSE:
3624         /* Close socket */
3625         io->rc = drv->SocketClose (io->sock);
3626         break;
3627     }
3628     /* Done, send signal to owner thread */
3629     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
3630     osDelay(1);
3631     osThreadFlagsSet (io->owner, flags);
3632     osThreadFlagsClear (F_ALL);
3633   }
3634 }
3635
3636 /**
3637 \brief  Function: WIFI_SocketListen
3638 \ingroup wifi_sock_api
3639 \details
3640 The test function \b WIFI_SocketListen verifies the WiFi Driver \b SocketListen function:
3641 \code
3642 int32_t (*SocketListen) (int32_t socket, int32_t backlog);
3643 \endcode
3644
3645 Stream socket test 1:
3646  - Create stream socket
3647  - Bind socket
3648  - Check function parameters 
3649  - Start listening
3650  - Start listening 2nd time
3651  - Close socket
3652
3653 Stream socket test 2:
3654  - Create stream socket
3655  - Start listening, unbound socket
3656  - Close socket
3657  - Start listening, closed socket
3658
3659 Datagram socket test:
3660  - Create datagram socket
3661  - Bind socket
3662  - Start listening
3663  - Close socket
3664 */
3665 void WIFI_SocketListen (void) { 
3666   osThreadId_t worker;
3667   int32_t      rval;
3668   IO_LISTEN    io;
3669   int32_t      sock;
3670
3671   if (socket_funcs_exist == 0U) {
3672     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
3673     return;
3674   }
3675
3676   if (station_init (1) == 0) {
3677     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
3678     return;
3679   }
3680
3681   /* Create worker thread */
3682   worker = osThreadNew ((osThreadFunc_t)Th_Listen, &io, NULL);
3683   if (worker == NULL) {
3684     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
3685     return;
3686   }
3687
3688   ARG_INIT();
3689
3690   /* Create stream socket */
3691   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
3692   if (io.rc < 0) {
3693     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
3694   } else {
3695     sock = io.rc;
3696
3697     /* Bind socket */
3698     io.sock = sock;
3699     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3700     TH_ASSERT  (io.rc == 0);
3701
3702     /* Check parameter (socket = -1) */
3703     ARG_LISTEN (-1, 1);
3704     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3705     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3706
3707     /* Check parameter (socket = INT32_MIN) */
3708     ARG_LISTEN (INT32_MIN, 1);
3709     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3710     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3711
3712     /* Check parameter (socket = INT32_MAX) */
3713     ARG_LISTEN (INT32_MAX, 1);
3714     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3715     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3716
3717     /* Start listening */
3718     ARG_LISTEN (sock, 1);
3719     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3720     TH_ASSERT  (io.rc == 0);
3721
3722     /* Start listening 2nd time */
3723     ARG_LISTEN (sock, 1);
3724     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3725     /* Should return error (socket already listening) */
3726     /* Strict: EINVAL, valid non-strict: OK, ERROR */
3727     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), ((io.rc == 0) || (io.rc == ARM_SOCKET_ERROR)), "listen on already listening socket", io.rc, ARM_SOCKET_EINVAL);
3728
3729     /* Close socket */
3730     io.sock = sock;
3731     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3732     TH_ASSERT  (io.rc == 0);
3733
3734     osDelay (10);
3735   }
3736
3737   /* Create stream socket */
3738   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
3739   if (io.rc < 0) {
3740     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
3741   } else {
3742     sock = io.rc;
3743
3744     /* Start listening, unbound socket */
3745     ARG_LISTEN (sock, 1);
3746     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3747     /* Should return error (socket not bound) */
3748     /* Strict: EINVAL, valid non-strict: ERROR */
3749     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "listen on unbound socket", io.rc, ARM_SOCKET_EINVAL);
3750
3751     /* Close socket */
3752     io.sock = sock;
3753     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3754     TH_ASSERT  (io.rc == 0);
3755
3756     /* Start listening, closed socket */
3757     ARG_LISTEN (sock, 1);
3758     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3759     /* Should return error (socket not created) */
3760     /* Strict: ESOCK, valid non-strict: ERROR */
3761     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "listen on closed socket", io.rc, ARM_SOCKET_ESOCK);
3762
3763     osDelay (10);
3764   }
3765
3766   /* Create datagram socket */
3767   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
3768   if (io.rc < 0) {
3769     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
3770   } else {
3771     sock = io.rc;
3772
3773     /* Bind socket */
3774     io.sock = sock;
3775     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3776     TH_ASSERT  (io.rc == 0);
3777
3778     /* Start listening */
3779     ARG_LISTEN (sock, 1);
3780     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3781     /* Should return error (operation not supported) */
3782     /* Strict: ENOTSUP, valid non-strict: ERROR */
3783     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTSUP), (io.rc == ARM_SOCKET_ERROR), "listen on datagram socket", io.rc, ARM_SOCKET_ENOTSUP);
3784
3785     /* Close socket */
3786     io.sock = sock;
3787     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3788     TH_ASSERT  (io.rc == 0);
3789
3790     osDelay (10);
3791   }
3792
3793   if (rval == 0) {
3794     station_uninit ();
3795   }
3796
3797   /* Terminate worker thread */
3798   osThreadTerminate (worker);
3799 }
3800
3801 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
3802
3803 /* Accept IO parameters */
3804 #ifndef __DOXYGEN__                     // Exclude form the documentation
3805 typedef struct {
3806   int32_t      sock;
3807   uint8_t     *ip;
3808   uint32_t    *ip_len;
3809   uint16_t    *port;
3810   int32_t      rc;
3811   /* Control */
3812   osThreadId_t owner;
3813   uint32_t     xid;
3814   const char  *cmd;
3815 } IO_ACCEPT;
3816 #endif
3817
3818 /* Assign arguments */
3819 #define ARG_ACCEPT(_sock,_ip,_ip_len,_port) do {                   \
3820                                               io.sock   = _sock;   \
3821                                               io.ip     = _ip;     \
3822                                               io.ip_len = _ip_len; \
3823                                               io.port   = _port;   \
3824                                             } while (0)
3825
3826 /* TestAssistant control */
3827 #define TEST_PORT           2000
3828
3829 /* CONNECT <proto>,<ip_addr>,<port>,<delay_ms>
3830            <proto>    = protocol (TCP, UDP)
3831            <ip_addr>  = IP address (0.0.0.0 = sender address)
3832            <port>     = port number
3833            <delay_ms> = startup delay
3834
3835   Example: CONNECT TCP,192.168.1.200,80,600
3836   (wait 600ms then connect to 192.168.1.200, port 80)
3837 */
3838 #define CMD_CONNECT_TCP     "CONNECT TCP,0.0.0.0,2000,500"
3839 #define CMD_CONNECT_UDP     "CONNECT UDP,0.0.0.0,2000,200"
3840
3841 /* Accept worker thread */
3842 __NO_RETURN static void Th_Accept (IO_ACCEPT *io) {
3843   uint32_t flags,xid;
3844   int32_t sock;
3845
3846   for (;;) {
3847     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_BIND | F_LISTEN |
3848                                F_ACCEPT     | F_SEND_CTRL  | F_RECV | F_CLOSE, osFlagsWaitAny, osWaitForever);
3849     xid   = io->xid;
3850     switch (flags) {
3851       case F_CREATE_TCP:
3852         /* Create stream socket */
3853         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3854         break;
3855
3856       case F_CREATE_UDP:
3857         /* Create datagram socket */
3858         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
3859         break;
3860
3861       case F_BIND:
3862         /* Bind socket */
3863         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, TEST_PORT);
3864         break;
3865
3866       case F_LISTEN:
3867         /* Listen on socket */
3868         io->rc = drv->SocketListen (io->sock, 1);
3869         break;
3870
3871       case F_ACCEPT:
3872         /* Accept on socket */
3873         io->rc = drv->SocketAccept (io->sock, io->ip, io->ip_len, io->port);
3874         break;
3875
3876       case F_RECV:
3877         /* Recv on socket (stream, datagram) */
3878         memset((void *)buffer, 0xCC, 16);
3879         io->rc = drv->SocketRecv (io->sock, buffer, 16);
3880         if ((io->rc > 0) && (memcmp ((const void *)buffer, (const void *)"SockServer", 10) != 0)) {
3881           /* Failed if rc <= 0 */
3882           io->rc = 0;
3883         }
3884         break;
3885
3886       case F_CLOSE:
3887         /* Close socket */
3888         io->rc = drv->SocketClose (io->sock);
3889         break;
3890
3891       case F_SEND_CTRL:
3892         /* Send control command to TestAssistant */
3893         sock = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3894         drv->SocketConnect (sock, ip_socket_server, 4, ASSISTANT_PORT);
3895         io->rc = drv->SocketSend (sock, io->cmd, strlen(io->cmd));
3896         drv->SocketClose (sock);
3897         osDelay (10);
3898         break;
3899     }
3900     /* Done, send signal to owner thread */
3901     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
3902     osDelay(1);
3903     osThreadFlagsSet (io->owner, flags);
3904     osThreadFlagsClear (F_ALL);
3905   }
3906 }
3907
3908 /**
3909 \brief  Function: WIFI_SocketAccept
3910 \ingroup wifi_sock_api
3911 \details
3912 The test function \b WIFI_SocketAccept verifies the WiFi Driver \b SocketAccept function:
3913 \code
3914 int32_t (*SocketAccept) (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t *port);
3915 \endcode
3916
3917 Stream socket test:
3918  - Create stream socket
3919  - Bind socket
3920  - Start listening
3921  - Check function parameters 
3922  - Accept connection, NULL parameters
3923  - Receive ServerId on accepted socket
3924  - Close accepted socket
3925  - Accept connection again, return IP address and port
3926  - Receive ServerId on accepted socket
3927  - Receive again, server closed connection
3928  - Close accepted socket
3929  - Close listening socket
3930  - Accept again, closed socket
3931
3932 Datagram socket test:
3933  - Create datagram socket
3934  - Bind socket
3935  - Start listening
3936  - Accept connection, provide return parameters for IP address and port
3937  - Receive ServerId on socket
3938  - Close socket
3939 */
3940 void WIFI_SocketAccept (void) {
3941   uint8_t      ip[5];
3942   uint32_t     ip_len;
3943   uint16_t     port;
3944   osThreadId_t worker;
3945   int32_t      rval;
3946   IO_ACCEPT    io;
3947   int32_t      sock;
3948
3949   if (socket_funcs_exist == 0U) {
3950     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
3951     return;
3952   }
3953
3954   if (station_init (1) == 0) {
3955     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
3956     return;
3957   }
3958
3959   /* Create worker thread */
3960   worker = osThreadNew ((osThreadFunc_t)Th_Accept, &io, NULL);
3961   if (worker == NULL) {
3962     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
3963     return;
3964   }
3965
3966   ARG_INIT();
3967
3968   /* Create stream socket */
3969   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
3970   if (io.rc < 0) {
3971     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
3972   } else {
3973     sock = io.rc;
3974
3975     /* Bind socket */
3976     io.sock = sock;
3977     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3978     TH_ASSERT  (io.rc == 0);
3979
3980     /* Start listening */
3981     io.sock = sock;
3982     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3983     TH_ASSERT  (io.rc == 0);
3984
3985     /* Check parameter (socket = -1) */
3986     ip_len = sizeof(ip);
3987     ARG_ACCEPT (-1, ip, &ip_len, &port);
3988     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
3989     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3990
3991     /* Check parameter (socket = INT32_MIN) */
3992     ARG_ACCEPT (INT32_MIN, ip, &ip_len, &port);
3993     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
3994     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3995
3996     /* Check parameter (socket = INT32_MAX) */
3997     ARG_ACCEPT (INT32_MAX, ip, &ip_len, &port);
3998     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
3999     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4000
4001     /* Parameters 'ip', 'ip_len' and 'port' are optional, can be NULL */
4002
4003     /* Request a remote server to connect to us */
4004     io.cmd = CMD_CONNECT_TCP;
4005     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
4006     TH_ASSERT  (io.rc > 0);
4007
4008     /* Accept connection with NULL parameters */
4009     ARG_ACCEPT (sock, NULL, NULL, NULL);
4010     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT_LONG);
4011     /* Accepted socket should be different */
4012     TH_ASSERT  ((io.rc != io.sock) && (io.rc >= 0));
4013
4014     /* Receive SockServer id string */
4015     io.sock = io.rc;
4016     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
4017     TH_ASSERT (io.rc > 0);
4018
4019     /* Close accepted socket */
4020     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4021     TH_ASSERT  (io.rc == 0);
4022
4023     osDelay (500);
4024
4025     /* Request from remote server to connect to us */
4026     io.cmd = CMD_CONNECT_TCP;
4027     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
4028     TH_ASSERT  (io.rc > 0);
4029
4030     /* Initialize buffers for return values */
4031     port   = 0;
4032     ip_len = sizeof(ip) + 1;
4033     memset ((void *)ip, 0, sizeof(ip));
4034
4035     /* Accept again, return ip address and port */
4036     ARG_ACCEPT (sock, &ip[0], &ip_len, &port);
4037     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT_LONG);
4038     /* Accepted socket should be different */
4039     TH_ASSERT  ((io.rc != io.sock) && (io.rc >= 0));
4040     /* IP address should be the address of the server */
4041     TH_ASSERT  ((memcmp ((const void *)ip, (const void *)ip_socket_server, 4) == 0) && (ip_len == 4));
4042     /* Port number of remote peer should be non-zero */
4043     TH_ASSERT  (port != 0);
4044
4045     /* Receive SockServer id string */
4046     io.sock = io.rc;
4047     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
4048     TH_ASSERT (io.rc > 0);
4049
4050     /* SockServer disconnects after 500ms */
4051
4052     /* Receive again, no data */
4053     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
4054     /* Should return error (connection reset) */
4055     /* Strict: ECONNRESET, valid non-strict: ERROR */
4056     TH_ASSERT2 ((io.rc == ARM_SOCKET_ECONNRESET), (io.rc == ARM_SOCKET_ERROR), "receive on disconnected socket", io.rc, ARM_SOCKET_ECONNRESET);
4057
4058     /* Close accepted socket */
4059     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4060     TH_ASSERT  (io.rc == 0);
4061
4062     /* Close listening socket */
4063     io.sock = sock;
4064     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4065     TH_ASSERT  (io.rc == 0);
4066
4067     /* Accept again, closed socket */
4068     ip_len = 4;
4069     ARG_ACCEPT (sock, &ip[0], &ip_len, &port);
4070     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
4071     /* Should return error (socket not created) */
4072     /* Strict: ESOCK, valid non-strict: ERROR */
4073     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "accept on closed socket", io.rc, ARM_SOCKET_ESOCK);
4074
4075     osDelay (10);
4076   }
4077
4078   /* Create datagram socket */
4079   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
4080   if (io.rc < 0) {
4081     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
4082   } else {
4083     sock = io.rc;
4084
4085     /* Bind socket */
4086     io.sock = sock;
4087     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4088     TH_ASSERT  (io.rc == 0);
4089
4090     /* Start listening */
4091     io.sock = sock;
4092     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
4093     /* Listen on datagram socket should fail */
4094     /* Strict: ENOTSUP, valid non-strict: ERROR */
4095     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTSUP), (io.rc == ARM_SOCKET_ERROR), "listen on datagram socket", io.rc, ARM_SOCKET_ENOTSUP);
4096
4097     /* Initialize buffers for return values */
4098     port   = 0;
4099     ip_len = sizeof(ip);
4100     memset ((void *)ip, 0, sizeof(ip));
4101
4102     /* Accept on datagram socket */
4103     ARG_ACCEPT (sock, &ip[0], &ip_len, &port);
4104     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
4105     /* Accept on datagram socket should fail */
4106     /* Strict: ENOTSUP, valid non-strict: ERROR */
4107     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTSUP), (io.rc == ARM_SOCKET_ERROR), "accept on datagram socket", io.rc, ARM_SOCKET_ENOTSUP);
4108
4109     osDelay (500);
4110
4111     /* Request from remote server to send us a test message */
4112     io.cmd = CMD_CONNECT_UDP;
4113     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
4114     TH_ASSERT  (io.rc > 0);
4115
4116     /* Receive SockServer id string */
4117     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
4118     TH_ASSERT  (io.rc > 0);
4119
4120     /* Close socket */
4121     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4122     TH_ASSERT  (io.rc == 0);
4123
4124     osDelay (10);
4125   }
4126
4127   if (rval == 0) {
4128     station_uninit ();
4129   }
4130
4131   /* Terminate worker thread */
4132   osThreadTerminate (worker);
4133 }
4134
4135 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
4136
4137 /* Connect IO parameters */
4138 #ifndef __DOXYGEN__                     // Exclude form the documentation
4139 typedef struct {
4140   int32_t        sock;
4141   const uint8_t *ip;
4142   uint32_t       ip_len;
4143   uint16_t       port;
4144   uint16_t       reserved;
4145   int32_t        rc;
4146   /* Control */
4147   osThreadId_t   owner;
4148   uint32_t       xid;
4149 } IO_CONNECT;
4150 #endif
4151
4152 /* Assign arguments */
4153 #define ARG_CONNECT(_sock,_ip,_ip_len,_port) do {                   \
4154                                                io.sock   = _sock;   \
4155                                                io.ip     = _ip;     \
4156                                                io.ip_len = _ip_len; \
4157                                                io.port   = _port;   \
4158                                              } while (0)
4159
4160 /* Connect worker thread */
4161 __NO_RETURN static void Th_Connect (IO_CONNECT *io) {
4162   uint32_t flags,xid;
4163
4164   for (;;) {
4165     /* Wait for the signal to select and execute the function */
4166     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_BIND |
4167                                F_CONNECT    | F_LISTEN     | F_CLOSE, osFlagsWaitAny, osWaitForever);
4168     xid   = io->xid;
4169     switch (flags) {
4170       case F_CREATE_TCP:
4171         /* Create stream socket */
4172         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
4173         break;
4174
4175       case F_CREATE_UDP:
4176         /* Create datagram socket */
4177         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
4178         break;
4179
4180       case F_BIND:
4181         /* Bind socket */
4182         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
4183         break;
4184
4185       case F_CONNECT:
4186         /* Connect on socket */
4187         io->rc = drv->SocketConnect (io->sock, io->ip, io->ip_len, io->port);
4188         break;
4189
4190       case F_LISTEN:
4191         /* Listen on socket */
4192         io->rc = drv->SocketListen (io->sock, 1);
4193         break;
4194
4195       case F_CLOSE:
4196         /* Close socket */
4197         io->rc = drv->SocketClose (io->sock);
4198         break;
4199     }
4200     /* Done, send signal to owner thread */
4201     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
4202     osDelay(1);
4203     osThreadFlagsSet (io->owner, flags);
4204     osThreadFlagsClear (F_ALL);
4205   }
4206 }
4207
4208 /**
4209 \brief  Function: WIFI_SocketConnect
4210 \ingroup wifi_sock_api
4211 \details
4212 The test function \b WIFI_SocketConnect verifies the WiFi Driver \b SocketConnect function:
4213 \code
4214 int32_t (*SocketConnect) (int32_t socket, const uint8_t *ip, uint32_t  ip_len, uint16_t  port);
4215 \endcode
4216
4217 Stream socket test 1:
4218  - Create stream socket
4219  - Check function parameters
4220  - Connect to server, blocking mode
4221  - Connect again, already connected
4222  - Bind connected socket
4223  - Close socket
4224  - Connect on closed socket
4225
4226 Stream socket test 2:
4227  - Create stream socket
4228  - Connect to server, connection rejected
4229  - Close socket
4230
4231 Stream socket test 3:
4232  - Create stream socket
4233  - Connect to server, non-responding or non-existent
4234  - Close socket
4235
4236 Stream socket test 4:
4237  - Create stream socket
4238  - Bind socket
4239  - Start listening
4240  - Connect to server, blocking mode
4241  - Close socket
4242
4243 Datagram socket test:
4244  - Create datagram socket
4245  - Bind socket
4246  - Check function parameters
4247  - Connect to server, enable address filtering
4248  - Connect to unspecified address, disable filtering
4249  - Close socket
4250  - Connect again, closed socket
4251 */
4252 void WIFI_SocketConnect (void) {
4253   osThreadId_t worker;
4254   int32_t      rval;
4255   IO_CONNECT   io;
4256   int32_t      sock;
4257
4258   if (socket_funcs_exist == 0U) {
4259     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
4260     return;
4261   }
4262
4263   if (station_init (1) == 0) {
4264     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
4265     return;
4266   }
4267
4268   /* Create worker thread */
4269   worker = osThreadNew ((osThreadFunc_t)Th_Connect, &io, NULL);
4270   if (worker == NULL) {
4271     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
4272     return;
4273   }
4274
4275   ARG_INIT();
4276
4277   /* Create stream socket */
4278   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4279   if (io.rc < 0) {
4280     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4281   } else {
4282     sock = io.rc;
4283
4284     /* Check parameter (socket = -1) */
4285     ARG_CONNECT(-1, ip_socket_server, 4, DISCARD_PORT);
4286     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4287     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4288
4289     /* Check parameter (socket = INT32_MIN) */
4290     ARG_CONNECT(INT32_MIN, ip_socket_server, 4, DISCARD_PORT);
4291     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4292     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4293
4294     /* Check parameter (socket = INT32_MAX) */
4295     ARG_CONNECT(INT32_MAX, ip_socket_server, 4, DISCARD_PORT);
4296     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4297     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4298
4299     /* Check parameter (ip = NULL) */
4300     ARG_CONNECT(sock, NULL, 4, DISCARD_PORT);
4301     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4302     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4303
4304     /* Check parameter (ip = 0.0.0.0) */
4305     ARG_CONNECT(sock, ip_unspec, 4, DISCARD_PORT);
4306     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4307     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4308
4309     /* Check parameter (ip_len = 0) */
4310     ARG_CONNECT(sock, ip_socket_server, 0, DISCARD_PORT);
4311     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4312     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4313
4314     /* Check parameter (ip_len = 5) */
4315     ARG_CONNECT(sock, ip_socket_server, 5, DISCARD_PORT);
4316     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4317     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4318
4319     /* Check parameter (port = 0) */
4320     ARG_CONNECT(sock, ip_socket_server, 4, 0);
4321     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4322     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4323
4324     /* Connect to stream server */
4325     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4326     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4327     TH_ASSERT  (io.rc == 0);
4328
4329     /* Connect 2nd time */
4330     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4331     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4332     /* Should return error (socket already connected) */
4333     /* Strict: EISCONN, valid non-strict: OK, ERROR */
4334     TH_ASSERT2 ((io.rc == ARM_SOCKET_EISCONN), ((io.rc == 0) || (io.rc == ARM_SOCKET_ERROR)), "connect socket to same address again", io.rc, ARM_SOCKET_EISCONN);
4335
4336     /* Bind connected socket */
4337     io.sock = sock;
4338     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4339     /* Should return error (socket already connected) */
4340     /* Strict: EISCONN, valid non-strict: ERROR */
4341     TH_ASSERT2 ((io.rc == ARM_SOCKET_EISCONN), (io.rc == ARM_SOCKET_ERROR), "bind on connected socket", io.rc, ARM_SOCKET_EISCONN);
4342
4343     /* Close socket */
4344     io.sock = sock;
4345     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4346     TH_ASSERT  (io.rc == 0);
4347
4348     /* Connect again, closed socket */
4349     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4350     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4351     /* Should return error (socket not created) */
4352     /* Strict: ESOCK, valid non-strict: ERROR */
4353     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "connect on closed socket", io.rc, ARM_SOCKET_ESOCK);
4354
4355     osDelay (10);
4356   }
4357
4358   /* Create stream socket */
4359   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4360   if (io.rc < 0) {
4361     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4362   } else {
4363     sock = io.rc;
4364
4365     /* Connect to stream server (connection rejected) */
4366     ARG_CONNECT(sock, ip_socket_server, 4, TCP_REJECTED_PORT);
4367     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4368     /* Should return error (connection rejected by the peer) */
4369     /* Strict: ECONNREFUSED, valid non-strict: ETIMEDOUT, ERROR */
4370     TH_ASSERT2 ((io.rc == ARM_SOCKET_ECONNREFUSED), ((io.rc == ARM_SOCKET_ETIMEDOUT) || (io.rc == ARM_SOCKET_ERROR)), "connect to non-existent port", io.rc, ARM_SOCKET_ECONNREFUSED);
4371
4372     /* Close socket */
4373     io.sock = sock;
4374     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4375     TH_ASSERT  (io.rc == 0);
4376
4377     osDelay (10);
4378   }
4379
4380   /* Create stream socket */
4381   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4382   if (io.rc < 0) {
4383     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4384   } else {
4385     sock = io.rc;
4386
4387     /* Connect to stream server (non-existent) */
4388     ARG_CONNECT(sock, ip_socket_server, 4, TCP_TIMEOUT_PORT);
4389     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4390     /* Should return error (connection timeout) */
4391     /* Strict: ETIMEDOUT, valid non-strict: ERROR */
4392     TH_ASSERT2 ((io.rc == ARM_SOCKET_ETIMEDOUT), (io.rc == ARM_SOCKET_ERROR), "connect to non-existent stream server", io.rc, ARM_SOCKET_ETIMEDOUT);
4393
4394     /* Close socket */
4395     io.sock = sock;
4396     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4397     TH_ASSERT  (io.rc == 0);
4398
4399     osDelay (10);
4400   }
4401
4402   /* Create stream socket */
4403   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4404   if (io.rc < 0) {
4405     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4406   } else {
4407     sock = io.rc;
4408
4409     /* Bind socket */
4410     io.sock = sock;
4411     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4412     TH_ASSERT  (io.rc == 0);
4413
4414     /* Start listening */
4415     io.sock = sock;
4416     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
4417     TH_ASSERT  (io.rc == 0);
4418
4419     /* Connect to stream server */
4420     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4421     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4422     /* Connect on listening socket should fail */
4423     /* Strict: EINVAL, valid non-strict: ERROR */
4424     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "connect on listening socket", io.rc, ARM_SOCKET_EINVAL);
4425
4426     /* Close socket */
4427     io.sock = sock;
4428     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4429     TH_ASSERT  (io.rc == 0);
4430
4431     osDelay (10);
4432   }
4433
4434   /* Create datagram socket */
4435   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
4436   if (io.rc < 0) {
4437     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
4438   } else {
4439     sock = io.rc;
4440
4441     /* Check parameter (socket = -1) */
4442     ARG_CONNECT(-1, ip_socket_server, 4, DISCARD_PORT);
4443     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4444     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4445
4446     /* Check parameter (socket = INT32_MIN) */
4447     ARG_CONNECT(INT32_MIN, ip_socket_server, 4, DISCARD_PORT);
4448     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4449     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4450
4451     /* Check parameter (socket = INT32_MAX) */
4452     ARG_CONNECT(INT32_MAX, ip_socket_server, 4, DISCARD_PORT);
4453     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4454     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4455
4456     /* Check parameter (ip = NULL) */
4457     ARG_CONNECT(sock, NULL, 4, DISCARD_PORT);
4458     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4459     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4460
4461     /* Check parameter (ip = 0.0.0.0) */
4462     ARG_CONNECT(sock, ip_unspec, 4, DISCARD_PORT);
4463     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4464     /* Datagram sockets may dissolve the association */
4465     /* by connecting to unspecified address.         */
4466     /* Strict: OK, valid non-strict: EINVAL, ERROR */
4467     TH_ASSERT2 ((io.rc == 0), ((io.rc == ARM_SOCKET_EINVAL) || (io.rc == ARM_SOCKET_ERROR)), "connect datagram socket to unspecified address (0.0.0.0)", io.rc, 0);
4468
4469     /* Check parameter (ip_len = 0) */
4470     ARG_CONNECT(sock, ip_socket_server, 0, DISCARD_PORT);
4471     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4472     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4473
4474     /* Check parameter (ip_len = 5) */
4475     ARG_CONNECT(sock, ip_socket_server, 5, DISCARD_PORT);
4476     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4477     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4478
4479     /* Check parameter (port = 0) */
4480     ARG_CONNECT(sock, ip_socket_server, 4, 0);
4481     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4482     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4483
4484     /* Connect to datagram server */
4485     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4486     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4487     TH_ASSERT  (io.rc == 0);
4488
4489     /* Connect to unspecified address (0.0.0.0) */
4490     ARG_CONNECT(sock, ip_unspec, 4, DISCARD_PORT);
4491     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4492     /* Datagram sockets may dissolve the association */
4493     /* by connecting to unspecified address.         */
4494     /* Should return ok (socket address deleted) */
4495     /* Strict: OK, valid non-strict: EINVAL, ERROR */
4496     TH_ASSERT2 ((io.rc == 0), ((io.rc == ARM_SOCKET_EINVAL) || (io.rc == ARM_SOCKET_ERROR)), "connect datagram socket to unspecified address (0.0.0.0)", io.rc, 0);
4497
4498     /* Close socket */
4499     io.sock = sock;
4500     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4501     TH_ASSERT  (io.rc == 0);
4502
4503     /* Connect again, closed socket */
4504     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4505     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4506     /* Should return error (socket not created) */
4507     /* Strict: ESOCK, valid non-strict: ERROR */
4508     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "connect on closed socket", io.rc, ARM_SOCKET_ESOCK);
4509
4510     osDelay (10);
4511   }
4512
4513   if (rval == 0) {
4514     station_uninit ();
4515   }
4516
4517   /* Terminate worker thread */
4518   osThreadTerminate (worker);
4519 }
4520
4521 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
4522
4523 /* Recv IO parameters */
4524 #ifndef __DOXYGEN__                     // Exclude form the documentation
4525 typedef struct {
4526   int32_t      sock;
4527   uint8_t     *buf;
4528   uint32_t     len;
4529   int32_t      rc;
4530   /* Control */
4531   osThreadId_t owner;
4532   uint32_t     xid;
4533   uint32_t     tval;
4534 } IO_RECV;
4535 #endif
4536
4537 /* Assign arguments */
4538 #define ARG_RECV(_sock,_buf,_len) do {               \
4539                                     io.sock = _sock; \
4540                                     io.buf  = _buf;  \
4541                                     io.len  = _len;  \
4542                                   } while (0)
4543
4544 /* Recv worker thread */
4545 __NO_RETURN static void Th_Recv (IO_RECV *io) {
4546   uint32_t flags,xid;
4547
4548   for (;;) {
4549     /* Wait for the signal to select and execute the function */
4550     flags = osThreadFlagsWait (F_CREATE_TCP | F_BIND | F_CONNECT | F_LISTEN |
4551                                F_SETOPT     | F_RECV | F_CLOSE, osFlagsWaitAny, osWaitForever);
4552     xid   = io->xid;
4553     switch (flags) {
4554       case F_CREATE_TCP:
4555         /* Create stream socket */
4556         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
4557         break;
4558
4559       case F_BIND:
4560         /* Bind socket */
4561         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
4562         break;
4563
4564       case F_CONNECT:
4565         /* Connect on socket */
4566         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, (uint16_t)io->tval);
4567         break;
4568
4569       case F_LISTEN:
4570         /* Listen on socket */
4571         io->rc = drv->SocketListen (io->sock, 1);
4572         break;
4573
4574       case F_SETOPT:
4575         /* Set socket options */
4576         io->rc = drv->SocketSetOpt (io->sock, ARM_SOCKET_SO_RCVTIMEO, &io->tval, sizeof(io->tval));
4577         break;
4578
4579       case F_RECV:
4580         /* Recv on socket */
4581         if (io->buf != NULL) {
4582           memset((void *)io->buf, 0xCC, io->len);
4583         }
4584         io->rc = drv->SocketRecv (io->sock, io->buf, io->len);
4585         break;
4586
4587       case F_CLOSE:
4588         /* Close socket */
4589         io->rc = drv->SocketClose (io->sock);
4590         break;
4591     }
4592     /* Done, send signal to owner thread */
4593     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
4594     osDelay(1);
4595     osThreadFlagsSet (io->owner, flags);
4596     osThreadFlagsClear (F_ALL);
4597   }
4598 }
4599
4600 /**
4601 \brief  Function: WIFI_SocketRecv
4602 \ingroup wifi_sock_api
4603 \details
4604 Test case \b WIFI_SocketRecv verifies the WiFi Driver \b SocketRecv function:
4605 \code
4606 int32_t (*SocketRecv) (int32_t socket, void *buf, uint32_t len);
4607 \endcode
4608
4609 Stream socket test 1:
4610  - Create stream socket
4611  - Connect to Chargen server
4612  - Check function parameters
4613  - Receive data in blocking mode
4614  - Close socket
4615  - Receive again, closed socket
4616
4617 Stream socket test 2:
4618  - Create stream socket
4619  - Receive data, created socket
4620  - Bind socket
4621  - Receive data, bound socket
4622  - Start listening
4623  - Receive data, listening socket
4624  - Close socket
4625
4626 Stream socket test 3:
4627  - Create stream socket
4628  - Connect to Discard server
4629  - Set receive timeout to 1 sec
4630  - Receive data, timeout expires
4631  - Close socket
4632 */
4633 void WIFI_SocketRecv (void) {
4634   uint8_t      buf[4];
4635   uint32_t     ticks,tout;
4636   osThreadId_t worker;
4637   int32_t      rval;
4638   IO_RECV      io;
4639   int32_t      sock;
4640
4641   if (socket_funcs_exist == 0U) {
4642     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
4643     return;
4644   }
4645
4646   if (station_init (1) == 0) {
4647     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
4648     return;
4649   }
4650
4651   /* Create worker thread */
4652   worker = osThreadNew ((osThreadFunc_t)Th_Recv, &io, NULL);
4653   if (worker == NULL) {
4654     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
4655     return;
4656   }
4657
4658   ARG_INIT();
4659
4660   /* Create stream socket */
4661   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4662   if (io.rc < 0) {
4663     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4664   } else {
4665     sock = io.rc;
4666
4667     /* Connect to stream server */
4668     io.sock = sock;
4669     io.tval = CHARGEN_PORT;
4670     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4671     TH_ASSERT  (io.rc == 0);
4672
4673     /* Check parameter (socket = -1) */
4674     ARG_RECV   (-1, buf, sizeof(buf));
4675     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4676     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4677
4678     /* Check parameter (socket = INT32_MIN) */
4679     ARG_RECV   (INT32_MIN, buf, sizeof(buf));
4680     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4681     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4682
4683     /* Check parameter (socket = INT32_MAX) */
4684     ARG_RECV   (INT32_MAX, buf, sizeof(buf));
4685     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4686     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4687
4688     /* Check parameter (buf = NULL) */
4689     ARG_RECV   (sock, NULL, sizeof(buf));
4690     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4691     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4692
4693     /* Receive no data (check that received data is available) */
4694     ARG_RECV   (sock, buf, 0);
4695     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4696     TH_ASSERT  (io.rc == 0);
4697
4698     /* Receive some data */
4699     ARG_RECV   (sock, buffer, sizeof(buffer));
4700     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
4701     TH_ASSERT  (io.rc >= 2);
4702
4703     /* Close socket */
4704     io.sock = sock;
4705     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4706     TH_ASSERT  (io.rc == 0);
4707
4708     /* Receive again, closed socket */
4709     ARG_RECV (sock, buffer, sizeof(buffer));
4710     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4711     /* Should return error (socket not created) */
4712     /* Strict: ESOCK, valid non-strict: ERROR */
4713     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "recv on closed socket", io.rc, ARM_SOCKET_ESOCK);
4714
4715     osDelay (10);
4716   }
4717
4718   /* Create stream socket */
4719   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4720   if (io.rc < 0) {
4721     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4722   } else {
4723     /* Test server mode */
4724     sock = io.rc;
4725
4726     /* Receive, created socket */
4727     ARG_RECV   (sock, buffer, sizeof(buffer));
4728     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4729     /* Should return error (socket not connected) */
4730     /* Strict: ENOTCONN, valid non-strict: ERROR */
4731     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on created socket", io.rc, ARM_SOCKET_ENOTCONN);
4732
4733     /* Bind socket */
4734     io.sock = sock;
4735     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4736     TH_ASSERT  (io.rc == 0);
4737
4738     /* Receive, bound socket */
4739     ARG_RECV   (sock, buffer, sizeof(buffer));
4740     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4741     /* Should return error (socket not connected) */
4742     /* Strict: ENOTCONN, valid non-strict: ERROR */
4743     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on bound socket", io.rc, ARM_SOCKET_ENOTCONN);
4744
4745     /* Start listening */
4746     io.sock = sock;
4747     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
4748     TH_ASSERT  (io.rc == 0);
4749
4750     /* Receive, listening socket */
4751     ARG_RECV   (sock, buffer, sizeof(buffer));
4752     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4753     /* Should return error (socket not connected) */
4754     /* Strict: ENOTCONN, valid non-strict: ERROR */
4755     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on listening socket", io.rc, ARM_SOCKET_ENOTCONN);
4756
4757     /* Close socket */
4758     io.sock = sock;
4759     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4760     TH_ASSERT  (io.rc == 0);
4761
4762     osDelay (10);
4763   }
4764
4765   /* Create stream socket */
4766   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4767   if (io.rc < 0) {
4768     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4769   } else {
4770     sock = io.rc;
4771
4772     /* Connect to stream server */
4773     io.sock = sock;
4774     io.tval = DISCARD_PORT;
4775     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4776     TH_ASSERT  (io.rc == 0);
4777
4778     /* Set receive timeout to 1 sec */
4779     io.sock = sock;
4780     io.tval = 1000;
4781     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
4782     TH_ASSERT  (io.rc == 0);
4783
4784     /* Receive until timeout, no data */
4785     ARG_RECV   (sock, buffer, sizeof(buffer));
4786     ticks = GET_SYSTICK();
4787     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4788     tout = GET_SYSTICK() - ticks;
4789     /* Should return EAGAIN (operation timed out) */
4790     TH_ASSERT  (io.rc == ARM_SOCKET_EAGAIN);
4791     /* Check receive timeout is in the range of 0.9 to 1.1 sec */
4792     TH_ASSERT  (tout > SYSTICK_MICROSEC(900000) && tout < SYSTICK_MICROSEC(1100000));
4793
4794     /* Close socket */
4795     io.sock = sock;
4796     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4797     TH_ASSERT  (io.rc == 0);
4798
4799     osDelay (10);
4800   }
4801
4802   if (rval == 0) {
4803     station_uninit ();
4804   }
4805
4806   /* Terminate worker thread */
4807   osThreadTerminate (worker);
4808 }
4809
4810 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
4811
4812 /* RecvFrom IO parameters */
4813 #ifndef __DOXYGEN__                     // Exclude form the documentation
4814 typedef struct {
4815   int32_t      sock;
4816   uint8_t     *buf;
4817   uint32_t     len;
4818   uint8_t     *ip;
4819   uint32_t    *ip_len;
4820   uint16_t    *port;
4821   int32_t      rc;
4822   /* Control */
4823   osThreadId_t owner;
4824   uint32_t     xid;
4825   uint32_t     tout;
4826 } IO_RECVFROM;
4827 #endif
4828
4829 /* Assign arguments */
4830 #define ARG_RECVFROM(_sock,_buf,_len,_ip,_ip_len,_port) do {                   \
4831                                                           io.sock   = _sock;   \
4832                                                           io.buf    = _buf;    \
4833                                                           io.len    = _len;    \
4834                                                           io.ip     = _ip;     \
4835                                                           io.ip_len = _ip_len; \
4836                                                           io.port   = _port;   \
4837                                                         } while (0)
4838
4839 /* RecvFrom worker thread */
4840 __NO_RETURN static void Th_RecvFrom (IO_RECVFROM *io) {
4841   uint32_t flags,xid;
4842
4843   for (;;) {
4844     /* Wait for the signal to select and execute the function */
4845     flags = osThreadFlagsWait (F_CREATE_UDP | F_CONNECT | F_SETOPT |
4846                                F_RECVFROM   | F_SEND    | F_CLOSE, osFlagsWaitAny, osWaitForever);
4847     xid   = io->xid;
4848     switch (flags) {
4849       case F_CREATE_UDP:
4850         /* Create datagram socket */
4851         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
4852         break;
4853
4854       case F_CONNECT:
4855         /* Connect on socket */
4856         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, CHARGEN_PORT);
4857         break;
4858
4859       case F_SETOPT:
4860         /* Set socket options */
4861         io->rc = drv->SocketSetOpt (io->sock, ARM_SOCKET_SO_RCVTIMEO, &io->tout, sizeof(io->tout));
4862         break;
4863
4864       case F_RECVFROM:
4865         /* RecvFrom on socket */
4866         if (io->buf != NULL) {
4867           memset((void *)io->buf, 0xCC, io->len);
4868         }
4869         io->rc = drv->SocketRecvFrom (io->sock, io->buf, io->len, io->ip, io->ip_len, io->port);
4870         break;
4871
4872       case F_SEND:
4873         /* Send on socket */
4874         io->rc = drv->SocketSend (io->sock, "a", 1);
4875         break;
4876
4877       case F_CLOSE:
4878         /* Close socket */
4879         io->rc = drv->SocketClose (io->sock);
4880         break;
4881     }
4882     /* Done, send signal to owner thread */
4883     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
4884     osDelay(1);
4885     osThreadFlagsSet (io->owner, flags);
4886     osThreadFlagsClear (F_ALL);
4887   }
4888 }
4889
4890 /**
4891 \brief  Function: WIFI_SocketRecvFrom
4892 \ingroup wifi_sock_api
4893 \details
4894 The test function \b WIFI_SocketRecvFrom verifies the WiFi Driver \b SocketRecvFrom function:
4895 \code
4896 int32_t (*SocketRecvFrom) (int32_t socket, void *buf, uint32_t len, uint8_t *ip, uint32_t *ip_len, uint16_t *port);
4897 \endcode
4898
4899 Datagram socket test 1:
4900  - Create datagram socket
4901  - Connect to Chargen server
4902  - Check function parameters
4903  - Receive data in blocking mode
4904  - Set receive timeout to 1 sec
4905  - Receive again, timeout expires
4906  - Close socket
4907  - Receive again, closed socket
4908 */
4909 void WIFI_SocketRecvFrom (void) {
4910   uint8_t      ip[5];
4911   uint32_t     ip_len,ticks,tout;
4912   uint16_t     port;
4913   uint8_t      buf[4];
4914   osThreadId_t worker;
4915   int32_t      rval;
4916   IO_RECVFROM  io;
4917   int32_t      sock;
4918
4919   if (socket_funcs_exist == 0U) {
4920     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
4921     return;
4922   }
4923
4924   if (station_init (1) == 0) {
4925     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
4926     return;
4927   }
4928
4929   /* Create worker thread */
4930   worker = osThreadNew ((osThreadFunc_t)Th_RecvFrom, &io, NULL);
4931   if (worker == NULL) {
4932     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
4933     return;
4934   }
4935
4936   ARG_INIT();
4937
4938   /* Create datagram socket */
4939   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
4940   if (io.rc < 0) {
4941     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
4942   } else {
4943     sock = io.rc;
4944
4945     /* Connect to datagram server */
4946     io.sock = sock;
4947     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4948     TH_ASSERT  (io.rc == 0);
4949
4950     /* Check parameter (socket = -1) */
4951     ip_len = sizeof(ip);
4952     ARG_RECVFROM (-1, buf, sizeof(buf), ip, &ip_len, &port);
4953     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
4954     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4955
4956     /* Check parameter (socket = INT32_MIN) */
4957     ARG_RECVFROM (INT32_MIN, buf, sizeof(buf), ip, &ip_len, &port);
4958     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
4959     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4960
4961     /* Check parameter (socket = INT32_MAX) */
4962     ARG_RECVFROM (INT32_MAX, buf, sizeof(buf), ip, &ip_len, &port);
4963     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
4964     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4965
4966     /* Check parameter (buf == NULL) */
4967     ARG_RECVFROM (sock, NULL, sizeof(buf), ip, &ip_len, &port);
4968     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
4969     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4970
4971     /* Send one byte of data to trigger a reply */
4972     io.sock = sock;
4973     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT_LONG);
4974     TH_ASSERT  (io.rc == 1);
4975
4976     /* Initialize buffers for return values */
4977     port   = 0;
4978     ip_len = sizeof(ip) + 1;
4979     memset ((void *)ip, 0, sizeof(ip));
4980     
4981     /* Receive no data (check that received data is available) */
4982     ARG_RECVFROM (sock, NULL, 0, ip, &ip_len, &port);
4983     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT_LONG);
4984     TH_ASSERT  (io.rc == 0);
4985
4986     /* Receive some data */
4987     ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
4988     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT_LONG);
4989     /* Should receive at least 2 bytes */
4990     TH_ASSERT  (io.rc >= 2);
4991     /* IP address should be the address of the server */
4992     TH_ASSERT  ((memcmp ((const void *)ip, (const void *)ip_socket_server, 4) == 0) && (ip_len == 4));
4993     /* Port number should be the port of the CHARGEN server */
4994     TH_ASSERT  (port == CHARGEN_PORT);
4995
4996     /* Set receive timeout to 1 sec */
4997     io.sock = sock;
4998     io.tout = 1000;
4999     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
5000     TH_ASSERT  (io.rc == 0);
5001
5002     /* Receive until timeout, no data */
5003     ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
5004     ticks = GET_SYSTICK();
5005     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5006     tout = GET_SYSTICK() - ticks;
5007     /* Should return EAGAIN (operation timed out) */
5008     TH_ASSERT  (io.rc == ARM_SOCKET_EAGAIN);
5009     /* Check receive timeout is in the range of 0.9 to 1.1 sec */
5010     TH_ASSERT  (tout > SYSTICK_MICROSEC(900000) && tout < SYSTICK_MICROSEC(1100000));
5011
5012     /* Close socket */
5013     io.sock = sock;
5014     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5015     TH_ASSERT  (io.rc == 0);
5016
5017     /* Receive again, closed socket */
5018     ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
5019     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5020     /* Should return error (socket not created) */
5021     /* Strict: ESOCK, valid non-strict: ERROR */
5022     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "recvfrom on closed socket", io.rc, ARM_SOCKET_ESOCK);
5023
5024     osDelay (10);
5025   }
5026
5027   if (rval == 0) {
5028     station_uninit ();
5029   }
5030
5031   /* Terminate worker thread */
5032   osThreadTerminate (worker);
5033 }
5034
5035 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
5036
5037 /* Send IO parameters */
5038 #ifndef __DOXYGEN__                     // Exclude form the documentation
5039 typedef struct {
5040   int32_t        sock;
5041   const uint8_t *buf;
5042   uint32_t       len;
5043   int32_t        rc;
5044   /* Control */
5045   osThreadId_t owner;
5046   uint32_t     xid;
5047 } IO_SEND;
5048 #endif
5049
5050 /* Assign arguments */
5051 #define ARG_SEND(_sock,_buf,_len) do {               \
5052                                     io.sock = _sock; \
5053                                     io.buf  = _buf;  \
5054                                     io.len  = _len;  \
5055                                   } while (0)
5056
5057 /* Send worker thread */
5058 __NO_RETURN static void Th_Send (IO_SEND *io) {
5059   uint32_t flags,xid;
5060
5061   for (;;) {
5062     /* Wait for the signal to select and execute the function */
5063     flags = osThreadFlagsWait (F_CREATE_TCP | F_BIND | F_CONNECT |
5064                                F_LISTEN     | F_SEND | F_CLOSE, osFlagsWaitAny, osWaitForever);
5065     xid   = io->xid;
5066     switch (flags) {
5067       case F_CREATE_TCP:
5068         /* Create stream socket */
5069         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
5070         break;
5071
5072       case F_BIND:
5073         /* Bind socket */
5074         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
5075         break;
5076
5077       case F_CONNECT:
5078         /* Connect on socket */
5079         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
5080         break;
5081
5082        case F_LISTEN:
5083         /* Listen on socket */
5084         io->rc = drv->SocketListen (io->sock, 1);
5085         break;
5086
5087      case F_SEND:
5088         /* Send on socket */
5089         io->rc = drv->SocketSend (io->sock, io->buf, io->len);
5090         break;
5091
5092       case F_CLOSE:
5093         /* Close socket */
5094         io->rc = drv->SocketClose (io->sock);
5095         break;
5096     }
5097     /* Done, send signal to owner thread */
5098     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
5099     osDelay(1);
5100     osThreadFlagsSet (io->owner, flags);
5101     osThreadFlagsClear (F_ALL);
5102   }
5103 }
5104
5105 /**
5106 \brief  Function: WIFI_SocketSend
5107 \ingroup wifi_sock_api
5108 \details
5109 The test function \b WIFI_SocketSend verifies the WiFi Driver \b SocketSend function:
5110 \code
5111 int32_t (*SocketSend) (int32_t socket, const void *buf, uint32_t len);
5112 \endcode
5113
5114 Stream socket test 1:
5115  - Create stream socket
5116  - Connect to server, blocking mode
5117  - Check function parameters
5118  - Send data, blocking mode
5119  - Close socket
5120  - Send again, closed socket
5121
5122 Stream socket test 2:
5123  - Create stream socket
5124  - Connect to server, blocking mode
5125  - Send ESC data, server disconnects
5126  - Send again, disconnected socket
5127  - Close socket
5128
5129 Stream socket test 3:
5130  - Create stream socket
5131  - Send data, created socket
5132  - Bind socket
5133  - Send data, bound socket
5134  - Start listening
5135  - Send data, listening socket
5136  - Close socket
5137  - Send again, closed socket
5138 */
5139 void WIFI_SocketSend (void) {
5140   osThreadId_t worker;
5141   int32_t      rval;
5142   IO_SEND      io;
5143   int32_t      sock;
5144
5145   if (socket_funcs_exist == 0U) {
5146     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
5147     return;
5148   }
5149
5150   if (station_init (1) == 0) {
5151     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
5152     return;
5153   }
5154
5155   /* Create worker thread */
5156   worker = osThreadNew ((osThreadFunc_t)Th_Send, &io, NULL);
5157   if (worker == NULL) {
5158     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5159     return;
5160   }
5161
5162   ARG_INIT();
5163
5164   /* Create stream socket */
5165   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5166   if (io.rc < 0) {
5167     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5168   } else {
5169     sock = io.rc;
5170
5171     /* Connect to stream server */
5172     io.sock = sock;
5173     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
5174     TH_ASSERT  (io.rc == 0);
5175
5176     /* Check parameter (socket = -1) */
5177     ARG_SEND   (-1, test_msg, sizeof(test_msg));
5178     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5179     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5180
5181     /* Check parameter (socket = INT32_MIN) */
5182     ARG_SEND   (INT32_MIN, test_msg, sizeof(test_msg));
5183     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5184     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5185
5186     /* Check parameter (socket = INT32_MAX) */
5187     ARG_SEND   (INT32_MAX, test_msg, sizeof(test_msg));
5188     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5189     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5190
5191     /* Check parameter (buf = NULL) */
5192     ARG_SEND   (sock, NULL, sizeof(test_msg));
5193     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5194     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
5195
5196     /* Send no data (check that send is available) */
5197     ARG_SEND   (sock, test_msg, 0);
5198     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5199     TH_ASSERT  (io.rc == 0);
5200
5201     /* Send some data */
5202     ARG_SEND   (sock, test_msg, sizeof(test_msg));
5203     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT_LONG);
5204     TH_ASSERT  (io.rc == sizeof(test_msg));
5205
5206     /* Close socket */
5207     io.sock = sock;
5208     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5209     TH_ASSERT  (io.rc == 0);
5210
5211     /* Send again, closed socket */
5212     ARG_SEND   (sock, test_msg, sizeof(test_msg));
5213     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5214     /* Should return error (socket not created) */
5215     /* Strict: ESOCK, valid non-strict: ERROR */
5216     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "send on closed socket", io.rc, ARM_SOCKET_ESOCK);
5217
5218     osDelay (10);
5219   }
5220
5221   /* Create stream socket */
5222   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5223   if (io.rc < 0) {
5224     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5225   } else {
5226     sock = io.rc;
5227
5228     /* Connect to stream server */
5229     io.sock = sock;
5230     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
5231     TH_ASSERT  (io.rc == 0);
5232
5233     /* Send ESC command, server disconnects */
5234     ARG_SEND   (sock, (uint8_t *)"\x1B", 1);
5235     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT_LONG);
5236     TH_ASSERT  (io.rc == 1);
5237
5238     /* Wait for the server to disconnect */
5239     osDelay (200);
5240
5241     /* Send again, disconnected socket */
5242     ARG_SEND   (sock, test_msg, sizeof(test_msg));
5243     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5244     /* Should return error (connection reset by the peer) */
5245     /* Strict: ECONNRESET, valid non-strict: ERROR */
5246     TH_ASSERT2 ((io.rc == ARM_SOCKET_ECONNRESET), (io.rc == ARM_SOCKET_ERROR), "send on disconnected socket", io.rc, ARM_SOCKET_ECONNRESET);
5247
5248     /* Close socket */
5249     io.sock = sock;
5250     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5251     TH_ASSERT  (io.rc == 0);
5252
5253     osDelay (10);
5254   }
5255
5256   /* Create stream socket */
5257   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5258   if (io.rc < 0) {
5259     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5260   } else {
5261     sock = io.rc;
5262
5263     /* Send data, created socket */
5264     ARG_SEND   (sock, test_msg, sizeof(test_msg));
5265     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5266     /* Should return error (socket not connected) */
5267     /* Strict: ENOTCONN, valid non-strict: ERROR */
5268     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "send on created socket", io.rc, ARM_SOCKET_ENOTCONN);
5269
5270     /* Bind socket */
5271     io.sock = sock;
5272     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
5273     TH_ASSERT  (io.rc == 0);
5274
5275     /* Send data, bound socket */
5276     ARG_SEND (sock, test_msg, sizeof(test_msg));
5277     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5278     /* Should return error (socket not connected) */
5279     /* Strict: ENOTCONN, valid non-strict: ERROR */
5280     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "send on bound socket", io.rc, ARM_SOCKET_ENOTCONN);
5281
5282     /* Start listening */
5283     io.sock = sock;
5284     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
5285     TH_ASSERT  (io.rc == 0);
5286
5287     /* Send data, listening socket */
5288     ARG_SEND (sock, test_msg, sizeof(test_msg));
5289     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5290     /* Should return error (socket not connected) */
5291     /* Strict: ENOTCONN, valid non-strict: ERROR */
5292     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "send on listening socket", io.rc, ARM_SOCKET_ENOTCONN);
5293
5294     /* Close socket */
5295     io.sock = sock;
5296     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5297     TH_ASSERT  (io.rc == 0);
5298
5299     /* Send again, closed socket */
5300     ARG_SEND (sock, test_msg, sizeof(test_msg));
5301     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5302     /* Should return error (socket not created) */
5303     /* Strict: ESOCK, valid non-strict: ERROR */
5304     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "send on closed socket", io.rc, ARM_SOCKET_ESOCK);
5305
5306     osDelay (10);
5307   }
5308
5309   if (rval == 0) {
5310     station_uninit ();
5311   }
5312
5313   /* Terminate worker thread */
5314   osThreadTerminate (worker);
5315 }
5316
5317 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
5318
5319 /* SendTo IO parameters */
5320 #ifndef __DOXYGEN__                     // Exclude form the documentation
5321 typedef struct {
5322   int32_t        sock;
5323   const uint8_t *buf;
5324   uint32_t       len;
5325   const uint8_t *ip;
5326   uint32_t       ip_len;
5327   uint16_t       port;
5328   uint16_t       reserved;
5329   int32_t        rc;
5330   /* Control */
5331   osThreadId_t owner;
5332   uint32_t     xid;
5333 } IO_SENDTO;
5334 #endif
5335
5336 /* Assign arguments */
5337 #define ARG_SENDTO(_sock,_buf,_len,_ip,_ip_len,_port) do {                   \
5338                                                         io.sock   = _sock;   \
5339                                                         io.buf    = _buf;    \
5340                                                         io.len    = _len;    \
5341                                                         io.ip     = _ip;     \
5342                                                         io.ip_len = _ip_len; \
5343                                                         io.port   = _port;   \
5344                                                       } while (0)
5345
5346 /* SendTo worker thread */
5347 __NO_RETURN static void Th_SendTo (IO_SENDTO *io) {
5348   uint32_t flags,xid;
5349
5350   for (;;) {
5351     /* Wait for the signal to select and execute the function */
5352     flags = osThreadFlagsWait (F_CREATE_UDP | F_SENDTO | F_RECV | F_CLOSE, osFlagsWaitAny, osWaitForever);
5353     xid   = io->xid;
5354     switch (flags) {
5355       case F_CREATE_UDP:
5356         /* Create datagram socket */
5357         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
5358         break;
5359
5360       case F_SENDTO:
5361         /* SendTo on socket */
5362         io->rc = drv->SocketSendTo (io->sock, io->buf, io->len, io->ip, io->ip_len, io->port);
5363         break;
5364
5365       case F_RECV:
5366         /* Recv on socket */
5367         memset((void *)buffer, 0xCC, sizeof(buffer));
5368         io->rc = drv->SocketRecv (io->sock, buffer, sizeof(buffer));
5369         break;
5370
5371       case F_CLOSE:
5372         /* Close socket */
5373         io->rc = drv->SocketClose (io->sock);
5374         break;
5375     }
5376     /* Done, send signal to owner thread */
5377     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
5378     osDelay(1);
5379     osThreadFlagsSet (io->owner, flags);
5380     osThreadFlagsClear (F_ALL);
5381   }
5382 }
5383
5384 /**
5385 \brief  Function: WIFI_SocketSendTo
5386 \ingroup wifi_sock_api
5387 \details
5388 The test function \b WIFI_SocketSend verifies the WiFi Driver \b SocketSendTo function:
5389 \code
5390 int32_t (*SocketSendTo) (int32_t socket, const void *buf, uint32_t len, const uint8_t *ip, uint32_t ip_len, uint16_t port);
5391 \endcode
5392
5393 Datagram socket test:
5394  - Create datagram socket
5395  - Check function parameters
5396  - Send data, blocking mode
5397  - Receive echo data, verify if the same
5398  - Close socket
5399  - Send again, closed socket
5400 */
5401 void WIFI_SocketSendTo (void) {
5402   osThreadId_t worker;
5403   int32_t      rval;
5404   IO_SENDTO    io;
5405   int32_t      sock;
5406
5407   if (socket_funcs_exist == 0U) {
5408     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
5409     return;
5410   }
5411
5412   if (station_init (1) == 0) {
5413     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
5414     return;
5415   }
5416
5417   /* Create worker thread */
5418   worker = osThreadNew ((osThreadFunc_t)Th_SendTo, &io, NULL);
5419   if (worker == NULL) {
5420     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5421     return;
5422   }
5423
5424   ARG_INIT();
5425
5426   /* Create datagram socket */
5427   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
5428   if (io.rc < 0) {
5429     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
5430   } else {
5431     sock = io.rc;
5432
5433     /* Check parameter (socket = -1) */
5434     ARG_SENDTO (-1, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5435     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5436     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5437
5438     /* Check parameter (socket = INT32_MIN) */
5439     ARG_SENDTO (INT32_MIN, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5440     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5441     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5442
5443     /* Check parameter (socket = INT32_MAX) */
5444     ARG_SENDTO (INT32_MAX, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5445     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5446     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5447
5448     /* Check parameter (buf == NULL) */
5449     ARG_SENDTO (sock, NULL, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5450     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5451     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
5452
5453     /* Send no data (check that send is available) */
5454     ARG_SENDTO (sock, test_msg, 0, ip_socket_server, 4, ECHO_PORT);
5455     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5456     TH_ASSERT  (io.rc == 0);
5457
5458     /* Send some data */
5459     ARG_SENDTO (sock, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5460     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT_LONG);
5461     TH_ASSERT  (io.rc == sizeof(test_msg));
5462
5463     /* Receive the echoed data */
5464     io.sock = sock;
5465     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
5466     /* Should receive the same data (ECHO protocol) */
5467     TH_ASSERT  ((io.rc == sizeof(test_msg)) && (memcmp ((const void *)test_msg, (const void *)buffer, sizeof(test_msg)) == 0));
5468
5469     /* Close socket */
5470     io.sock = sock;
5471     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5472     TH_ASSERT  (io.rc == 0);
5473
5474     /* Send again, closed socket */
5475     ARG_SENDTO (sock, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5476     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5477     /* Should return error (socket not created) */
5478     /* Strict: ESOCK, valid non-strict: ERROR */
5479     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "sendto on closed socket", io.rc, ARM_SOCKET_ESOCK);
5480
5481     osDelay (10);
5482   }
5483
5484   if (rval == 0) {
5485     station_uninit ();
5486   }
5487
5488   /* Terminate worker thread */
5489   osThreadTerminate (worker);
5490 }
5491
5492 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
5493
5494 /* GetSockName IO parameters */
5495 #ifndef __DOXYGEN__                     // Exclude form the documentation
5496 typedef struct {
5497   int32_t      sock;
5498   uint8_t     *ip;
5499   uint32_t    *ip_len;
5500   uint16_t    *port;
5501   int32_t      rc;
5502   /* Control */
5503   osThreadId_t owner;
5504   uint32_t     xid;
5505 } IO_GETSOCKNAME;
5506 #endif
5507
5508 /* Assign arguments */
5509 #define ARG_GETSOCKNAME(_sock,_ip,_ip_len,_port) do {                   \
5510                                                    io.sock   = _sock;   \
5511                                                    io.ip     = _ip;     \
5512                                                    io.ip_len = _ip_len; \
5513                                                    io.port   = _port;   \
5514                                                  } while (0)
5515
5516 /* GetSockName worker thread */
5517 __NO_RETURN static void Th_GetSockName (IO_GETSOCKNAME *io) {
5518   uint32_t flags,xid;
5519
5520   for (;;) {
5521     /* Wait for the signal to select and execute the function */
5522     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP  | F_BIND |
5523                                F_CONNECT    | F_GETSOCKNAME | F_CLOSE, osFlagsWaitAny, osWaitForever);
5524     xid   = io->xid;
5525     switch (flags) {
5526       case F_CREATE_TCP:
5527         /* Create stream socket */
5528         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
5529         break;
5530
5531       case F_CREATE_UDP:
5532         /* Create datagram socket */
5533         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
5534         break;
5535
5536       case F_BIND:
5537         /* Bind socket */
5538         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
5539         break;
5540
5541       case F_CONNECT:
5542         /* Connect on socket */
5543         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
5544         break;
5545
5546       case F_GETSOCKNAME:
5547         /* Get socket name */
5548         io->rc = drv->SocketGetSockName (io->sock, io->ip, io->ip_len, io->port);
5549         break;
5550
5551       case F_CLOSE:
5552         /* Close socket */
5553         io->rc = drv->SocketClose (io->sock);
5554         break;
5555     }
5556     /* Done, send signal to owner thread */
5557     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
5558     osDelay(1);
5559     osThreadFlagsSet (io->owner, flags);
5560     osThreadFlagsClear (F_ALL);
5561   }
5562 }
5563
5564 /**
5565 \brief  Function: WIFI_SocketGetSockName
5566 \ingroup wifi_sock_api
5567 \details
5568 The test function \b WIFI_SocketGetSockName verifies the WiFi Driver \b SocketGetSockName function:
5569 \code
5570 int32_t (*SocketGetSockName) (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t *port);
5571 \endcode
5572
5573 Stream socket test 1:
5574  - Create stream socket
5575  - Connect to server, blocking mode
5576  - Check function parameters
5577  - Get socket name
5578  - Close socket
5579  - Get socket name again, closed socket
5580
5581 Stream socket test 1:
5582  - Create stream socket
5583  - Get socket name, not bound
5584  - Bind socket
5585  - Get socket name, bound
5586  - Close socket
5587
5588 Datagram socket test 1:
5589  - Create datagram socket
5590  - Connect to server, enable packet filtering
5591  - Check function parameters
5592  - Get socket name
5593  - Close socket
5594  - Get socket name again, closed socket
5595
5596 Datagram socket test 1:
5597  - Create datagram socket
5598  - Get socket name, not bound
5599  - Bind socket
5600  - Get socket name, bound
5601  - Close socket
5602 */
5603 void WIFI_SocketGetSockName (void) {
5604   uint8_t        local_ip[5];
5605   uint16_t       local_port;
5606   uint32_t       ip_len;
5607   osThreadId_t   worker;
5608   int32_t        rval;
5609   IO_GETSOCKNAME io;
5610   int32_t        sock;
5611
5612   if (socket_funcs_exist == 0U) {
5613     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
5614     return;
5615   }
5616
5617   if (station_init (1) == 0) {
5618     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
5619     return;
5620   }
5621
5622   /* Create worker thread */
5623   worker = osThreadNew ((osThreadFunc_t)Th_GetSockName, &io, NULL);
5624   if (worker == NULL) {
5625     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5626     return;
5627   }
5628
5629   ARG_INIT();
5630
5631   /* Create stream socket */
5632   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5633   if (io.rc < 0) {
5634     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5635   } else {
5636     /* Test client mode */
5637     sock = io.rc;
5638
5639     /* Connect to stream server */
5640     io.sock = sock;
5641     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
5642     TH_ASSERT  (io.rc == 0);
5643
5644     /* Check parameter (socket = -1) */
5645     ip_len = sizeof(local_ip);
5646     ARG_GETSOCKNAME (-1, local_ip, &ip_len, &local_port);
5647     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5648     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5649
5650     /* Check parameter (socket = INT32_MIN) */
5651     ARG_GETSOCKNAME (INT32_MIN, local_ip, &ip_len, &local_port);
5652     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5653     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5654
5655     /* Check parameter (socket = INT32_MAX) */
5656     ARG_GETSOCKNAME (INT32_MAX, local_ip, &ip_len, &local_port);
5657     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5658     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5659
5660     /* Check parameter (port = NULL) */
5661     ip_len = sizeof(local_ip);
5662     ARG_GETSOCKNAME (sock, local_ip, &ip_len, NULL);
5663     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5664     /* Request IP address only should be accepted */
5665     TH_ASSERT  (io.rc == 0);
5666
5667     /* Check parameter (ip = NULL, ip_len = NULL) */
5668     ARG_GETSOCKNAME (sock, NULL, NULL, &local_port);
5669     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5670     /* Request port only should be accepted */
5671     TH_ASSERT  (io.rc == 0);
5672
5673     /* Initialize buffers for return values */
5674     local_port = 0;
5675     ip_len     = sizeof(local_ip) + 1;
5676     memcpy (local_ip, ip_bcast, sizeof(local_ip));
5677
5678     /* Retrieve socket name */
5679     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5680     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5681     TH_ASSERT  (io.rc == 0);
5682     /* IP address should be different from broadcast */
5683     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_bcast, 4) != 0) && (ip_len == 4));
5684     /* Port number should be non-zero */
5685     TH_ASSERT  (local_port != 0);
5686
5687     /* Close socket */
5688     io.sock = sock;
5689     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5690     TH_ASSERT  (io.rc == 0);
5691
5692     /* Retrieve socket name again */
5693     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5694     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5695     /* Should return error (socket not created) */
5696     /* Strict: ESOCK, valid non-strict: ERROR */
5697     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockname on closed socket", io.rc, ARM_SOCKET_ESOCK);
5698
5699     osDelay (10);
5700   }
5701
5702   /* Create stream socket */
5703   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5704   if (io.rc < 0) {
5705     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5706   } else {
5707     /* Test server mode */
5708     sock = io.rc;
5709
5710     /* Retrieve socket name, not bound */
5711     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5712     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5713     /* Should return error (socket not bound) */
5714     /* Strict: EINVAL, valid non-strict: ERROR */
5715     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "getsockname on unbound socket", io.rc, ARM_SOCKET_EINVAL);
5716
5717     /* Initialize buffers for return values */
5718     local_port = 0;
5719     ip_len     = sizeof(local_ip) + 1;
5720     memcpy (local_ip, ip_bcast, sizeof(local_ip));
5721
5722     /* Bind socket */
5723     io.sock = sock;
5724     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
5725     TH_ASSERT  (io.rc == 0);
5726
5727     /* Retrieve socket name, bound */
5728     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5729     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5730     TH_ASSERT  (io.rc == 0);
5731     /* IP address should be unspecified */
5732     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_unspec, 4) == 0) && (ip_len == 4));
5733     /* Port number should be listening port */
5734     TH_ASSERT  (local_port == DISCARD_PORT);
5735
5736     /* Close socket */
5737     io.sock = sock;
5738     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5739     TH_ASSERT  (io.rc == 0);
5740
5741     osDelay (10);
5742   }
5743
5744   /* Create datagram socket */
5745   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
5746   if (io.rc < 0) {
5747     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
5748   } else {
5749     /* Test client mode */
5750     sock = io.rc;
5751
5752     /* Connect to datagram server */
5753     io.sock = sock;
5754     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
5755     TH_ASSERT  (io.rc == 0);
5756
5757     /* Check parameter (socket = -1) */
5758     ARG_GETSOCKNAME (-1, local_ip, &ip_len, &local_port);
5759     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5760     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5761
5762     /* Check parameter (socket = INT32_MIN) */
5763     ARG_GETSOCKNAME (INT32_MIN, local_ip, &ip_len, &local_port);
5764     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5765     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5766
5767     /* Check parameter (socket = INT32_MAX) */
5768     ARG_GETSOCKNAME (INT32_MAX, local_ip, &ip_len, &local_port);
5769     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5770     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5771
5772     /* Check parameter (port = NULL) */
5773     ip_len = sizeof(local_ip);
5774     ARG_GETSOCKNAME (sock, local_ip, &ip_len, NULL);
5775     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5776     /* Request IP address only should be accepted */
5777     TH_ASSERT  (io.rc == 0);
5778
5779     /* Check parameter (ip = NULL, ip_len = NULL) */
5780     ARG_GETSOCKNAME (sock, NULL, NULL, &local_port);
5781     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5782     /* Request port only should be accepted */
5783     TH_ASSERT  (io.rc == 0);
5784
5785     /* Initialize buffers for return values */
5786     local_port = 0;
5787     ip_len     = sizeof(local_ip) + 1;
5788     memcpy (local_ip, ip_bcast, sizeof(local_ip));
5789
5790     /* Retrieve socket name */
5791     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5792     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5793     TH_ASSERT  (io.rc == 0);
5794     /* IP address should be different from broadcast */
5795     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_bcast, 4) != 0) && (ip_len == 4));
5796     /* Port number should be non-zero */
5797     TH_ASSERT  (local_port != 0);
5798
5799     /* Close socket */
5800     io.sock = sock;
5801     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5802     TH_ASSERT  (io.rc == 0);
5803
5804     /* Retrieve socket name again */
5805     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5806     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5807     /* Should return error (socket not created) */
5808     /* Strict: ESOCK, valid non-strict: ERROR */
5809     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockname on closed socket", io.rc, ARM_SOCKET_ESOCK);
5810
5811     osDelay (10);
5812   }
5813
5814   /* Create datagram socket */
5815   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
5816   if (io.rc < 0) {
5817     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
5818   } else {
5819     /* Test server mode */
5820     sock = io.rc;
5821
5822     /* Retrieve socket name, not bound */
5823     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5824     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5825     /* Should return error (socket not bound) */
5826     /* Strict: EINVAL, valid non-strict: ERROR */
5827     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "getsockname on unbound socket", io.rc, ARM_SOCKET_EINVAL);
5828
5829     /* Initialize buffers for return values */
5830     local_port = 0;
5831     ip_len     = sizeof(local_ip) + 1;
5832     memcpy (local_ip, ip_bcast, sizeof(local_ip));
5833
5834     /* Bind socket */
5835     io.sock = sock;
5836     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
5837     TH_ASSERT  (io.rc == 0);
5838
5839     /* Retrieve socket name, bound */
5840     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5841     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5842     TH_ASSERT  (io.rc == 0);
5843     /* IP address should be unspecified */
5844     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_unspec, 4) == 0) && (ip_len == 4));
5845     /* Port number should be listening port */
5846     TH_ASSERT  (local_port == DISCARD_PORT);
5847
5848     /* Close socket */
5849     io.sock = sock;
5850     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5851     TH_ASSERT  (io.rc == 0);
5852
5853     osDelay (10);
5854   }
5855
5856   if (rval == 0) {
5857     station_uninit ();
5858   }
5859
5860   /* Terminate worker thread */
5861   osThreadTerminate (worker);
5862 }
5863
5864 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
5865
5866 /* GetPeerName IO parameters */
5867 #ifndef __DOXYGEN__                     // Exclude form the documentation
5868 typedef struct {
5869   int32_t      sock;
5870   uint8_t     *ip;
5871   uint32_t    *ip_len;
5872   uint16_t    *port;
5873   int32_t      rc;
5874   /* Control */
5875   osThreadId_t owner;
5876   uint32_t     xid;
5877 } IO_GETPEERNAME;
5878 #endif
5879
5880 /* Assign arguments */
5881 #define ARG_GETPEERNAME(_sock,_ip,_ip_len,_port) do {                   \
5882                                                    io.sock   = _sock;   \
5883                                                    io.ip     = _ip;     \
5884                                                    io.ip_len = _ip_len; \
5885                                                    io.port   = _port;   \
5886                                                  } while (0)
5887
5888 /* GetPeerName worker thread */
5889 __NO_RETURN static void Th_GetPeerName (IO_GETPEERNAME *io) {
5890   uint32_t flags,xid;
5891
5892   for (;;) {
5893     /* Wait for the signal to select and execute the function */
5894     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP  | F_BIND | F_CONNECT |
5895                                F_LISTEN     | F_GETPEERNAME | F_CLOSE, osFlagsWaitAny, osWaitForever);
5896     xid   = io->xid;
5897     switch (flags) {
5898       case F_CREATE_TCP:
5899         /* Create stream socket */
5900         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
5901         break;
5902
5903       case F_CREATE_UDP:
5904         /* Create datagram socket */
5905         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
5906         break;
5907
5908       case F_BIND:
5909         /* Bind socket */
5910         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
5911         break;
5912
5913       case F_CONNECT:
5914         /* Connect on socket */
5915         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
5916         break;
5917
5918        case F_LISTEN:
5919         /* Listen on socket */
5920         io->rc = drv->SocketListen (io->sock, 1);
5921         break;
5922
5923       case F_GETPEERNAME:
5924         /* Get peer name  */
5925         io->rc = drv->SocketGetPeerName (io->sock, io->ip, io->ip_len, io->port);
5926         break;
5927
5928       case F_CLOSE:
5929         /* Close socket */
5930         io->rc = drv->SocketClose (io->sock);
5931         break;
5932     }
5933     /* Done, send signal to owner thread */
5934     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
5935     osDelay(1);
5936     osThreadFlagsSet (io->owner, flags);
5937     osThreadFlagsClear (F_ALL);
5938   }
5939 }
5940
5941 /**
5942 \brief  Function: WIFI_SocketGetPeerName
5943 \ingroup wifi_sock_api
5944 \details
5945 The test function \b WIFI_SocketGetPeerName verifies the WiFi Driver \b SocketGetPeerName function:
5946 \code
5947 int32_t (*SocketGetPeerName) (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t *port);
5948 \endcode
5949
5950 Stream socket test  1:
5951  - Create stream socket
5952  - Connect to server, blocking mode
5953  - Check function parameters
5954  - Get peer name
5955  - Close socket
5956  - Get peer name, closed socket
5957
5958 Stream socket test  2:
5959  - Create stream socket
5960  - Get peer name, created socket
5961  - Bind socket
5962  - Get peer name, bound socket
5963  - Start listening
5964  - Get peer name, listening socket
5965  - Close socket
5966
5967 Datagram socket test:
5968  - Create datagram socket
5969  - Connect to server, enable packet filtering
5970  - Check function parameters
5971  - Get peer name
5972  - Close socket
5973  - Get peer name, closed socket
5974 */
5975 void WIFI_SocketGetPeerName (void) {
5976   uint8_t        peer_ip[5];
5977   uint16_t       peer_port;
5978   uint32_t       ip_len;
5979   osThreadId_t   worker;
5980   int32_t        rval;
5981   IO_GETPEERNAME io;
5982   int32_t        sock;
5983
5984   if (socket_funcs_exist == 0U) {
5985     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
5986     return;
5987   }
5988
5989   if (station_init (1) == 0) {
5990     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
5991     return;
5992   }
5993
5994   /* Create worker thread */
5995   worker = osThreadNew ((osThreadFunc_t)Th_GetPeerName, &io, NULL);
5996   if (worker == NULL) {
5997     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5998     return;
5999   }
6000
6001   ARG_INIT();
6002
6003   /* Create stream socket */
6004   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6005   if (io.rc < 0) {
6006     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6007   } else {
6008     sock = io.rc;
6009
6010     /* Connect to stream server */
6011     io.sock = sock;
6012     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
6013     TH_ASSERT  (io.rc == 0);
6014
6015     /* Check parameter (socket = -1) */
6016     ip_len = sizeof(peer_ip);
6017     ARG_GETPEERNAME (-1, peer_ip, &ip_len, &peer_port);
6018     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6019     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6020
6021     /* Check parameter (socket = INT32_MIN) */
6022     ARG_GETPEERNAME (INT32_MIN, peer_ip, &ip_len, &peer_port);
6023     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6024     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6025
6026     /* Check parameter (socket = INT32_MAX) */
6027     ARG_GETPEERNAME (INT32_MAX, peer_ip, &ip_len, &peer_port);
6028     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6029     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6030
6031     /* Check parameter (port = NULL) */
6032     ip_len = sizeof(peer_ip);
6033     ARG_GETPEERNAME (sock, peer_ip, &ip_len, NULL);
6034     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6035     /* Request IP address only should be accepted */
6036     TH_ASSERT  (io.rc == 0);
6037
6038     /* Check parameter (ip = NULL, ip_len = NULL) */
6039     ARG_GETPEERNAME (sock, NULL, NULL, &peer_port);
6040     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6041     /* Request port only should be accepted */
6042     TH_ASSERT  (io.rc == 0);
6043
6044     /* Initialize buffers for return values */
6045     peer_port = 0;
6046     ip_len    = sizeof(peer_ip) + 1;
6047     memcpy (peer_ip, ip_bcast, sizeof(peer_ip));
6048
6049     /* Retrieve peer name */
6050     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6051     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6052     TH_ASSERT  (io.rc == 0);
6053     /* IP address should be the address of the server */
6054     TH_ASSERT  ((memcmp ((const void *)peer_ip, (const void *)ip_socket_server, 4) == 0) && (ip_len == 4));
6055     /* Port number should be the DISCARD port */
6056     TH_ASSERT  (peer_port == DISCARD_PORT);
6057
6058     /* Close stream socket */
6059     io.sock = sock;
6060     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6061     TH_ASSERT  (io.rc == 0);
6062
6063     /* Retrieve peer name again */
6064     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6065     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6066     /* Should return error (socket not created) */
6067     /* Strict: ESOCK, valid non-strict: ERROR */
6068     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getpeername on closed socket", io.rc, ARM_SOCKET_ESOCK);
6069
6070     osDelay (10);
6071   }
6072
6073   /* Create stream socket */
6074   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6075   if (io.rc < 0) {
6076     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6077   } else {
6078     sock = io.rc;
6079
6080     /* Get peer name, created socket */
6081     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6082     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6083     /* Should return error (socket not connected) */
6084     /* Strict: ENOTCONN, valid non-strict: ERROR */
6085     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "getpeername on created socket", io.rc, ARM_SOCKET_ENOTCONN);
6086
6087     /* Bind socket */
6088     io.sock = sock;
6089     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
6090     TH_ASSERT  (io.rc == 0);
6091
6092     /* Get peer name, bound socket */
6093     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6094     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6095     /* Should return error (socket not connected) */
6096     /* Strict: ENOTCONN, valid non-strict: ERROR */
6097     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "getpeername on bound socket", io.rc, ARM_SOCKET_ENOTCONN);
6098
6099     /* Start listening */
6100     io.sock = sock;
6101     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
6102     TH_ASSERT  (io.rc == 0);
6103
6104     /* Get peer name, listening socket */
6105     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6106     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6107     /* Should return error (socket not connected) */
6108     /* Strict: ENOTCONN, valid non-strict: ERROR */
6109     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "getpeername on listening socket", io.rc, ARM_SOCKET_ENOTCONN);
6110
6111     /* Close socket */
6112     io.sock = sock;
6113     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6114     TH_ASSERT  (io.rc == 0);
6115
6116     osDelay (10);
6117   }
6118
6119   /* Create datagram socket */
6120   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
6121   if (io.rc < 0) {
6122     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
6123   } else {
6124     sock = io.rc;
6125
6126     /* Connect to datagram server */
6127     io.sock = sock;
6128     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
6129     TH_ASSERT  (io.rc == 0);
6130
6131     /* Check parameter (socket = -1) */
6132     ip_len =  sizeof(peer_ip);
6133     ARG_GETPEERNAME (-1, peer_ip, &ip_len, &peer_port);
6134     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6135     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6136
6137     /* Check parameter (socket = INT32_MIN) */
6138     ARG_GETPEERNAME (INT32_MIN, peer_ip, &ip_len, &peer_port);
6139     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6140     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6141
6142     /* Check parameter (socket = INT32_MAX) */
6143     ARG_GETPEERNAME (INT32_MAX, peer_ip, &ip_len, &peer_port);
6144     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6145     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6146
6147     /* Check parameter (port = NULL) */
6148     ip_len = sizeof(peer_ip);
6149     ARG_GETPEERNAME (sock, peer_ip, &ip_len, NULL);
6150     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6151     /* Request IP address only should be accepted */
6152     TH_ASSERT  (io.rc == 0);
6153
6154     /* Check parameter (ip = NULL, ip_len = NULL) */
6155     ARG_GETPEERNAME (sock, NULL, NULL, &peer_port);
6156     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6157     /* Request port only should be accepted */
6158     TH_ASSERT  (io.rc == 0);
6159
6160     /* Initialize buffers for return values */
6161     peer_port = 0;
6162     ip_len    = sizeof(peer_ip) + 1;
6163     memcpy (peer_ip, ip_bcast, sizeof(peer_ip));
6164
6165     /* Retrieve peer name */
6166     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6167     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6168     TH_ASSERT  (io.rc == 0);
6169     /* IP address should be the address of the server */
6170     TH_ASSERT  ((memcmp ((const void *)peer_ip, (const void *)ip_socket_server, 4) == 0) && (ip_len == 4));
6171     /* Port number should be the DISCARD port */
6172     TH_ASSERT  (peer_port == DISCARD_PORT);
6173
6174     /* Close socket */
6175     io.sock = sock;
6176     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6177     TH_ASSERT  (io.rc == 0);
6178
6179     /* Retrieve peer name again */
6180     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6181     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6182     /* Should return error (socket not created) */
6183     /* Strict: ESOCK, valid non-strict: ERROR */
6184     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getpeername on closed socket", io.rc, ARM_SOCKET_ESOCK);
6185
6186     osDelay (10);
6187   }
6188
6189   if (rval == 0) {
6190     station_uninit ();
6191   }
6192
6193   /* Terminate worker thread */
6194   osThreadTerminate (worker);
6195 }
6196
6197 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
6198
6199 /* GetOpt IO parameters */
6200 #ifndef __DOXYGEN__                     // Exclude form the documentation
6201 typedef struct {
6202   int32_t      sock;
6203   int32_t      opt_id;
6204   void        *opt_val;
6205   uint32_t    *opt_len;
6206   int32_t      rc;
6207   /* Control */
6208   osThreadId_t owner;
6209   uint32_t     xid;
6210 } IO_GETOPT;
6211 #endif
6212
6213 /* Assign arguments */
6214 #define ARG_GETOPT(_sock,_opt_id,_opt_val,_opt_len) do {                     \
6215                                                       io.sock    = _sock;    \
6216                                                       io.opt_id  = _opt_id;  \
6217                                                       io.opt_val = _opt_val; \
6218                                                       io.opt_len = _opt_len; \
6219                                                     } while (0)
6220
6221 /* GetOpt worker thread */
6222 __NO_RETURN static void Th_GetOpt (IO_GETOPT *io) {
6223   uint32_t flags,xid;
6224
6225   for (;;) {
6226     /* Wait for the signal to select and execute the function */
6227     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP |
6228                                F_GETOPT     | F_CLOSE, osFlagsWaitAny, osWaitForever);
6229     xid   = io->xid;
6230     switch (flags) {
6231       case F_CREATE_TCP:
6232         /* Create stream socket */
6233         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
6234         break;
6235
6236       case F_CREATE_UDP:
6237         /* Create datagram socket */
6238         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
6239         break;
6240
6241       case F_GETOPT:
6242         /* Get socket options */
6243         io->rc = drv->SocketGetOpt (io->sock, io->opt_id, io->opt_val, io->opt_len);
6244         break;
6245
6246       case F_CLOSE:
6247         /* Close socket */
6248         io->rc = drv->SocketClose (io->sock);
6249         break;
6250     }
6251     /* Done, send signal to owner thread */
6252     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
6253     osDelay(1);
6254     osThreadFlagsSet (io->owner, flags);
6255     osThreadFlagsClear (F_ALL);
6256   }
6257 }
6258
6259 /**
6260 \brief  Function: WIFI_SocketGetOpt
6261 \ingroup wifi_sock_api
6262 \details
6263 The test function \b WIFI_SocketGetOpt verifies the WiFi Driver \b SocketGetOpt function:
6264 \code
6265 int32_t (*SocketGetOpt) (int32_t socket, int32_t opt_id, void *opt_val, uint32_t *opt_len);
6266 \endcode
6267
6268 Stream socket test:
6269  - Create stream socket
6270  - Check function parameters
6271  - Get socket options
6272  - Close socket
6273  - Get socket options again, closed socket
6274
6275 Datagram socket test:
6276  - Create datagram socket
6277  - Get socket type
6278  - Close socket
6279  - Get socket type
6280 */
6281 void WIFI_SocketGetOpt (void) {
6282   uint32_t     opt_val;
6283   uint32_t     opt_len;
6284   osThreadId_t worker;
6285   int32_t      rval;
6286   IO_GETOPT    io;
6287   int32_t      sock;
6288
6289   if (socket_funcs_exist == 0U) {
6290     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
6291     return;
6292   }
6293
6294   if (station_init (1) == 0) {
6295     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
6296     return;
6297   }
6298
6299   /* Create worker thread */
6300   worker = osThreadNew ((osThreadFunc_t)Th_GetOpt, &io, NULL);
6301   if (worker == NULL) {
6302     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
6303     return;
6304   }
6305
6306   ARG_INIT();
6307
6308   /* Create stream socket */
6309   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6310   if (io.rc < 0) {
6311     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6312   } else {
6313     sock = io.rc;
6314  
6315     /* Check parameter (socket = -1) */
6316     opt_len = sizeof(opt_val);
6317     ARG_GETOPT (-1, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6318     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6319     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6320
6321     /* Check parameter (socket = INT32_MIN) */
6322     ARG_GETOPT (INT32_MIN, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6323     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6324     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6325
6326     /* Check parameter (socket = INT32_MAX) */
6327     ARG_GETOPT (INT32_MAX, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6328     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6329     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6330
6331     /* Check parameter (opt_id = -1) */
6332     ARG_GETOPT (sock, -1, &opt_val, &opt_len);
6333     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6334     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6335
6336     /* Check parameter (opt_id = INT32_MIN) */
6337     ARG_GETOPT (sock, INT32_MIN, &opt_val, &opt_len);
6338     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6339     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6340
6341     /* Check parameter (opt_id = INT32_MAX) */
6342     ARG_GETOPT (sock, INT32_MAX, &opt_val, &opt_len);
6343     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6344     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6345
6346     /* Check parameter (opt_val = NULL) */
6347     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, NULL, &opt_len);
6348     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6349     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6350
6351     /* Check parameter (opt_len = NULL) */
6352     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, NULL);
6353     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6354     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6355
6356     /* Check parameter (*opt_len = 0) */
6357     opt_len = 0;
6358     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6359     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6360     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6361
6362     /* Check parameter (*opt_len = 5) */
6363     opt_len = 5;
6364     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6365     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6366     TH_ASSERT  ((io.rc == 0) && (opt_len == 4));
6367
6368     /* Get option FIONBIO (set only) */
6369     opt_len = sizeof(opt_val);
6370     ARG_GETOPT (sock, ARM_SOCKET_IO_FIONBIO, &opt_val, &opt_len);
6371     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6372     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6373
6374     /* Get option RCVTIMEO */
6375     opt_len = sizeof(opt_val) + 1;
6376     opt_val = 0xE2A5A241;
6377     ARG_GETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, &opt_len);
6378     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6379     TH_ASSERT  (io.rc == 0);
6380     /* Should be different from the initial value */
6381     TH_ASSERT  ((opt_val != 0xE2A5A241) && (opt_len == 4));
6382
6383     /* Get option SNDTIMEO */
6384     opt_len = sizeof(opt_val) + 1;
6385     opt_val = 0xE2A5A241;
6386     ARG_GETOPT (sock, ARM_SOCKET_SO_SNDTIMEO, &opt_val, &opt_len);
6387     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6388     TH_ASSERT  (io.rc == 0);
6389     /* Should be different from the initial value */
6390     TH_ASSERT  ((opt_val != 0xE2A5A241) && (opt_len == 4));
6391
6392     /* Get option KEEPALIVE */
6393     opt_len = sizeof(opt_val) + 1;
6394     opt_val = 0xE2A5A241;
6395     ARG_GETOPT (sock, ARM_SOCKET_SO_KEEPALIVE, &opt_val, &opt_len);
6396     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6397     TH_ASSERT  (io.rc == 0);
6398     /* Should be different from the initial value */
6399     TH_ASSERT  ((opt_val != 0xE2A5A241) && (opt_len == 4));
6400
6401     /* Get option socket TYPE */
6402     opt_len = sizeof(opt_val) + 1;
6403     opt_val = UINT32_MAX;
6404     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6405     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6406     TH_ASSERT  (io.rc == 0);
6407     /* Should be SOCK_STREAM type */
6408     TH_ASSERT  ((opt_val == ARM_SOCKET_SOCK_STREAM) && (opt_len == 4));
6409
6410     /* Close stream socket */
6411     io.sock = sock;
6412     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6413     TH_ASSERT  (io.rc == 0);
6414
6415     /* Get option socket TYPE again */
6416     opt_len = sizeof(opt_val);
6417     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6418     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6419     /* Should return error (socket not created) */
6420     /* Strict: ESOCK, valid non-strict: ERROR */
6421     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
6422
6423     osDelay (10);
6424   }
6425
6426   /* Create datagram socket */
6427   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
6428   if (io.rc < 0) {
6429     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
6430   } else {
6431     sock = io.rc;
6432
6433     /* Get option socket TYPE */
6434     opt_len = sizeof(opt_val) + 1;
6435     opt_val = UINT32_MAX;
6436     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6437     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6438     TH_ASSERT  (io.rc == 0);
6439     /* Should be SOCK_DGRAM type */
6440     TH_ASSERT  ((opt_val == ARM_SOCKET_SOCK_DGRAM) && (opt_len == 4));
6441
6442     /* Close socket */
6443     io.sock = sock;
6444     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6445     TH_ASSERT  (io.rc == 0);
6446
6447     /* Get option socket TYPE again */
6448     opt_len = sizeof(opt_val);
6449     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6450     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6451     /* Should return error (socket not created) */
6452     /* Strict: ESOCK, valid non-strict: ERROR */
6453     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
6454
6455     osDelay (10);
6456   }
6457
6458   if (rval == 0) {
6459     station_uninit ();
6460   }
6461
6462   /* Terminate worker thread */
6463   osThreadTerminate (worker);
6464 }
6465
6466 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
6467
6468 /* SetOpt IO parameters */
6469 #ifndef __DOXYGEN__                     // Exclude form the documentation
6470 typedef struct {
6471   int32_t      sock;
6472   int32_t      opt_id;
6473   const void  *opt_val;
6474   uint32_t     opt_len;
6475   int32_t      rc;
6476   /* Control */
6477   osThreadId_t owner;
6478   uint32_t     xid;
6479 } IO_SETOPT;
6480 #endif
6481
6482 /* Assign arguments */
6483 #define ARG_SETOPT(_sock,_opt_id,_opt_val,_opt_len) do {                     \
6484                                                       io.sock    = _sock;    \
6485                                                       io.opt_id  = _opt_id;  \
6486                                                       io.opt_val = _opt_val; \
6487                                                       io.opt_len = _opt_len; \
6488                                                     } while (0)
6489
6490 /* SetOpt worker thread */
6491 __NO_RETURN static void Th_SetOpt (IO_SETOPT *io) {
6492   uint32_t flags,xid;
6493
6494   for (;;) {
6495     /* Wait for the signal to select and execute the function */
6496     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_SETOPT | F_CLOSE, osFlagsWaitAny, osWaitForever);
6497     xid   = io->xid;
6498     switch (flags) {
6499       case F_CREATE_TCP:
6500         /* Create stream socket */
6501         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
6502         break;
6503
6504       case F_CREATE_UDP:
6505         /* Create datagram socket */
6506         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
6507         break;
6508
6509       case F_SETOPT:
6510         /* Set socket options */
6511         io->rc = drv->SocketSetOpt (io->sock, io->opt_id, io->opt_val, io->opt_len);
6512         break;
6513
6514       case F_CLOSE:
6515         /* Close socket */
6516         io->rc = drv->SocketClose (io->sock);
6517         break;
6518     }
6519     /* Done, send signal to owner thread */
6520     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
6521     osDelay(1);
6522     osThreadFlagsSet (io->owner, flags);
6523     osThreadFlagsClear (F_ALL);
6524   }
6525 }
6526
6527 /**
6528 \brief  Function: WIFI_SocketSetOpt
6529 \ingroup wifi_sock_api
6530 \details
6531 The test function \b WIFI_SocketSetOpt verifies the WiFi Driver \b SocketSetOpt function:
6532 \code
6533 int32_t (*SocketSetOpt) (int32_t socket, int32_t opt_id, const void *opt_val, uint32_t opt_len);
6534 \endcode
6535
6536 Stream socket test:
6537  - Create stream socket
6538  - Check function parameters
6539  - Set socket options
6540  - Close socket
6541  - Set socket option again, closed socket
6542
6543 Datagram socket test:
6544  - Create datagram socket
6545  - Set socket options
6546  - Close socket
6547  - Set socket option again, closed socket
6548 */
6549
6550 void WIFI_SocketSetOpt (void) {
6551   uint32_t     opt_val;
6552   osThreadId_t worker;
6553   int32_t      rval;
6554   IO_SETOPT    io;
6555   int32_t      sock;
6556
6557   if (socket_funcs_exist == 0U) {
6558     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
6559     return;
6560   }
6561
6562   if (station_init (1) == 0) {
6563     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
6564     return;
6565   }
6566
6567   /* Create worker thread */
6568   worker = osThreadNew ((osThreadFunc_t)Th_SetOpt, &io, NULL);
6569   if (worker == NULL) {
6570     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
6571     return;
6572   }
6573
6574   ARG_INIT();
6575
6576   /* Create stream socket */
6577   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6578   if (io.rc < 0) {
6579     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6580   } else {
6581     sock = io.rc;
6582  
6583     /* Check parameter (socket = -1) */
6584     opt_val = 5000;
6585     ARG_SETOPT (-1, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6586     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6587     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6588
6589     /* Check parameter (socket = INT32_MIN) */
6590     ARG_SETOPT (-1, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6591     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6592     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6593
6594     /* Check parameter (socket = INT32_MAX) */
6595     ARG_SETOPT (-1, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6596     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6597     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6598
6599     /* Check parameter (opt_id = -1) */
6600     ARG_SETOPT (sock, -1, &opt_val, sizeof(opt_val));
6601     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6602     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6603
6604     /* Check parameter (opt_id = INT32_MIN) */
6605     ARG_SETOPT (sock, INT32_MIN, &opt_val, sizeof(opt_val));
6606     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6607     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6608
6609     /* Check parameter (opt_id = INT32_MAX) */
6610     ARG_SETOPT (sock, INT32_MAX, &opt_val, sizeof(opt_val));
6611     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6612     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6613
6614     /* Check parameter (opt_val = NULL) */
6615     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, NULL, sizeof(opt_val));
6616     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6617     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6618
6619     /* Check parameter (opt_len = 0) */
6620     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, 0);
6621     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6622     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6623
6624     /* Check parameter (opt_len = 3) */
6625     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, 3);
6626     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6627     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6628
6629     /* Set option FIONBIO (set only) */
6630     opt_val = 0;
6631     ARG_SETOPT (sock, ARM_SOCKET_IO_FIONBIO, &opt_val, sizeof(opt_val));
6632     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6633     TH_ASSERT  (io.rc == 0);
6634
6635     /* Set option RCVTIMEO */
6636     opt_val = 5000;
6637     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6638     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6639     TH_ASSERT  (io.rc == 0);
6640
6641     /* Set option SNDTIMEO */
6642     opt_val = 2000;
6643     ARG_SETOPT (sock, ARM_SOCKET_SO_SNDTIMEO, &opt_val, sizeof(opt_val));
6644     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6645     TH_ASSERT  (io.rc == 0);
6646
6647     /* Set option KEEPALIVE */
6648     opt_val = 1;
6649     ARG_SETOPT (sock, ARM_SOCKET_SO_KEEPALIVE, &opt_val, sizeof(opt_val));
6650     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6651     TH_ASSERT  (io.rc == 0);
6652
6653     /* Set option socket TYPE (get only) */
6654     opt_val = ARM_SOCKET_SOCK_STREAM;
6655     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, sizeof(opt_val));
6656     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6657     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6658
6659     /* Close stream socket */
6660     io.sock = sock;
6661     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6662     TH_ASSERT  (io.rc == 0);
6663
6664     /* Set option RCVTIMEO again */
6665     opt_val = 5000;
6666     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6667     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6668     /* Should return error (socket not created) */
6669     /* Strict: ESOCK, valid non-strict: ERROR */
6670     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "setsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
6671
6672     osDelay (10);
6673   }
6674
6675   /* Create datagram socket */
6676   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
6677   if (io.rc < 0) {
6678     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
6679   } else {
6680     sock = io.rc;
6681
6682     /* Set option RCVTIMEO */
6683     opt_val = 5000;
6684     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6685     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6686     TH_ASSERT  (io.rc == 0);
6687
6688     /* Close socket */
6689     io.sock = sock;
6690     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6691     TH_ASSERT  (io.rc == 0);
6692
6693     /* Set option RCVTIMEO again */
6694     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6695     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6696     /* Should return error (socket not created) */
6697     /* Strict: ESOCK, valid non-strict: ERROR */
6698     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "setsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
6699
6700     osDelay (10);
6701   }
6702
6703   if (rval == 0) {
6704     station_uninit ();
6705   }
6706
6707   /* Terminate worker thread */
6708   osThreadTerminate (worker);
6709 }
6710
6711 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
6712
6713 /* Close IO parameters */
6714 #ifndef __DOXYGEN__                     // Exclude form the documentation
6715 typedef struct {
6716   int32_t      sock;
6717   int32_t      rc;
6718   /* Control */
6719   osThreadId_t owner;
6720   uint32_t     xid;
6721 } IO_CLOSE;
6722 #endif
6723
6724 /* Assign arguments */
6725 #define ARG_CLOSE(_sock) do {               \
6726                            io.sock = _sock; \
6727                          } while (0)
6728
6729 /* Close worker thread */
6730 __NO_RETURN static void Th_Close (IO_CLOSE *io) {
6731   uint32_t flags,xid;
6732
6733   for (;;) {
6734     /* Wait for the signal to select and execute the function */
6735     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_BIND |
6736                                F_CONNECT    | F_LISTEN     | F_CLOSE, osFlagsWaitAny, osWaitForever);
6737     xid   = io->xid;
6738     switch (flags) {
6739       case F_CREATE_TCP:
6740         /* Create stream socket */
6741         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
6742         break;
6743
6744       case F_CREATE_UDP:
6745         /* Create datagram socket */
6746         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
6747         break;
6748
6749       case F_BIND:
6750         /* Bind socket */
6751         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
6752         break;
6753
6754       case F_CONNECT:
6755         /* Connect on socket */
6756         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
6757         break;
6758
6759       case F_LISTEN:
6760         /* Listen on socket */
6761         io->rc = drv->SocketListen (io->sock, 1);
6762         break;
6763
6764       case F_CLOSE:
6765         /* Close socket */
6766         io->rc = drv->SocketClose (io->sock);
6767         break;
6768     }
6769     /* Done, send signal to owner thread */
6770     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
6771     osDelay(1);
6772     osThreadFlagsSet (io->owner, flags);
6773     osThreadFlagsClear (F_ALL);
6774   }
6775 }
6776
6777 /**
6778 \brief  Function: WIFI_SocketClose
6779 \ingroup wifi_sock_api
6780 \details
6781 The test function \b WIFI_SocketClose verifies the WiFi Driver \b SocketClose function:
6782 \code
6783 int32_t (*SocketClose) (int32_t socket);
6784 \endcode
6785
6786 Stream socket test 1:
6787  - Create stream socket
6788  - Bind socket
6789  - Connect to server
6790  - Check function parameters
6791  - Close socket
6792  - Close socket again
6793
6794 Stream socket test 2:
6795  - Create stream socket
6796  - Bind socket
6797  - Start listening
6798  - Close socket
6799  - Close socket again
6800
6801 Datagram socket test:
6802  - Create datagram socket
6803  - Bind socket
6804  - Check function parameters
6805  - Close socket
6806  - Close socket again
6807 */
6808 void WIFI_SocketClose (void) {
6809   osThreadId_t worker;
6810   int32_t      rval;
6811   IO_CLOSE     io;
6812   int32_t      sock;
6813
6814   if (socket_funcs_exist == 0U) {
6815     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
6816     return;
6817   }
6818
6819   if (station_init (1) == 0) {
6820     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
6821     return;
6822   }
6823
6824   /* Create worker thread */
6825   worker = osThreadNew ((osThreadFunc_t)Th_Close, &io, NULL);
6826   if (worker == NULL) {
6827     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
6828     return;
6829   }
6830
6831   ARG_INIT();
6832
6833   /* Create stream socket */
6834   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6835   if (io.rc < 0) {
6836     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6837   } else {
6838     sock = io.rc;
6839
6840     /* Connect to stream server */
6841     io.sock = sock;
6842     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
6843     TH_ASSERT  (io.rc == 0);
6844
6845     /* Check parameter (socket = -1) */
6846     ARG_CLOSE  (-1);
6847     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6848     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6849
6850     /* Check parameter (socket = INT32_MIN) */
6851     ARG_CLOSE  (INT32_MIN);
6852     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6853     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6854
6855     /* Check parameter (socket = INT32_MAX) */
6856     ARG_CLOSE  (INT32_MAX);
6857     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6858     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6859
6860     /* Close socket */
6861     ARG_CLOSE  (sock);
6862     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6863     TH_ASSERT  (io.rc == 0);
6864
6865     /* Close again, closed socket */
6866     ARG_CLOSE  (sock);
6867     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6868     /* Should return error (socket not created) */
6869     /* Strict: ESOCK, valid non-strict: OK */
6870     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == 0), "close already closed socket", io.rc, ARM_SOCKET_ESOCK);
6871
6872     osDelay (10);
6873   }
6874
6875   /* Create stream socket */
6876   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6877   if (io.rc < 0) {
6878     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6879   } else {
6880     sock = io.rc;
6881
6882     /* Bind socket */
6883     io.sock = sock;
6884     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
6885     TH_ASSERT  (io.rc == 0);
6886
6887     /* Start listening */
6888     io.sock = sock;
6889     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
6890     TH_ASSERT  (io.rc == 0);
6891
6892     /* Close socket */
6893     ARG_CLOSE (sock);
6894     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6895     TH_ASSERT  (io.rc == 0);
6896
6897     /* Close again, closed socket */
6898     ARG_CLOSE (sock);
6899     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6900     /* Should return error (socket not created) */
6901     /* Strict: ESOCK, valid non-strict: OK */
6902     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == 0), "close already closed socket", io.rc, ARM_SOCKET_ESOCK);
6903
6904     osDelay (10);
6905   }
6906
6907   /* Create datagram socket */
6908   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
6909   if (io.rc < 0) {
6910     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
6911   } else {
6912     sock = io.rc;
6913
6914     /* Bind socket */
6915     io.sock = sock;
6916     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
6917     TH_ASSERT  (io.rc == 0);
6918
6919     /* Check parameter (socket = -1) */
6920     ARG_CLOSE  (-1);
6921     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6922     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6923
6924     /* Check parameter (socket = INT32_MIN) */
6925     ARG_CLOSE  (INT32_MIN);
6926     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6927     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6928
6929     /* Check parameter (socket = INT32_MAX) */
6930     ARG_CLOSE  (INT32_MAX);
6931     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6932     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6933
6934     /* Close socket */
6935     ARG_CLOSE  (sock);
6936     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6937     TH_ASSERT  (io.rc == 0);
6938
6939     /* Close again, closed socket */
6940     ARG_CLOSE  (sock);
6941     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6942     /* Should return error (socket not created) */
6943     /* Strict: ESOCK, valid non-strict: OK */
6944     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == 0), "close already closed socket", io.rc, ARM_SOCKET_ESOCK);
6945
6946     osDelay (10);
6947   }
6948
6949   if (rval == 0) {
6950     station_uninit ();
6951   }
6952
6953   /* Terminate worker thread */
6954   osThreadTerminate (worker);
6955 }
6956
6957 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
6958
6959 /* GetHostByName IO parameters */
6960 #ifndef __DOXYGEN__                     // Exclude form the documentation
6961 typedef struct {
6962   const char  *name;
6963   int32_t      af;
6964   uint8_t     *ip;
6965   uint32_t    *ip_len;
6966   int32_t      rc;
6967   /* Control */
6968   osThreadId_t owner;
6969   uint32_t     xid;
6970 } IO_GETHOST;
6971 #endif
6972
6973 /* Assign arguments */
6974 #define ARG_GETHOST(_name,_af,_ip,_ip_len) do {                   \
6975                                              io.name   = _name;   \
6976                                              io.af     = _af;     \
6977                                              io.ip     = _ip;     \
6978                                              io.ip_len = _ip_len; \
6979                                            } while (0)
6980
6981 /* GetHostByName worker thread */
6982 __NO_RETURN static void Th_GetHostByName (IO_GETHOST *io) {
6983   uint32_t flags,xid;
6984
6985   for (;;) {
6986     /* Wait for the signal to select and execute the function */
6987     flags = osThreadFlagsWait (F_GETHOSTBYNAME, osFlagsWaitAny, osWaitForever);
6988     xid   = io->xid;
6989     switch (flags) {
6990       case F_GETHOSTBYNAME:
6991         /* Resolve host */
6992         io->rc = drv->SocketGetHostByName (io->name, io->af, io->ip, io->ip_len);
6993         break;
6994     }
6995     /* Done, send signal to owner thread */
6996     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
6997     osDelay(1);
6998     osThreadFlagsSet (io->owner, flags);
6999     osThreadFlagsClear (F_ALL);
7000   }
7001 }
7002
7003 /**
7004 \brief  Function: WIFI_SocketGetHostByName
7005 \ingroup wifi_sock_api
7006 \details
7007 The test function \b WIFI_SocketGetHostByName the WiFi Driver \b SocketGetHostByName function:
7008 \code
7009 int32_t (*SocketGetHostByName) (const char *name, int32_t af, uint8_t *ip, uint32_t *ip_len);
7010 \endcode
7011
7012 Function test:
7013  - Check function parameters
7014  - Resolve host
7015  - Resolve non-existent host
7016
7017 \note
7018 This test requires internet connectivity to DNS server.
7019 */
7020 void WIFI_SocketGetHostByName (void) {
7021   const char  *host_name = "www.arm.com";
7022   uint8_t      host_ip[5];
7023   uint32_t     ip_len;
7024   osThreadId_t worker;
7025   int32_t      rval;
7026   IO_GETHOST   io;
7027
7028   if (socket_funcs_exist == 0U) {
7029     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
7030     return;
7031   }
7032
7033   if (station_init (1) == 0) {
7034     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7035     return;
7036   }
7037
7038   /* Create worker thread */
7039   worker = osThreadNew ((osThreadFunc_t)Th_GetHostByName, &io, NULL);
7040   if (worker == NULL) {
7041     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7042     return;
7043   }
7044
7045   ARG_INIT();
7046
7047   /* Check parameter (name = NULL) */
7048   ip_len = sizeof(host_ip);
7049   ARG_GETHOST(NULL, ARM_SOCKET_AF_INET, host_ip, &ip_len);
7050   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7051   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7052
7053   /* Check parameter (af = -1) */
7054   ARG_GETHOST(host_name, -1, host_ip, &ip_len);
7055   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7056   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7057
7058   /* Check parameter (af = INT32_MIN) */
7059   ARG_GETHOST(host_name, INT32_MIN, host_ip, &ip_len);
7060   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7061   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7062
7063   /* Check parameter (af = INT32_MAX) */
7064   ARG_GETHOST(host_name, INT32_MAX, host_ip, &ip_len);
7065   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7066   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7067
7068   /* Check parameter (ip = NULL) */
7069   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, NULL, &ip_len);
7070   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7071   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7072
7073   /* Check parameter (ip_len = NULL) */
7074   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, host_ip, NULL);
7075   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7076   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7077
7078   /* Check parameter (*ip_len = 0) */
7079   ip_len = 0;
7080   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, host_ip, &ip_len);
7081   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7082   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7083
7084   /* Check parameter (*ip_len = 3) */
7085   ip_len = 3;
7086   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, host_ip, &ip_len);
7087   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7088   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7089
7090   /* Resolve valid host */
7091   ip_len = sizeof(host_ip) + 1;
7092   memset((void *)host_ip, 0, sizeof(host_ip));
7093   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, host_ip, &ip_len);
7094   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT_LONG);
7095   /* IP address should be valid */
7096   TH_ASSERT  ((memcmp((const void *)host_ip, (const void *)ip_unspec, 4) != 0) && (ip_len == 4));
7097
7098   /* Resolve non-existent host */
7099   ip_len = sizeof(host_ip);
7100   ARG_GETHOST("non.existent.host", ARM_SOCKET_AF_INET, host_ip, &ip_len);
7101   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT_LONG);
7102   /* Should return error (host not found) */
7103   /* Strict: EHOSTNOTFOUND, valid non-strict: ERROR */
7104   TH_ASSERT2 ((io.rc == ARM_SOCKET_EHOSTNOTFOUND), (io.rc == ARM_SOCKET_ERROR), "gethostbyname for non-existing host", io.rc, ARM_SOCKET_EHOSTNOTFOUND);
7105
7106   if (rval == 0) {
7107     station_uninit ();
7108   }
7109
7110   /* Terminate worker thread */
7111   osThreadTerminate (worker);
7112 }
7113
7114 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
7115
7116 /* Ping IO parameters */
7117 #ifndef __DOXYGEN__                     // Exclude form the documentation
7118 typedef struct {
7119   const uint8_t *ip;
7120   uint32_t       ip_len;
7121   int32_t        rc;
7122   /* Control */
7123   osThreadId_t owner;
7124   uint32_t     xid;
7125 } IO_PING;
7126 #endif
7127
7128 /* Assign arguments */
7129 #define ARG_PING(_ip,_ip_len) do {                   \
7130                                 io.ip     = _ip;     \
7131                                 io.ip_len = _ip_len; \
7132                               } while (0)
7133
7134 /* Ping worker thread */
7135 __NO_RETURN static void Th_Ping (IO_PING *io) {
7136   uint32_t flags,xid;
7137
7138   for (;;) {
7139     /* Wait for the signal to select and execute the function */
7140     flags = osThreadFlagsWait (F_PING, osFlagsWaitAny, osWaitForever);
7141     xid   = io->xid;
7142     switch (flags) {
7143       case F_PING:
7144         /* Ping host */
7145         io->rc = drv->Ping (io->ip, io->ip_len);
7146         break;
7147     }
7148     /* Done, send signal to owner thread */
7149     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
7150     osDelay(1);
7151     osThreadFlagsSet (io->owner, flags);
7152     osThreadFlagsClear (F_ALL);
7153   }
7154 }
7155
7156 /**
7157 \brief  Function: WIFI_Ping
7158 \ingroup wifi_sock_api
7159 \details
7160 The test function \b WIFI_Ping verifies the WiFi Driver \b Ping function:
7161 \code
7162 int32_t (*Ping) (const uint8_t *ip, uint32_t ip_len);
7163 \endcode
7164
7165 Function test:
7166  - Check function parameters
7167  - Ping host
7168 */
7169 void WIFI_Ping (void) {
7170   osThreadId_t worker;
7171   int32_t      rval;
7172   IO_PING      io;
7173
7174   if (drv->Ping == NULL) {
7175     TEST_ASSERT_MESSAGE(0,"[FAILED] Ping function not available");
7176     return;
7177   }
7178
7179   if (station_init (1) == 0) {
7180     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7181     return;
7182   }
7183
7184   /* Create worker thread */
7185   worker = osThreadNew ((osThreadFunc_t)Th_Ping, &io, NULL);
7186   if (worker == NULL) {
7187     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7188     return;
7189   }
7190
7191   ARG_INIT();
7192
7193   /* Check parameter (ip = NULL) */
7194   ARG_PING   (NULL, 4);
7195   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
7196   TH_ASSERT  (io.rc == ARM_DRIVER_ERROR_PARAMETER);
7197
7198   /* Check parameter (ip_len = 0) */
7199   ARG_PING   (ip_socket_server, 0);
7200   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
7201   TH_ASSERT  (io.rc == ARM_DRIVER_ERROR_PARAMETER);
7202
7203   /* Check parameter (ip_len = 5) */
7204   ARG_PING   (ip_socket_server, 5);
7205   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
7206   TH_ASSERT  (io.rc == ARM_DRIVER_ERROR_PARAMETER);
7207
7208   /* Ping server */
7209   ARG_PING   (ip_socket_server, 4);
7210   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
7211   TH_ASSERT  (io.rc == ARM_DRIVER_OK);
7212
7213   if (rval == 0) {
7214     station_uninit ();
7215   }
7216
7217   /* Terminate worker thread */
7218   osThreadTerminate (worker);
7219 }
7220
7221 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
7222
7223 /**
7224 \defgroup wifi_sock_op Socket Operation
7225 \ingroup wifi_tests
7226 \details 
7227 These tests verify operation of the WiFi socket functions.
7228 */
7229
7230 /* Worker thread is used for the following tests:
7231    - WIFI_Transfer_Fixed
7232    - WIFI_Transfer_Incremental
7233    - WIFI_Send_Fragmented
7234    - WIFI_Recv_Fragmented
7235    - WIFI_Test_Speed
7236    - WIFI_Concurrent_Socket
7237 */
7238
7239 /* Transfer IO parameters */
7240 #ifndef __DOXYGEN__                     // Exclude form the documentation
7241 typedef struct {
7242   int32_t      sock;
7243   uint32_t     len;
7244   uint32_t     size;
7245   int32_t      rc;
7246   /* Control */
7247   osThreadId_t owner;
7248   uint32_t     xid;
7249   int32_t      tcp;
7250 } IO_TRANSFER;
7251 #endif
7252
7253 /* Assign arguments */
7254 #define ARG_TRANSFER(_sock,_len,_size) do {               \
7255                                          io.sock = _sock; \
7256                                          io.len  = _len;  \
7257                                          io.size = _size; \
7258                                        } while (0)
7259
7260 /* Transfer worker thread */
7261 __NO_RETURN static void Th_Transfer (IO_TRANSFER *io) {
7262   uint32_t flags,xid,i,j;
7263   int32_t  rc = 0;
7264
7265   for (;;) {
7266     /* Wait for the signal to select and execute the function */
7267     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP |
7268                                F_CONNECT    | F_CLOSE      |
7269                                F_XFER_FIXED | F_XFER_INCR  |
7270                                F_SEND_FRAG  | F_RECV_FRAG, osFlagsWaitAny, osWaitForever);
7271     xid   = io->xid;
7272     switch (flags) {
7273       case F_CREATE_TCP:
7274         /* Create stream socket */
7275         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
7276         break;
7277
7278       case F_CREATE_UDP:
7279         /* Create datagram socket */
7280         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
7281         break;
7282
7283       case F_CONNECT:
7284         /* Connect on socket */
7285         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, ECHO_PORT);
7286         break;
7287
7288       case F_CLOSE:
7289         /* Close socket */
7290         io->rc = drv->SocketClose (io->sock);
7291         break;
7292
7293       case F_XFER_FIXED:
7294         /* Transfer Fixed size blocks */
7295         memset ((void *)buffer, 0xCC, io->len);
7296         /* Send and receive in small blocks */
7297         for (i = 0; i < io->len; i += io->size) {
7298           rc = drv->SocketSend (io->sock, &test_buf[i], io->size);
7299           if (rc <= 0) break;
7300           for (j = 0; j < io->size; j += (uint32_t)rc) {
7301             /* Returns any data available, up to requested amount */
7302             rc = drv->SocketRecv (io->sock, &buffer[i+j], io->size-j);
7303             if ((rc <= 0) || !io->tcp) break;
7304           }
7305           if (rc <= 0) break;
7306         }
7307         if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
7308           rc = (int32_t)i;
7309         }
7310         io->rc = rc;
7311         break;
7312
7313       case F_XFER_INCR:
7314         /* Transfer Increased size blocks */
7315         memset ((void *)buffer, 0xCC, io->len);
7316         /* Send and receive in enlarged block sizes */
7317         for (i = 0; i < io->len; i += io->size++) {
7318           rc = drv->SocketSend (io->sock, &test_buf[i], io->size);
7319           if (rc <= 0) break;
7320           rc = drv->SocketRecv (io->sock, &buffer[i], io->size);
7321           if (rc <= 0) break;
7322         }
7323         if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
7324           rc = (int32_t)i;
7325         }
7326         io->rc = rc;
7327         break;
7328
7329       case F_SEND_FRAG:
7330         /* Send Fragmented blocks */
7331         memset ((void *)buffer, 0xCC, io->len);
7332         /* Send in small blocks */
7333         for (i = 0; i < io->len; i += io->size) {
7334           rc = drv->SocketSend (io->sock, &test_buf[i], io->size);
7335           if (rc <= 0) break;
7336         }
7337         /* Receive in single block */
7338         if (rc > 0) {
7339           /* Small delay that blocks are received */
7340           osDelay (100);
7341           for (i = 0; i < io->len; i += (uint32_t)rc) {
7342             /* Returns any data available, up to requested amount */
7343             rc = drv->SocketRecv (io->sock, &buffer[i], io->len-i);
7344             if (rc <= 0) break;
7345           }
7346           if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
7347             rc = (int32_t)i;
7348           }
7349         }
7350         io->rc = rc;
7351         break;
7352
7353       case F_RECV_FRAG:
7354         /* Receive Fragmented blocks */
7355         memset ((void *)buffer, 0xCC, io->len);
7356         /* Send single block */
7357         rc = drv->SocketSend (io->sock, test_buf, io->len);
7358         if (rc > 0) {
7359           osDelay (100);
7360           /* Receive in small blocks */
7361           for (i = 0; i < io->len; i += io->size) {
7362             for (j = 0; j < io->size; j += (uint32_t)rc) {
7363               /* Returns any data available, up to requested amount */
7364               rc = drv->SocketRecv (io->sock, &buffer[i+j], io->size-j);
7365               if (rc <= 0) break;
7366             }
7367             if (rc <= 0) break;
7368           }
7369           if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
7370             rc = (int32_t)i;
7371           }
7372         }
7373         io->rc = rc;
7374         break;
7375     }
7376     /* Done, send signal to owner thread */
7377     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
7378     osDelay(1);
7379     osThreadFlagsSet (io->owner, flags);
7380     osThreadFlagsClear (F_ALL);
7381   }
7382 }
7383
7384 /**
7385 \brief  Function: WIFI_Transfer_Fixed
7386 \ingroup wifi_sock_op
7387 \details
7388 The test function \b WIFI_Transfer_Fixed verifies data transfer in fixed size blocks.
7389  
7390 Stream socket test: 
7391  - Create stream socket
7392  - Transfer 128 blocks of   16 bytes
7393  - Transfer  32 blocks of   64 bytes
7394  - Transfer   8 blocks of  256 bytes
7395  - Transfer   2 blocks of 1024 bytes
7396  - Transfer   1 block  of 2048 bytes
7397  - Close socket
7398
7399 Datagram socket test:
7400  - Create datagram socket
7401  - Transfer 128 blocks of   16 bytes
7402  - Transfer  32 blocks of   64 bytes
7403  - Transfer   8 blocks of  256 bytes
7404  - Transfer   2 blocks of 1024 bytes
7405  - Transfer   1 block  of 1460 bytes
7406  - Close socket
7407 */
7408 void WIFI_Transfer_Fixed (void) {
7409   osThreadId_t worker;
7410   int32_t      rval;
7411   IO_TRANSFER  io;
7412   int32_t      sock;
7413
7414   if (station_init (1) == 0) {
7415     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7416     return;
7417   }
7418
7419   /* Create worker thread */
7420   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
7421   if (worker == NULL) {
7422     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7423     return;
7424   }
7425
7426   ARG_INIT();
7427
7428   /* Create stream socket */
7429   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7430   if (io.rc < 0) {
7431     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7432   } else {
7433     sock = io.rc;
7434
7435     /* Connect to stream server */
7436     io.tcp  = 1;
7437     io.sock = sock;
7438     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7439     TH_ASSERT  (io.rc == 0);
7440
7441     /* Transfer 16-byte block(s) */
7442     ARG_TRANSFER (sock, 2048, 16);
7443     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7444     TH_ASSERT  (io.rc == 2048);
7445
7446     /* Transfer 64-byte block(s) */
7447     ARG_TRANSFER (sock, 2048, 64);
7448     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7449     TH_ASSERT  (io.rc == 2048);
7450
7451     /* Transfer 256-byte block(s) */
7452     ARG_TRANSFER (sock, 2048, 256);
7453     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7454     TH_ASSERT  (io.rc == 2048);
7455
7456     /* Transfer 1024-byte block(s) */
7457     ARG_TRANSFER (sock, 2048, 1024);
7458     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7459     TH_ASSERT  (io.rc == 2048);
7460
7461     /* Transfer 2048-byte block */
7462     ARG_TRANSFER (sock, 2048, 2048);
7463     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7464     TH_ASSERT  (io.rc == 2048);
7465
7466     /* Close stream socket */
7467     io.sock = sock;
7468     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7469     TH_ASSERT  (io.rc == 0);
7470
7471     osDelay (10);
7472   }
7473
7474   /* Create datagram socket */
7475   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
7476   if (io.rc < 0) {
7477     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
7478   } else {
7479     sock = io.rc;
7480
7481     /* Connect to datagram server */
7482     io.tcp  = 0;
7483     io.sock = sock;
7484     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
7485     TH_ASSERT  (io.rc == 0);
7486
7487     /* Transfer 16-byte block(s) */
7488     ARG_TRANSFER (sock, 2048, 16);
7489     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7490     TH_ASSERT  (io.rc == 2048);
7491
7492     /* Transfer 64-byte block(s) */
7493     ARG_TRANSFER (sock, 2048, 64);
7494     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7495     TH_ASSERT  (io.rc == 2048);
7496
7497     /* Transfer 256-byte block(s) */
7498     ARG_TRANSFER (sock, 2048, 256);
7499     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7500     TH_ASSERT  (io.rc == 2048);
7501
7502     /* Transfer 1024-byte block(s) */
7503     ARG_TRANSFER (sock, 2048, 1024);
7504     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7505     TH_ASSERT  (io.rc == 2048);
7506
7507     /* Transfer 1460-byte block */
7508     ARG_TRANSFER (sock, 1460, 1460);
7509     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7510     TH_ASSERT  (io.rc == 1460);
7511
7512     /* Close datagram socket */
7513     io.sock = sock;
7514     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7515     TH_ASSERT  (io.rc == 0);
7516
7517     osDelay (10);
7518   }
7519
7520   if (rval == 0) {
7521     station_uninit ();
7522   }
7523
7524   /* Terminate worker thread */
7525   osThreadTerminate (worker);
7526 }
7527
7528 /**
7529 \brief  Function: WIFI_Transfer_Incremental
7530 \ingroup wifi_sock_op
7531 \details
7532 The test function \b WIFI_Transfer_Incremental verifies data transfer in ascending size blocks.
7533 Each subsequent block that the socket sends is one byte larger than the previous block.
7534
7535 Stream socket test:
7536  - Create stream socket
7537  - Transfer 51 blocks of   1 -  50 bytes
7538  - Transfer 30 blocks of  51 -  80 bytes
7539  - Transfer 20 blocks of  81 - 100 bytes
7540  - Transfer 13 blocks of 120 - 132 bytes
7541  - Transfer  8 blocks of 252 - 259 bytes
7542  - Transfer  4 blocks of 510 - 513 bytes
7543  - Close socket
7544
7545 Datagram socket test:
7546  - Create datagram socket
7547  - Transfer 51 blocks of   1 -  50 bytes
7548  - Transfer 30 blocks of  51 -  80 bytes
7549  - Transfer 20 blocks of  81 - 100 bytes
7550  - Transfer 13 blocks of 120 - 132 bytes
7551  - Transfer  8 blocks of 252 - 259 bytes
7552  - Transfer  4 blocks of 510 - 513 bytes
7553  - Close socket
7554 */
7555 void WIFI_Transfer_Incremental (void) {
7556   osThreadId_t worker;
7557   int32_t      rval;
7558   IO_TRANSFER  io;
7559   int32_t      sock;
7560
7561   if (station_init (1) == 0) {
7562     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7563     return;
7564   }
7565
7566   /* Create worker thread */
7567   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
7568   if (worker == NULL) {
7569     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7570     return;
7571   }
7572
7573   ARG_INIT();
7574
7575   /* Create stream socket */
7576   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7577   if (io.rc < 0) {
7578     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7579   } else {
7580     sock = io.rc;
7581
7582     /* Connect to stream server */
7583     io.sock = sock;
7584     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7585     TH_ASSERT  (io.rc == 0);
7586
7587     /* Transfer 1 byte - 50 byte blocks */
7588     ARG_TRANSFER (sock, 1275, 1);
7589     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7590     TH_ASSERT  (io.rc == 1275);
7591
7592     /* Transfer 51 byte - 80-byte blocks */
7593     ARG_TRANSFER (sock, 1965, 51);
7594     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7595     TH_ASSERT  (io.rc == 1965);
7596
7597     /* Transfer 81 byte - 100 byte blocks */
7598     ARG_TRANSFER (sock, 1810, 81);
7599     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7600     TH_ASSERT  (io.rc == 1810);
7601
7602     /* Transfer 120 byte - 132 byte blocks */
7603     ARG_TRANSFER (sock, 1905, 120);
7604     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7605     TH_ASSERT  (io.rc == 1905);
7606
7607     /* Transfer 252 byte - 259 byte blocks */
7608     ARG_TRANSFER (sock, 2044, 252);
7609     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7610     TH_ASSERT  (io.rc == 2044);
7611
7612     /* Transfer 510 byte - 513 byte blocks */
7613     ARG_TRANSFER (sock, 2046, 510);
7614     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7615     TH_ASSERT  (io.rc == 2046);
7616
7617     /* Close stream socket */
7618     io.sock = sock;
7619     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7620     TH_ASSERT  (io.rc == 0);
7621
7622     osDelay (10);
7623   }
7624
7625   /* Create datagram socket */
7626   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
7627   if (io.rc < 0) {
7628     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
7629   } else {
7630     sock = io.rc;
7631
7632     /* Connect to datagram server */
7633     io.sock = sock;
7634     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
7635     TH_ASSERT  (io.rc == 0);
7636
7637     /* Transfer 1 byte - 50 byte blocks */
7638     ARG_TRANSFER (sock, 1275, 1);
7639     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7640     TH_ASSERT  (io.rc == 1275);
7641
7642     /* Transfer 51 byte - 80-byte blocks */
7643     ARG_TRANSFER (sock, 1965, 51);
7644     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7645     TH_ASSERT  (io.rc == 1965);
7646
7647     /* Transfer 81 byte - 100 byte blocks */
7648     ARG_TRANSFER (sock, 1810, 81);
7649     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7650     TH_ASSERT  (io.rc == 1810);
7651
7652     /* Transfer 120 byte - 132 byte blocks */
7653     ARG_TRANSFER (sock, 1905, 120);
7654     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7655     TH_ASSERT  (io.rc == 1905);
7656
7657     /* Transfer 252 byte - 259 byte blocks */
7658     ARG_TRANSFER (sock, 2044, 252);
7659     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7660     TH_ASSERT  (io.rc == 2044);
7661
7662     /* Transfer 510 byte - 513 byte blocks */
7663     ARG_TRANSFER (sock, 2046, 510);
7664     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7665     TH_ASSERT  (io.rc == 2046);
7666
7667     /* Close datagram socket */
7668     io.sock = sock;
7669     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7670     TH_ASSERT  (io.rc == 0);
7671
7672     osDelay (10);
7673   }
7674
7675   if (rval == 0) {
7676     station_uninit ();
7677   }
7678
7679   /* Terminate worker thread */
7680   osThreadTerminate (worker);
7681 }
7682
7683 /**
7684 \brief  Function: WIFI_Send_Fragmented
7685 \ingroup wifi_sock_op
7686 \details
7687 The test function \b WIFI_Send_Fragmented verifies data transfer in chunks.
7688
7689 Stream socket test:
7690  - Create stream socket
7691  - Send 16 blocks of   16 bytes, receive 1 block of  256 bytes
7692  - Send 16 blocks of   64 bytes, receive 1 block of 1024 bytes
7693  - Send  5 blocks of  256 bytes, receive 1 block of 1280 bytes
7694  - Send  2 blocks of 1024 bytes, receive 1 block of 2048 bytes
7695  - Close socket
7696 */
7697 void WIFI_Send_Fragmented (void) {
7698   osThreadId_t worker;
7699   int32_t      rval;
7700   IO_TRANSFER  io;
7701   int32_t      sock;
7702
7703   if (station_init (1) == 0) {
7704     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7705     return;
7706   }
7707
7708   /* Create worker thread */
7709   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
7710   if (worker == NULL) {
7711     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7712     return;
7713   }
7714
7715   ARG_INIT();
7716
7717   /* Create stream socket */
7718   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7719   if (io.rc < 0) {
7720     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7721   } else {
7722     sock = io.rc;
7723
7724     /* Connect to stream server */
7725     io.sock = sock;
7726     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7727     TH_ASSERT  (io.rc == 0);
7728
7729     /* Transfer 16-byte block(s) */
7730     ARG_TRANSFER (sock, 256, 16);
7731     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7732     TH_ASSERT  (io.rc == 256);
7733
7734     /* Transfer 64-byte block(s) */
7735     ARG_TRANSFER (sock, 1024, 64);
7736     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7737     TH_ASSERT  (io.rc == 1024);
7738
7739     /* Transfer 256-byte block(s) */
7740     ARG_TRANSFER (sock, 1280, 256);
7741     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7742     TH_ASSERT  (io.rc == 1280);
7743
7744     /* Transfer 1024-byte block(s) */
7745     ARG_TRANSFER (sock, 2048, 1024);
7746     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7747     TH_ASSERT  (io.rc == 2048);
7748
7749     /* Close stream socket */
7750     io.sock = sock;
7751     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7752     TH_ASSERT  (io.rc == 0);
7753
7754     osDelay (10);
7755   }
7756
7757   if (rval == 0) {
7758     station_uninit ();
7759   }
7760
7761   /* Terminate worker thread */
7762   osThreadTerminate (worker);
7763 }
7764
7765 /**
7766 \brief  Function: WIFI_Recv_Fragmented
7767 \ingroup wifi_sock_op
7768 \details
7769 The test function \b WIFI_Recv_Fragmented verifies data transfer in chunks.
7770
7771 Stream socket test:
7772  - Create stream socket
7773  - Send block of  256 bytes, receive 16 blocks of   16 bytes
7774  - Send block of 1024 bytes, receive 16 blocks of   64 bytes
7775  - Send block of 1280 bytes, receive  5 blocks of  256 bytes
7776  - Send block of 2048 bytes, receive  2 blocks of 1024 bytes
7777  - Close socket
7778 */
7779 void WIFI_Recv_Fragmented (void) {
7780   osThreadId_t worker;
7781   int32_t      rval;
7782   IO_TRANSFER  io;
7783   int32_t      sock;
7784
7785   if (station_init (1) == 0) {
7786     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7787     return;
7788   }
7789
7790   /* Create worker thread */
7791   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
7792   if (worker == NULL) {
7793     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7794     return;
7795   }
7796
7797   ARG_INIT();
7798
7799   /* Create stream socket */
7800   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7801   if (io.rc < 0) {
7802     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7803   } else {
7804     sock = io.rc;
7805
7806     /* Connect to stream server */
7807     io.sock = sock;
7808     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7809     TH_ASSERT  (io.rc == 0);
7810
7811     /* Transfer 16-byte block(s) */
7812     ARG_TRANSFER (sock, 256, 16);
7813     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7814     TH_ASSERT  (io.rc == 256);
7815
7816     /* Transfer 64-byte block(s) */
7817     ARG_TRANSFER (sock, 1024, 64);
7818     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7819     TH_ASSERT  (io.rc == 1024);
7820
7821     /* Transfer 256-byte block(s) */
7822     ARG_TRANSFER (sock, 1280, 256);
7823     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7824     TH_ASSERT  (io.rc == 1280);
7825
7826     /* Transfer 1024-byte block(s) */
7827     ARG_TRANSFER (sock, 2048, 1024);
7828     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7829     TH_ASSERT  (io.rc == 2048);
7830
7831     /* Close stream socket */
7832     io.sock = sock;
7833     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7834     TH_ASSERT (io.rc == 0);
7835
7836     osDelay (10);
7837   }
7838
7839   if (rval == 0) {
7840     station_uninit ();
7841   }
7842
7843   /* Terminate worker thread */
7844   osThreadTerminate (worker);
7845 }
7846
7847 /**
7848 \brief  Function: WIFI_Test_Speed
7849 \ingroup wifi_sock_op
7850 \details
7851 The test function \b WIFI_Test_Speed tests data transfer speed.
7852
7853 Stream socket test:
7854  - Create stream socket
7855  - Transfer for 4 seconds, send and receive
7856  - Calculate transfer rate
7857  - Close socket
7858
7859 Datagram socket test:
7860  - Create datagram socket
7861  - Transfer for 4 seconds, send and receive
7862  - Calculate transfer rate
7863  - Close socket
7864 */
7865 void WIFI_Test_Speed (void) {
7866   uint32_t     ticks,tout;
7867   osThreadId_t worker;
7868   int32_t      rval,n_bytes;
7869   IO_TRANSFER  io;
7870   int32_t      sock;
7871
7872   if (station_init (1) == 0) {
7873     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7874     return;
7875   }
7876
7877   /* Create worker thread */
7878   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
7879   if (worker == NULL) {
7880     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7881     return;
7882   }
7883
7884   ARG_INIT();
7885
7886   /* Create stream socket */
7887   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7888   if (io.rc < 0) {
7889     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7890   } else {
7891     sock = io.rc;
7892
7893     /* Connect to stream server */
7894     io.tcp  = 1;
7895     io.sock = sock;
7896     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7897     TH_ASSERT  (io.rc == 0);
7898
7899     /* Transfer for 4 seconds */
7900     tout  = SYSTICK_MICROSEC(4000000);
7901     ticks = GET_SYSTICK();
7902     n_bytes = 0;
7903     do {
7904       ARG_TRANSFER (sock, 1420, 1420);
7905       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7906       if (io.rc > 0) n_bytes += io.rc;
7907       else           break;
7908     } while (GET_SYSTICK() - ticks < tout);
7909     /* Check transfer rate */
7910     if (n_bytes < 10000) {
7911       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
7912       TEST_MESSAGE(msg_buf);
7913     }
7914
7915     /* Close stream socket */
7916     io.sock = sock;
7917     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7918     TH_ASSERT  (io.rc == 0);
7919
7920     osDelay (10);
7921   }
7922
7923   /* Create datagram socket */
7924   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
7925   if (io.rc < 0) {
7926     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
7927   } else {
7928     sock = io.rc;
7929
7930     /* Connect to datagram server */
7931     io.tcp  = 0;
7932     io.sock = sock;
7933     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
7934     TH_ASSERT  (io.rc == 0);
7935
7936     /* Transfer for 4 seconds */
7937     tout  = SYSTICK_MICROSEC(4000000);
7938     ticks = GET_SYSTICK();
7939     n_bytes = 0;
7940     do {
7941       ARG_TRANSFER (sock, 1460, 1460);
7942       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7943       if (io.rc > 0) n_bytes += io.rc;
7944       else           break;
7945     } while (GET_SYSTICK() - ticks < tout);
7946     /* Check transfer rate */
7947     if (n_bytes < 10000) {
7948       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
7949       TEST_MESSAGE(msg_buf);
7950     }
7951
7952     /* Close datagram socket */
7953     io.sock = sock;
7954     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7955     TH_ASSERT  (io.rc == 0);
7956
7957     osDelay (10);
7958   }
7959
7960   if (rval == 0) {
7961     station_uninit ();
7962   }
7963
7964   /* Terminate worker thread */
7965   osThreadTerminate (worker);
7966 }
7967
7968 /* Sidekick IO parameters */
7969 #ifndef __DOXYGEN__                     // Exclude form the documentation
7970 typedef struct {
7971   int32_t  sock;
7972   uint32_t count;
7973 } IO_SIDEKICK;
7974 #endif
7975
7976 /* Concurrent coworker thread */
7977 __NO_RETURN static void Th_Sidekick (IO_SIDEKICK *io2) {
7978   uint8_t buff[48];
7979   int32_t rc;
7980
7981   for (;;) {
7982     if (osThreadFlagsWait (SK_TERMINATE, osFlagsWaitAny, 200) == SK_TERMINATE) {
7983       break;
7984     }
7985     memset ((void *)buff, 0xCC, sizeof(buff));
7986     rc = drv->SocketSend (io2->sock, test_msg, sizeof(test_msg));
7987     if (rc <= 0) break;
7988     rc = drv->SocketRecv (io2->sock, buff, sizeof(test_msg));
7989     if (rc <= 0) break;
7990     if (memcmp ((const void *)buff, (const void *)test_msg, sizeof(test_msg)) == 0) {
7991       io2->count += sizeof(test_msg);
7992     }
7993   }
7994   /* Owner deletes this thread */
7995   while (1) osDelay (osWaitForever);
7996 }
7997
7998 /**
7999 \brief  Function: WIFI_Concurrent_Socket
8000 \ingroup wifi_sock_op
8001 \details
8002 The test function \b WIFI_Concurrent_Socket verifies transfer of two concurrent sockets.
8003
8004 Stream socket test:
8005  - Create two stream sockets
8006  - Start transfer on 2nd socket with 200ms intervals
8007  - Transfer on main socket, full speed
8008  - Calculate transfer rate
8009  - Close sockets
8010
8011 Datagram socket test:
8012  - Create datagram and stream sockets
8013  - Start transfer on stream socket with 200ms intervals
8014  - Transfer on main socket, full speed
8015  - Calculate transfer rate
8016  - Close sockets
8017 \note
8018 The test runs with a coherent thread, that performs an additional stream socket io.
8019 */
8020 void WIFI_Concurrent_Socket (void) {
8021   uint32_t     ticks,tout;
8022   osThreadId_t worker,spawn;
8023   int32_t      rval,n_bytes;
8024   IO_TRANSFER  io;
8025   IO_SIDEKICK  io2;
8026   int32_t      sock;
8027
8028   if (station_init (1) == 0) {
8029     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8030     return;
8031   }
8032
8033   /* Create worker thread */
8034   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
8035   if (worker == NULL) {
8036     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8037     return;
8038   }
8039
8040   ARG_INIT();
8041
8042   /* The test connects two stream sockets to the ECHO server and then    */
8043   /* performs simultaneous data transfer. The main socket transmits at   */
8044   /* full speed, and the other socket sends messages at 200ms intervals. */
8045   /* Both sockets record the number of bytes of data transferred, and    */
8046   /* the transfer rate is calculated.                                    */
8047
8048   /* Create stream socket */
8049   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8050   if (io.rc < 0) {
8051     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8052   } else {
8053     sock = io.rc;
8054
8055     /* Create 2nd stream socket */
8056     TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8057     if (io.rc < 0) {
8058       TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8059     }
8060     io2.sock  = io.rc;
8061     io2.count = 0;
8062
8063     /* Connect sockets */
8064     io.tcp  = 1;
8065     io.sock = sock;
8066     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
8067     TH_ASSERT  (io.rc == 0);
8068
8069     io.sock = io2.sock;
8070     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
8071     TH_ASSERT  (io.rc == 0);
8072
8073     /* Create spawned thread */
8074     spawn = osThreadNew ((osThreadFunc_t)Th_Sidekick, &io2, NULL);
8075     TEST_ASSERT(spawn != NULL);
8076
8077     /* Transfer for 4 seconds */
8078     tout  = SYSTICK_MICROSEC(4000000);
8079     ticks = GET_SYSTICK();
8080     n_bytes = 0;
8081     do {
8082       ARG_TRANSFER (sock, 1420, 1420);
8083       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8084       if (io.rc > 0) n_bytes += io.rc;
8085       else           break;
8086     } while (GET_SYSTICK() - ticks < tout);
8087     /* Check main transfer rate */
8088     if (n_bytes < 10000) {
8089       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
8090       TEST_MESSAGE(msg_buf);
8091     }
8092     /* Check auxiliary transfer rate */
8093     if (io2.count == 0) {
8094       TEST_ASSERT_MESSAGE(0,"[FAILED] Auxiliary transfer failed");
8095     }
8096     else if (io2.count < 440) {
8097       TEST_MESSAGE("[WARNING] Auxiliary Transfer rate low");
8098     }
8099
8100     /* Terminate spawned thread */
8101     osThreadFlagsSet (spawn, SK_TERMINATE);
8102     osDelay(100);
8103     osThreadTerminate (spawn);
8104
8105     /* Close stream sockets */
8106     io.sock = io2.sock;
8107     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8108     TH_ASSERT  (io.rc == 0);
8109
8110     io.sock = sock;
8111     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8112     TH_ASSERT  (io.rc == 0);
8113
8114     osDelay (10);
8115   }
8116
8117   /* The test connects datagram and stream sockets to the ECHO server     */
8118   /* and then performs simultaneous data transfer. The datagram socket    */
8119   /* transmits at full speed, and the stream socket sends messages at     */
8120   /* 200ms intervals. The number of bytes of transferred data is recorded */
8121   /* and the rate of transmission is calculated.                          */
8122
8123   /* Create datagram socket */
8124   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
8125   if (io.rc < 0) {
8126     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
8127   } else {
8128     sock = io.rc;
8129
8130     /* Connect datagram socket */
8131     io.tcp  = 0;
8132     io.sock = sock;
8133     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
8134     TH_ASSERT  (io.rc == 0);
8135
8136     /* Create stream socket */
8137     TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8138     if (io.rc < 0) {
8139       TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8140     }
8141     io2.sock  = io.rc;
8142     io2.count = 0;
8143
8144     /* Connect stream socket */
8145     io.sock = io2.sock;
8146     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
8147     TH_ASSERT  (io.rc == 0);
8148
8149     /* Create spawned thread */
8150     spawn = osThreadNew ((osThreadFunc_t)Th_Sidekick, &io2, NULL);
8151     TEST_ASSERT(spawn != NULL);
8152
8153     /* Transfer for 4 seconds */
8154     tout  = SYSTICK_MICROSEC(4000000);
8155     ticks = GET_SYSTICK();
8156     n_bytes = 0;
8157     do {
8158       ARG_TRANSFER (sock, 1460, 1460);
8159       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8160       if (io.rc > 0) n_bytes += io.rc;
8161       else           break;
8162     } while (GET_SYSTICK() - ticks < tout);
8163     /* Check main transfer rate */
8164     if (n_bytes < 10000) {
8165       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
8166       TEST_MESSAGE(msg_buf);
8167     }
8168     /* Check auxiliary transfer rate */
8169     if (io2.count == 0) {
8170       TEST_ASSERT_MESSAGE(0,"[FAILED] Auxiliary transfer failed");
8171     }
8172     else if (io2.count < 440) {
8173       TEST_MESSAGE("[WARNING] Auxiliary Transfer rate low");
8174     }
8175
8176     /* Terminate spawned thread */
8177     osThreadFlagsSet (spawn, SK_TERMINATE);
8178     osDelay(100);
8179     osThreadTerminate (spawn);
8180
8181     /* Close sockets */
8182     io.sock = io2.sock;
8183     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8184     TH_ASSERT  (io.rc == 0);
8185
8186     io.sock = sock;
8187     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8188     TH_ASSERT  (io.rc == 0);
8189
8190     osDelay (10);
8191   }
8192
8193   if (rval == 0) {
8194     station_uninit ();
8195   }
8196
8197   /* Terminate worker thread */
8198   osThreadTerminate (worker);
8199 }
8200
8201 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
8202
8203 /* TestAssistant commands */
8204 #define CMD_SEND_TCP        "SEND TCP,1420,4000"
8205 #define CMD_RECV_TCP        "RECV TCP,1420"
8206 #define TEST_BSIZE          1420
8207
8208 /* StreamRate IO parameters */
8209 #ifndef __DOXYGEN__                     // Exclude form the documentation
8210 typedef struct {
8211   int32_t      sock;
8212   int32_t      rc;
8213   /* Control */
8214   osThreadId_t owner;
8215   uint32_t     xid;
8216   int32_t      loss;
8217   const char  *cmd;
8218 } IO_STREAMRATE;
8219 #endif
8220
8221 /* StreamRate coworker thread */
8222 __NO_RETURN static void Th_StreamRate (IO_STREAMRATE *io) {
8223   uint32_t flags,xid,ticks,tout;
8224   int32_t  n,rc,i,val;
8225
8226   for (;;) {
8227     flags = osThreadFlagsWait (F_CREATE_TCP | F_DOWNLOAD | F_UPLOAD |
8228                                F_SEND_CTRL  | F_CLOSE, osFlagsWaitAny, osWaitForever);
8229     xid   = io->xid;
8230     switch (flags) {
8231       case F_CREATE_TCP:
8232         /* Create stream socket */
8233         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
8234         break;
8235
8236       case F_DOWNLOAD:
8237         /* Downstream test, server is sender */
8238         for (n = 0; ; n += rc) {
8239           rc = drv->SocketRecv (io->sock, buffer, TEST_BSIZE);
8240           if (strncmp ((char *)buffer, "STAT", 4) == 0) {
8241             /* Server completed the test */
8242             sscanf ((char *)buffer+4, "%d", &val);
8243             if (val > n) io->loss = val - n;
8244             break;
8245           }
8246           if (rc <= 0) break;
8247         }
8248         io->rc = n;
8249         break;
8250
8251       case F_UPLOAD:
8252         /* Upstream test, server is receiver */
8253         memset ((void *)buffer, 'a', TEST_BSIZE);
8254         tout  = SYSTICK_MICROSEC(4000000);
8255         ticks = GET_SYSTICK();
8256         i = n = 0;
8257         do {
8258           snprintf ((char *)buffer, sizeof(buffer), "Block[%d]", ++i);
8259           rc = drv->SocketSend (io->sock, buffer, TEST_BSIZE);
8260           if (rc > 0) n += rc;
8261         } while (GET_SYSTICK() - ticks < tout);
8262         rc = snprintf ((char *)buffer, sizeof(buffer), "STOP %d bytes.", n);
8263         drv->SocketSend (io->sock, buffer, (uint32_t)rc);
8264         /* Receive report from server */
8265         drv->SocketRecv (io->sock, buffer, TEST_BSIZE);
8266         if (strncmp ((char *)buffer, "STAT", 4) == 0) {
8267           sscanf ((char *)buffer+4, "%d", &val);
8268           if (n > val) io->loss = n - val;
8269         }
8270         io->rc = n;
8271         break;
8272
8273       case F_CLOSE:
8274         /* Close socket */
8275         io->rc = drv->SocketClose (io->sock);
8276         break;
8277
8278       case F_SEND_CTRL:
8279         /* Send control command to TestAssistant */
8280         drv->SocketConnect (io->sock, ip_socket_server, 4, ASSISTANT_PORT);
8281         io->rc = drv->SocketSend (io->sock, io->cmd, strlen(io->cmd));
8282         break;
8283     }
8284     /* Done, send signal to owner thread */
8285     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
8286     osDelay(1);
8287     osThreadFlagsSet (io->owner, flags);
8288     osThreadFlagsClear (F_ALL);
8289   }
8290 }
8291
8292 /**
8293 \brief  Function: WIFI_Downstream_Rate
8294 \ingroup wifi_sock_op
8295 \details
8296 The test function \b WIFI_Downstream_Rate tests the maximum rate at which the data
8297 can be received.
8298 */
8299 void WIFI_Downstream_Rate (void) {
8300   osThreadId_t  worker;
8301   int32_t       rval;
8302   IO_STREAMRATE io;
8303
8304   if (station_init (1) == 0) {
8305     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8306     return;
8307   }
8308
8309   /* Create worker thread */
8310   worker = osThreadNew ((osThreadFunc_t)Th_StreamRate, &io, NULL);
8311   if (worker == NULL) {
8312     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8313     return;
8314   }
8315
8316   ARG_INIT();
8317
8318   /* Create stream socket */
8319   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8320   if (io.rc < 0) {
8321     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8322   } else {
8323     io.sock = io.rc;
8324
8325     /* Send command to start the download */
8326     io.cmd = CMD_SEND_TCP;
8327     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
8328     TH_ASSERT  (io.rc > 0);
8329
8330     /* Wait for transfer to complete */
8331     io.loss = 0;
8332     TH_EXECUTE (F_DOWNLOAD, 5000 + WIFI_SOCKET_TIMEOUT);
8333     TH_ASSERT  (io.rc > 0);
8334
8335     /* Check data loss */
8336     if (io.loss) {
8337       snprintf(msg_buf, sizeof(msg_buf), "[FAILED] Data loss %d byte(s)", io.loss);
8338       TEST_ASSERT_MESSAGE(0,msg_buf);
8339     }
8340     else if (rval != 0) {
8341       snprintf(msg_buf, sizeof(msg_buf), "[INFO] Speed %d KB/s", io.rc/4096);
8342       TEST_MESSAGE(msg_buf);
8343     }
8344
8345     /* Close stream socket */
8346     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8347     TH_ASSERT  (io.rc == 0);
8348
8349     osDelay (10);
8350   }
8351
8352   if (rval == 0) {
8353     station_uninit ();
8354   }
8355
8356   /* Terminate worker thread */
8357   osThreadTerminate (worker);
8358 }
8359
8360 /**
8361 \brief  Function: WIFI_Upstream_Rate
8362 \ingroup wifi_sock_op
8363 \details
8364 The test function \b WIFI_Upstream_Rate tests the maximum rate at which the data
8365 can be sent.
8366 */
8367 void WIFI_Upstream_Rate (void) {
8368   osThreadId_t  worker;
8369   int32_t       rval;
8370   IO_STREAMRATE io;
8371
8372   if (station_init (1) == 0) {
8373     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8374     return;
8375   }
8376
8377   /* Create worker thread */
8378   worker = osThreadNew ((osThreadFunc_t)Th_StreamRate, &io, NULL);
8379   if (worker == NULL) {
8380     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8381     return;
8382   }
8383
8384   ARG_INIT();
8385
8386   /* Create stream socket */
8387   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8388   if (io.rc < 0) {
8389     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8390   } else {
8391     io.sock = io.rc;
8392
8393     /* Send command to start the upload */
8394     io.cmd = CMD_RECV_TCP;
8395     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
8396     TH_ASSERT  (io.rc > 0);
8397
8398     /* Wait for transfer to complete */
8399     io.loss = 0;
8400     TH_EXECUTE (F_UPLOAD, 5000 + WIFI_SOCKET_TIMEOUT);
8401     TH_ASSERT  (io.rc > 0);
8402
8403     /* Check data loss */
8404     if (io.loss) {
8405       snprintf(msg_buf, sizeof(msg_buf), "[FAILED] Data loss %d byte(s)", io.loss);
8406       TEST_ASSERT_MESSAGE(0,msg_buf);
8407     }
8408     else if (rval != 0) {
8409       snprintf(msg_buf, sizeof(msg_buf), "[INFO] Speed %d KB/s", io.rc/4096);
8410       TEST_MESSAGE(msg_buf);
8411     }
8412
8413     /* Close stream socket */
8414     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8415     TH_ASSERT  (io.rc == 0);
8416
8417     osDelay (10);
8418   }
8419
8420   if (rval == 0) {
8421     station_uninit ();
8422   }
8423
8424   /* Terminate worker thread */
8425   osThreadTerminate (worker);
8426 }