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