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