]> begriffs open source - cmsis-driver-validation/blob - Source/DV_WIFI.c
Minor corrections to the documentation
[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 checks:
187 - API interface compliance.
188 - Some of Control and Management operation.
189 - Socket operation with various transfer sizes and communication parameters.
190 - Socket performance tests.
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   return (0);
3006 }
3007
3008 #define TH_EXECUTE(sig,tout) do {                                                \
3009                                io.xid++;                                         \
3010                                rval = th_execute (worker, sig, tout);            \
3011                                if (rval == 0) {                                  \
3012                                  /* Function timeout expired */                                           \
3013                                  snprintf(msg_buf, sizeof(msg_buf), "Execution timeout (%d ms)", tout);   \
3014                                  TEST_ASSERT_MESSAGE(0,msg_buf);                 \
3015                                }                                                 \
3016                              } while (0)
3017
3018 #define TH_ASSERT(cond)      do {                                                \
3019                                if (rval) { TEST_ASSERT(cond); }                  \
3020                              } while (0)
3021
3022 #define TH_ASSERT2(c1,c2,s1,r1,r2) do {                                          \
3023                                if (rval) {                                       \
3024                                  if (!c2) { TEST_ASSERT(c1); }                   \
3025                                  else {                                          \
3026                                    snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Non BSD-strict, %s (result %s, expected %s)", s1, str_sock_ret[-r1], str_sock_ret[-r2]); \
3027                                    TEST_MESSAGE(msg_buf);                        \
3028                                  }                                               \
3029                                }                                                 \
3030                              } while (0)
3031
3032 #define ARG_INIT()           do {                                                \
3033                                io.owner = osThreadGetId ();                      \
3034                                io.xid   = 0;                                     \
3035                              } while (0)
3036
3037 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
3038
3039 /* Create IO parameters */
3040 typedef struct {
3041   int32_t      sock;
3042   int32_t      af;
3043   int32_t      type;
3044   int32_t      protocol;
3045   int32_t      rc;
3046   /* Control */
3047   osThreadId_t owner;
3048   uint32_t     xid;
3049 } IO_CREATE;
3050
3051 /* Assign arguments */
3052 #define ARG_CREATE(_af,_type,_proto) do {                     \
3053                                        io.af       = _af;     \
3054                                        io.type     = _type;   \
3055                                        io.protocol = _proto;  \
3056                                      } while (0)
3057
3058 /* Create worker thread */
3059 __NO_RETURN static void Th_Create (IO_CREATE *io) {
3060   uint32_t flags, xid;
3061
3062   for (;;) {
3063     flags = osThreadFlagsWait (F_CREATE | F_CLOSE, osFlagsWaitAny, osWaitForever);
3064     xid   = io->xid;
3065     switch (flags) {
3066       case F_CREATE:
3067         /* Create socket */
3068         io->rc = drv->SocketCreate (io->af, io->type, io->protocol);
3069         break;
3070
3071       case F_CLOSE:
3072         /* Close socket */
3073         io->rc = drv->SocketClose (io->sock);
3074         break;
3075     }
3076     /* Done, send signal to owner thread */
3077     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
3078     osDelay(1);
3079     osThreadFlagsSet (io->owner, flags);
3080     osThreadFlagsClear (F_ALL);
3081   }
3082 }
3083
3084 /**
3085 \brief  Test case: WIFI_SocketCreate
3086 \ingroup wifi_sock_api
3087 \details
3088 The test case \b WIFI_SocketCreate verifies the WiFi Driver \b SocketCreate function:
3089 \code
3090 int32_t (*SocketCreate) (int32_t af, int32_t type, int32_t protocol);
3091 \endcode
3092
3093 Create socket test:
3094  - Check function parameters 
3095  - Create multiple stream sockets
3096  - Gradually close stream sockets and create datagram sockets
3097  - Close datagram sockets
3098 */
3099 void WIFI_SocketCreate (void) { 
3100   osThreadId_t worker;
3101   int32_t      rval;
3102   IO_CREATE    io;
3103   int32_t      sock[WIFI_SOCKET_MAX_NUM], i;
3104
3105   if (socket_funcs_exist == 0U) {
3106     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
3107     return;
3108   }
3109
3110   if (station_init (1) == 0) {
3111     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
3112     return;
3113   }
3114
3115   /* Create worker thread */
3116   worker = osThreadNew ((osThreadFunc_t)Th_Create, &io, NULL);
3117   if (worker == NULL) {
3118     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
3119     return;
3120   }
3121
3122   ARG_INIT();
3123
3124   /* Check parameter (af = -1) */
3125   ARG_CREATE (-1, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3126   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3127   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3128
3129   /* Check parameter (af = INT32_MIN) */
3130   ARG_CREATE (INT32_MIN, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3131   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3132   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3133
3134   /* Check parameter (af = INT32_MAX) */
3135   ARG_CREATE (INT32_MAX, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3136   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3137   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3138
3139   /* Check parameter (type = -1) */
3140   ARG_CREATE (ARM_SOCKET_AF_INET, -1, ARM_SOCKET_IPPROTO_TCP);
3141   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3142   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3143
3144   /* Check parameter (type = INT32_MIN) */
3145   ARG_CREATE (ARM_SOCKET_AF_INET, INT32_MIN, ARM_SOCKET_IPPROTO_TCP);
3146   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3147   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3148
3149   /* Check parameter (type = INT32_MAX) */
3150   ARG_CREATE (ARM_SOCKET_AF_INET, INT32_MAX, ARM_SOCKET_IPPROTO_TCP);
3151   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3152   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3153
3154   /* Check parameter, stream socket (protocol = -1) */
3155   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, -1);
3156   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3157   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3158
3159   /* Check parameter, stream socket (protocol = INT32_MIN) */
3160   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, INT32_MIN);
3161   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3162   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3163
3164   /* Check parameter, stream socket (protocol = INT32_MAX) */
3165   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, INT32_MAX);
3166   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3167   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3168
3169   /* Check parameter, datagram socket (protocol = -1) */
3170   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, -1);
3171   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3172   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3173
3174   /* Check parameter, datagram socket (protocol = INT32_MIN) */
3175   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, INT32_MIN);
3176   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3177   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3178
3179   /* Check parameter, datagram socket (protocol = INT32_MAX) */
3180   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, INT32_MAX);
3181   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3182   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3183
3184   /* Check parameter, stream socket (protocol = ARM_SOCKET_IPPROTO_UDP) */
3185   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_UDP);
3186   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3187   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3188
3189   /* Check parameter, datagram socket (protocol = ARM_SOCKET_IPPROTO_TCP) */
3190   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_TCP);
3191   TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3192   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3193
3194   /* Create multiple stream sockets */
3195   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3196   for (i = 0; i < WIFI_SOCKET_MAX_NUM; i++) {
3197     TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3198     TH_ASSERT  (io.rc >= 0);
3199     sock[i] = io.rc;
3200   }
3201   osDelay (10);
3202
3203   /* Gradually close stream sockets, create datagram sockets */
3204   ARG_CREATE (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
3205   for (i = 0; i < WIFI_SOCKET_MAX_NUM; i++) {
3206     /* Close stream socket */
3207     io.sock = sock[i];
3208     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3209     TH_ASSERT  (io.rc == 0);
3210
3211     /* Create datagram socket */
3212     TH_EXECUTE (F_CREATE, WIFI_SOCKET_TIMEOUT);
3213     TH_ASSERT  (io.rc >= 0);
3214     sock[i] = io.rc;
3215   }
3216   osDelay (10);
3217
3218   /* Close datagram sockets */
3219   for (i = 0; i < WIFI_SOCKET_MAX_NUM; i++) {
3220     io.sock = sock[i];
3221     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3222     TH_ASSERT  (io.rc == 0);
3223   }
3224   osDelay (10);
3225
3226   if (rval == 0) {
3227     station_uninit ();
3228   }
3229
3230   /* Terminate worker thread */
3231   osThreadTerminate (worker);
3232 }
3233
3234 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
3235
3236 /* Bind IO parameters */
3237 typedef struct {
3238   int32_t        sock;
3239   const uint8_t *ip;
3240   uint32_t       ip_len;
3241   uint16_t       port;
3242   uint16_t       reserved;
3243   int32_t        rc;
3244   /* Control */
3245   osThreadId_t   owner;
3246   uint32_t       xid;
3247 } IO_BIND;
3248
3249 /* Assign arguments */
3250 #define ARG_BIND(_sock,_ip,_ip_len,_port) do {                   \
3251                                             io.sock   = _sock;   \
3252                                             io.ip     = _ip;     \
3253                                             io.ip_len = _ip_len; \
3254                                             io.port   = _port;   \
3255                                           } while (0)
3256
3257 /* Bind worker thread */
3258 __NO_RETURN static void Th_Bind (IO_BIND *io) {
3259   uint32_t flags,xid;
3260
3261   for (;;) {
3262     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_BIND | F_CLOSE, osFlagsWaitAny, osWaitForever);
3263     xid   = io->xid;
3264     switch (flags) {
3265       case F_CREATE_TCP:
3266         /* Create stream socket */
3267         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3268         break;
3269
3270       case F_CREATE_UDP:
3271         /* Create datagram socket */
3272         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
3273         break;
3274
3275       case F_BIND:
3276         /* Bind socket */
3277         io->rc = drv->SocketBind (io->sock, io->ip, io->ip_len, io->port);
3278         break;
3279
3280       case F_CLOSE:
3281         /* Close socket */
3282         io->rc = drv->SocketClose (io->sock);
3283         break;
3284     }
3285     /* Done, send signal to owner thread */
3286     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
3287     osDelay(1);
3288     osThreadFlagsSet (io->owner, flags);
3289     osThreadFlagsClear (F_ALL);
3290   }
3291 }
3292
3293 /**
3294 \brief  Test case: WIFI_SocketBind
3295 \ingroup wifi_sock_api
3296 \details
3297 The test case \b WIFI_SocketBind verifies the WiFi Driver \b SocketBind function:
3298 \code
3299 int32_t (*SocketBind) (int32_t socket, const uint8_t *ip, uint32_t  ip_len, uint16_t  port);
3300 \endcode
3301
3302 Stream socket test:
3303  - Create stream socket
3304  - Check function parameters 
3305  - Bind stream socket
3306  - Bind socket second time
3307  - Create 2nd stream socket
3308  - Bind 2nd socket, used port
3309  - Bind 2nd socket, unused port
3310  - Close stream sockets
3311  - Bind closed socket
3312
3313 Datagram socket test: 
3314  - Create datagram socket
3315  - Bind datagram socket
3316  - Bind socket second time
3317  - Create 2nd datagram socket
3318  - Bind 2nd socket, used port
3319  - Bind 2nd socket, unused port
3320  - Close datagram socket
3321  - Bind closed socket
3322 */
3323 void WIFI_SocketBind (void) { 
3324   osThreadId_t worker;
3325   int32_t      rval;
3326   IO_BIND      io;
3327   int32_t      sock,sock2;
3328
3329   if (socket_funcs_exist == 0U) {
3330     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
3331     return;
3332   }
3333
3334   if (station_init (1) == 0) {
3335     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
3336     return;
3337   }
3338
3339   /* Create worker thread */
3340   worker = osThreadNew ((osThreadFunc_t)Th_Bind, &io, NULL);
3341   if (worker == NULL) {
3342     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
3343     return;
3344   }
3345
3346   ARG_INIT();
3347
3348   /* Create stream socket */
3349   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
3350   if (io.rc < 0) {
3351     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
3352   } else {
3353     sock = io.rc;
3354
3355     /* Check parameter (socket = -1) */
3356     ARG_BIND   (-1, ip_unspec, 4, DISCARD_PORT);
3357     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3358     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3359
3360     /* Check parameter (socket = INT32_MIN) */
3361     ARG_BIND (INT32_MIN, ip_unspec, 4, DISCARD_PORT);
3362     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3363     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3364
3365     /* Check parameter (socket = INT32_MAX) */
3366     ARG_BIND (INT32_MAX, ip_unspec, 4, DISCARD_PORT);
3367     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3368     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3369
3370     /* Check parameter (ip = NULL) */
3371     ARG_BIND (sock, NULL, 4, DISCARD_PORT);
3372     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3373     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3374
3375     /* Check parameter (ip_len = 0) */
3376     ARG_BIND (sock, ip_unspec, 0, DISCARD_PORT);
3377     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3378     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3379
3380     /* Check parameter (ip_len = UINT32_MAX) */
3381     ARG_BIND (sock, ip_unspec, UINT32_MAX, DISCARD_PORT);
3382     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3383     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3384
3385     /* Check parameter (port = 0) */
3386     ARG_BIND (sock, ip_unspec, 4, 0);
3387     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3388     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3389
3390     /* Bind socket */
3391     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3392     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3393     TH_ASSERT  (io.rc == 0);
3394
3395     /* Bind socket 2nd time */
3396     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3397     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3398     /* Should return error (socket already bound) */
3399     /* Strict: EINVAL, valid non-strict: OK, ERROR */
3400     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);
3401
3402     /* Create 2nd stream socket */
3403     TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
3404     if (io.rc < 0) {
3405       TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
3406     }
3407     sock2 = io.rc;
3408
3409     /* Bind 2nd socket, used port */
3410     ARG_BIND (sock2, ip_unspec, 4, DISCARD_PORT);
3411     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3412     /* Should return error (address already used) */
3413     /* Strict: EADDRINUSE, valid non-strict: ERROR */
3414     TH_ASSERT2 ((io.rc == ARM_SOCKET_EADDRINUSE), (io.rc == ARM_SOCKET_ERROR), "bind another socket to used address", io.rc, ARM_SOCKET_EADDRINUSE);
3415
3416     /* Bind 2nd socket, unused port */
3417     ARG_BIND (sock2, ip_unspec, 4, ECHO_PORT);
3418     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3419     TH_ASSERT  (io.rc == 0);
3420
3421     /* Close sockets */
3422     io.sock = sock2;
3423     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3424     TH_ASSERT  (io.rc == 0);
3425
3426     io.sock = sock;
3427     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3428     TH_ASSERT  (io.rc == 0);
3429
3430     /* Bind again, closed socket */
3431     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3432     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3433     /* Should return error (socket not created) */
3434     /* Strict: ESOCK, valid non-strict: ERROR */
3435     /* Return code strict: ESOCK, non-strict: ERROR */
3436     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "bind on closed socket", io.rc, ARM_SOCKET_ESOCK);
3437
3438     osDelay (10);
3439   }
3440
3441   /* Create datagram socket */
3442   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
3443   if (io.rc < 0) {
3444     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
3445   } else {
3446     sock = io.rc;
3447
3448     /* Check parameter (socket = -1) */
3449     ARG_BIND (-1, ip_unspec, 4, DISCARD_PORT);
3450     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3451     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3452
3453     /* Check parameter (socket = INT32_MIN) */
3454     ARG_BIND (INT32_MIN, ip_unspec, 4, DISCARD_PORT);
3455     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3456     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3457
3458     /* Check parameter (socket = INT32_MAX) */
3459     ARG_BIND (INT32_MAX, ip_unspec, 4, DISCARD_PORT);
3460     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3461     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3462
3463     /* Check parameter (ip = NULL) */
3464     ARG_BIND (sock, NULL, 4, DISCARD_PORT);
3465     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3466     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3467
3468     /* Check parameter (ip_len = 0) */
3469     ARG_BIND (sock, ip_unspec, 0, DISCARD_PORT);
3470     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3471     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3472
3473     /* Check parameter (ip_len = UINT32_MAX) */
3474     ARG_BIND (sock, ip_unspec, UINT32_MAX, DISCARD_PORT);
3475     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3476     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3477
3478     /* Check parameter (port = 0) */
3479     ARG_BIND (sock, ip_unspec, 4, 0);
3480     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3481     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
3482
3483     /* Bind socket */
3484     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3485     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3486     TH_ASSERT  (io.rc == 0);
3487
3488     /* Bind socket 2nd time */
3489     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3490     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3491     /* Should return error (socket already bound) */
3492     /* Strict: EINVAL, valid non-strict: OK, ERROR */
3493     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);
3494
3495     /* Create 2nd datagram socket */
3496     TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
3497     if (io.rc < 0) {
3498       TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
3499     }
3500     sock2 = io.rc;
3501
3502     /* Bind 2nd socket, used port */
3503     ARG_BIND (sock2, ip_unspec, 4, DISCARD_PORT);
3504     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3505     /* Should return error (address already used) */
3506     /* Strict: EADDRINUSE, valid non-strict: ERROR */
3507     TH_ASSERT2 ((io.rc == ARM_SOCKET_EADDRINUSE), (io.rc == ARM_SOCKET_ERROR), "bind another socket to used address", io.rc, ARM_SOCKET_EADDRINUSE);
3508
3509     /* Bind 2nd socket, unused port */
3510     ARG_BIND (sock2, ip_unspec, 4, ECHO_PORT);
3511     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3512     TH_ASSERT  (io.rc == 0);
3513
3514     /* Close sockets */
3515     io.sock = sock2;
3516     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3517     TH_ASSERT  (io.rc == 0);
3518
3519     io.sock = sock;
3520     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3521     TH_ASSERT  (io.rc == 0);
3522
3523     /* Bind again, closed socket */
3524     ARG_BIND (sock, ip_unspec, 4, DISCARD_PORT);
3525     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3526     /* Should return error (socket not created) */
3527     /* Strict: ESOCK, valid non-strict: ERROR */
3528     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "bind on closed socket", io.rc, ARM_SOCKET_ESOCK);
3529
3530     osDelay (10);
3531   }
3532
3533   if (rval == 0) {
3534     station_uninit ();
3535   }
3536
3537   /* Terminate worker thread */
3538   osThreadTerminate (worker);
3539 }
3540
3541 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
3542
3543 /* Listen IO parameters */
3544 typedef struct {
3545   int32_t      sock;
3546   int32_t      backlog;
3547   int32_t      rc;
3548   /* Control */
3549   osThreadId_t owner;
3550   uint32_t     xid;
3551 } IO_LISTEN;
3552
3553 /* Assign arguments */
3554 #define ARG_LISTEN(_sock,_backlog) do {                     \
3555                                      io.sock    = _sock;    \
3556                                      io.backlog = _backlog; \
3557                                    } while (0)
3558
3559 /* Listen worker thread */
3560 __NO_RETURN static void Th_Listen (IO_LISTEN *io) {
3561   uint32_t flags,xid;
3562
3563   for (;;) {
3564     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP |
3565                                F_BIND       | F_LISTEN     | F_CLOSE, osFlagsWaitAny, osWaitForever);
3566     xid   = io->xid;
3567     switch (flags) {
3568       case F_CREATE_TCP:
3569         /* Create stream socket */
3570         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3571         break;
3572
3573       case F_CREATE_UDP:
3574         /* Create datagram socket */
3575         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
3576         break;
3577
3578       case F_BIND:
3579         /* Bind socket */
3580         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
3581         break;
3582
3583       case F_LISTEN:
3584         /* Listen on socket */
3585         io->rc = drv->SocketListen (io->sock, io->backlog);
3586         break;
3587
3588       case F_CLOSE:
3589         /* Close socket */
3590         io->rc = drv->SocketClose (io->sock);
3591         break;
3592     }
3593     /* Done, send signal to owner thread */
3594     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
3595     osDelay(1);
3596     osThreadFlagsSet (io->owner, flags);
3597     osThreadFlagsClear (F_ALL);
3598   }
3599 }
3600
3601 /**
3602 \brief  Test case: WIFI_SocketListen
3603 \ingroup wifi_sock_api
3604 \details
3605 The test case \b WIFI_SocketListen verifies the WiFi Driver \b SocketListen function:
3606 \code
3607 int32_t (*SocketListen) (int32_t socket, int32_t backlog);
3608 \endcode
3609
3610 Stream socket test 1:
3611  - Create stream socket
3612  - Bind socket
3613  - Check function parameters 
3614  - Start listening
3615  - Start listening 2nd time
3616  - Close socket
3617
3618 Stream socket test 2:
3619  - Create stream socket
3620  - Start listening, unbound socket
3621  - Close socket
3622  - Start listening, closed socket
3623
3624 Datagram socket test:
3625  - Create datagram socket
3626  - Bind socket
3627  - Start listening
3628  - Close socket
3629 */
3630 void WIFI_SocketListen (void) { 
3631   osThreadId_t worker;
3632   int32_t      rval;
3633   IO_LISTEN    io;
3634   int32_t      sock;
3635
3636   if (socket_funcs_exist == 0U) {
3637     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
3638     return;
3639   }
3640
3641   if (station_init (1) == 0) {
3642     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
3643     return;
3644   }
3645
3646   /* Create worker thread */
3647   worker = osThreadNew ((osThreadFunc_t)Th_Listen, &io, NULL);
3648   if (worker == NULL) {
3649     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
3650     return;
3651   }
3652
3653   ARG_INIT();
3654
3655   /* Create stream socket */
3656   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
3657   if (io.rc < 0) {
3658     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
3659   } else {
3660     sock = io.rc;
3661
3662     /* Bind socket */
3663     io.sock = sock;
3664     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3665     TH_ASSERT  (io.rc == 0);
3666
3667     /* Check parameter (socket = -1) */
3668     ARG_LISTEN (-1, 1);
3669     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3670     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3671
3672     /* Check parameter (socket = INT32_MIN) */
3673     ARG_LISTEN (INT32_MIN, 1);
3674     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3675     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3676
3677     /* Check parameter (socket = INT32_MAX) */
3678     ARG_LISTEN (INT32_MAX, 1);
3679     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3680     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3681
3682     /* Start listening */
3683     ARG_LISTEN (sock, 1);
3684     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3685     TH_ASSERT  (io.rc == 0);
3686
3687     /* Start listening 2nd time */
3688     ARG_LISTEN (sock, 1);
3689     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3690     /* Should return error (socket already listening) */
3691     /* Strict: EINVAL, valid non-strict: OK, ERROR */
3692     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);
3693
3694     /* Close socket */
3695     io.sock = sock;
3696     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3697     TH_ASSERT  (io.rc == 0);
3698
3699     osDelay (10);
3700   }
3701
3702   /* Create stream socket */
3703   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
3704   if (io.rc < 0) {
3705     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
3706   } else {
3707     sock = io.rc;
3708
3709     /* Start listening, unbound socket */
3710     ARG_LISTEN (sock, 1);
3711     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3712     /* Should return error (socket not bound) */
3713     /* Strict: EINVAL, valid non-strict: ERROR */
3714     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "listen on unbound socket", io.rc, ARM_SOCKET_EINVAL);
3715
3716     /* Close socket */
3717     io.sock = sock;
3718     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3719     TH_ASSERT  (io.rc == 0);
3720
3721     /* Start listening, closed socket */
3722     ARG_LISTEN (sock, 1);
3723     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3724     /* Should return error (socket not created) */
3725     /* Strict: ESOCK, valid non-strict: ERROR */
3726     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "listen on closed socket", io.rc, ARM_SOCKET_ESOCK);
3727
3728     osDelay (10);
3729   }
3730
3731   /* Create datagram socket */
3732   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
3733   if (io.rc < 0) {
3734     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
3735   } else {
3736     sock = io.rc;
3737
3738     /* Bind socket */
3739     io.sock = sock;
3740     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3741     TH_ASSERT  (io.rc == 0);
3742
3743     /* Start listening */
3744     ARG_LISTEN (sock, 1);
3745     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3746     /* Should return error (operation not supported) */
3747     /* Strict: ENOTSUP, valid non-strict: ERROR */
3748     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTSUP), (io.rc == ARM_SOCKET_ERROR), "listen on datagram socket", io.rc, ARM_SOCKET_ENOTSUP);
3749
3750     /* Close socket */
3751     io.sock = sock;
3752     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3753     TH_ASSERT  (io.rc == 0);
3754
3755     osDelay (10);
3756   }
3757
3758   if (rval == 0) {
3759     station_uninit ();
3760   }
3761
3762   /* Terminate worker thread */
3763   osThreadTerminate (worker);
3764 }
3765
3766 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
3767
3768 /* Accept IO parameters */
3769 typedef struct {
3770   int32_t      sock;
3771   uint8_t     *ip;
3772   uint32_t    *ip_len;
3773   uint16_t    *port;
3774   int32_t      rc;
3775   /* Control */
3776   osThreadId_t owner;
3777   uint32_t     xid;
3778   const char  *cmd;
3779 } IO_ACCEPT;
3780
3781 /* Assign arguments */
3782 #define ARG_ACCEPT(_sock,_ip,_ip_len,_port) do {                   \
3783                                               io.sock   = _sock;   \
3784                                               io.ip     = _ip;     \
3785                                               io.ip_len = _ip_len; \
3786                                               io.port   = _port;   \
3787                                             } while (0)
3788
3789 /* TestAssistant control */
3790 #define TEST_PORT           2000
3791
3792 /* CONNECT <proto>,<ip_addr>,<port>,<delay_ms>
3793            <proto>    = protocol (TCP, UDP)
3794            <ip_addr>  = IP address (0.0.0.0 = sender address)
3795            <port>     = port number
3796            <delay_ms> = startup delay
3797
3798   Example: CONNECT TCP,192.168.1.200,80,600
3799   (wait 600ms then connect to 192.168.1.200, port 80)
3800 */
3801 #define CMD_CONNECT_TCP     "CONNECT TCP,0.0.0.0,2000,500"
3802 #define CMD_CONNECT_UDP     "CONNECT UDP,0.0.0.0,2000,200"
3803
3804 /* Accept worker thread */
3805 __NO_RETURN static void Th_Accept (IO_ACCEPT *io) {
3806   uint32_t flags,xid;
3807   int32_t sock;
3808
3809   for (;;) {
3810     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_BIND | F_LISTEN |
3811                                F_ACCEPT     | F_SEND_CTRL  | F_RECV | F_CLOSE, osFlagsWaitAny, osWaitForever);
3812     xid   = io->xid;
3813     switch (flags) {
3814       case F_CREATE_TCP:
3815         /* Create stream socket */
3816         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3817         break;
3818
3819       case F_CREATE_UDP:
3820         /* Create datagram socket */
3821         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
3822         break;
3823
3824       case F_BIND:
3825         /* Bind socket */
3826         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, TEST_PORT);
3827         break;
3828
3829       case F_LISTEN:
3830         /* Listen on socket */
3831         io->rc = drv->SocketListen (io->sock, 1);
3832         break;
3833
3834       case F_ACCEPT:
3835         /* Accept on socket */
3836         io->rc = drv->SocketAccept (io->sock, io->ip, io->ip_len, io->port);
3837         break;
3838
3839       case F_RECV:
3840         /* Recv on socket (stream, datagram) */
3841         memset((void *)buffer, 0xCC, 16);
3842         io->rc = drv->SocketRecv (io->sock, buffer, 16);
3843         if ((io->rc > 0) && (memcmp ((const void *)buffer, (const void *)"SockServer", 10) != 0)) {
3844           /* Failed if rc <= 0 */
3845           io->rc = 0;
3846         }
3847         break;
3848
3849       case F_CLOSE:
3850         /* Close socket */
3851         io->rc = drv->SocketClose (io->sock);
3852         break;
3853
3854       case F_SEND_CTRL:
3855         /* Send control command to TestAssistant */
3856         sock = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
3857         drv->SocketConnect (sock, ip_socket_server, 4, ASSISTANT_PORT);
3858         io->rc = drv->SocketSend (sock, io->cmd, strlen(io->cmd));
3859         drv->SocketClose (sock);
3860         osDelay (10);
3861         break;
3862     }
3863     /* Done, send signal to owner thread */
3864     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
3865     osDelay(1);
3866     osThreadFlagsSet (io->owner, flags);
3867     osThreadFlagsClear (F_ALL);
3868   }
3869 }
3870
3871 /**
3872 \brief  Test case: WIFI_SocketAccept
3873 \ingroup wifi_sock_api
3874 \details
3875 The test case \b WIFI_SocketAccept verifies the WiFi Driver \b SocketAccept function:
3876 \code
3877 int32_t (*SocketAccept) (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t *port);
3878 \endcode
3879
3880 Stream socket test:
3881  - Create stream socket
3882  - Bind socket
3883  - Start listening
3884  - Check function parameters 
3885  - Accept connection, NULL parameters
3886  - Receive ServerId on accepted socket
3887  - Close accepted socket
3888  - Accept connection again, return IP address and port
3889  - Receive ServerId on accepted socket
3890  - Receive again, server closed connection
3891  - Close accepted socket
3892  - Close listening socket
3893  - Accept again, closed socket
3894
3895 Datagram socket test:
3896  - Create datagram socket
3897  - Bind socket
3898  - Start listening
3899  - Accept connection, provide return parameters for IP address and port
3900  - Receive ServerId on socket
3901  - Close socket
3902 */
3903 void WIFI_SocketAccept (void) {
3904   uint8_t      ip[4];
3905   uint32_t     ip_len;
3906   uint16_t     port;
3907   osThreadId_t worker;
3908   int32_t      rval;
3909   IO_ACCEPT    io;
3910   int32_t      sock;
3911
3912   if (socket_funcs_exist == 0U) {
3913     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
3914     return;
3915   }
3916
3917   if (station_init (1) == 0) {
3918     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
3919     return;
3920   }
3921
3922   /* Create worker thread */
3923   worker = osThreadNew ((osThreadFunc_t)Th_Accept, &io, NULL);
3924   if (worker == NULL) {
3925     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
3926     return;
3927   }
3928
3929   ARG_INIT();
3930
3931   /* Create stream socket */
3932   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
3933   if (io.rc < 0) {
3934     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
3935   } else {
3936     sock = io.rc;
3937
3938     /* Bind socket */
3939     io.sock = sock;
3940     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
3941     TH_ASSERT  (io.rc == 0);
3942
3943     /* Start listening */
3944     io.sock = sock;
3945     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
3946     TH_ASSERT  (io.rc == 0);
3947
3948     /* Check parameter (socket = -1) */
3949     ip_len = sizeof(ip);
3950     ARG_ACCEPT (-1, ip, &ip_len, &port);
3951     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
3952     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3953
3954     /* Check parameter (socket = INT32_MIN) */
3955     ARG_ACCEPT (INT32_MIN, ip, &ip_len, &port);
3956     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
3957     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3958
3959     /* Check parameter (socket = INT32_MAX) */
3960     ARG_ACCEPT (INT32_MAX, ip, &ip_len, &port);
3961     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
3962     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
3963
3964     /* Parameters 'ip', 'ip_len' and 'port' are optional, can be NULL */
3965
3966     /* Request a remote server to connect to us */
3967     io.cmd = CMD_CONNECT_TCP;
3968     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
3969     TH_ASSERT  (io.rc > 0);
3970
3971     /* Accept connection with NULL parameters */
3972     ARG_ACCEPT (sock, NULL, NULL, NULL);
3973     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT_LONG);
3974     /* Accepted socket should be different */
3975     TH_ASSERT  ((io.rc != io.sock) && (io.rc >= 0));
3976
3977     /* Receive SockServer id string */
3978     io.sock = io.rc;
3979     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
3980     TH_ASSERT (io.rc > 0);
3981
3982     /* Close accepted socket */
3983     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
3984     TH_ASSERT  (io.rc == 0);
3985
3986     osDelay (500);
3987
3988     /* Request from remote server to connect to us */
3989     io.cmd = CMD_CONNECT_TCP;
3990     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
3991     TH_ASSERT  (io.rc > 0);
3992
3993     /* Initialize buffers for return values */
3994     port   = 0;
3995     ip_len = sizeof(ip) + 1;
3996     memset ((void *)ip, 0, sizeof(ip));
3997
3998     /* Accept again, return ip address and port */
3999     ARG_ACCEPT (sock, &ip[0], &ip_len, &port);
4000     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT_LONG);
4001     /* Accepted socket should be different */
4002     TH_ASSERT  ((io.rc != io.sock) && (io.rc >= 0));
4003     /* IP address should be the address of the server */
4004     TH_ASSERT  ((memcmp ((const void *)ip, (const void *)ip_socket_server, 4) == 0) && (ip_len == 4));
4005     /* Port number of remote peer should be non-zero */
4006     TH_ASSERT  (port != 0);
4007
4008     /* Receive SockServer id string */
4009     io.sock = io.rc;
4010     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
4011     TH_ASSERT (io.rc > 0);
4012
4013     /* SockServer disconnects after 500ms */
4014
4015     /* Receive again, no data */
4016     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
4017     /* Should return error (connection reset) */
4018     /* Strict: ECONNRESET, valid non-strict: ERROR */
4019     TH_ASSERT2 ((io.rc == ARM_SOCKET_ECONNRESET), (io.rc == ARM_SOCKET_ERROR), "receive on disconnected socket", io.rc, ARM_SOCKET_ECONNRESET);
4020
4021     /* Close accepted socket */
4022     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4023     TH_ASSERT  (io.rc == 0);
4024
4025     /* Close listening socket */
4026     io.sock = sock;
4027     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4028     TH_ASSERT  (io.rc == 0);
4029
4030     /* Accept again, closed socket */
4031     ip_len = 4;
4032     ARG_ACCEPT (sock, &ip[0], &ip_len, &port);
4033     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
4034     /* Should return error (socket not created) */
4035     /* Strict: ESOCK, valid non-strict: ERROR */
4036     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "accept on closed socket", io.rc, ARM_SOCKET_ESOCK);
4037
4038     osDelay (10);
4039   }
4040
4041   /* Create datagram socket */
4042   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
4043   if (io.rc < 0) {
4044     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
4045   } else {
4046     sock = io.rc;
4047
4048     /* Bind socket */
4049     io.sock = sock;
4050     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4051     TH_ASSERT  (io.rc == 0);
4052
4053     /* Start listening */
4054     io.sock = sock;
4055     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
4056     /* Listen on datagram socket should fail */
4057     /* Strict: ENOTSUP, valid non-strict: ERROR */
4058     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTSUP), (io.rc == ARM_SOCKET_ERROR), "listen on datagram socket", io.rc, ARM_SOCKET_ENOTSUP);
4059
4060     /* Initialize buffers for return values */
4061     port   = 0;
4062     ip_len = sizeof(ip);
4063     memset ((void *)ip, 0, sizeof(ip));
4064
4065     /* Accept on datagram socket */
4066     ARG_ACCEPT (sock, &ip[0], &ip_len, &port);
4067     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
4068     /* Accept on datagram socket should fail */
4069     /* Strict: ENOTSUP, valid non-strict: ERROR */
4070     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTSUP), (io.rc == ARM_SOCKET_ERROR), "accept on datagram socket", io.rc, ARM_SOCKET_ENOTSUP);
4071
4072     osDelay (500);
4073
4074     /* Request from remote server to send us a test message */
4075     io.cmd = CMD_CONNECT_UDP;
4076     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
4077     TH_ASSERT  (io.rc > 0);
4078
4079     /* Receive SockServer id string */
4080     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
4081     TH_ASSERT  (io.rc > 0);
4082
4083     /* Close socket */
4084     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4085     TH_ASSERT  (io.rc == 0);
4086
4087     osDelay (10);
4088   }
4089
4090   if (rval == 0) {
4091     station_uninit ();
4092   }
4093
4094   /* Terminate worker thread */
4095   osThreadTerminate (worker);
4096 }
4097
4098 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
4099
4100 /* Connect IO parameters */
4101 typedef struct {
4102   int32_t        sock;
4103   const uint8_t *ip;
4104   uint32_t       ip_len;
4105   uint16_t       port;
4106   uint16_t       reserved;
4107   int32_t        rc;
4108   /* Control */
4109   osThreadId_t   owner;
4110   uint32_t       xid;
4111 } IO_CONNECT;
4112
4113 /* Assign arguments */
4114 #define ARG_CONNECT(_sock,_ip,_ip_len,_port) do {                   \
4115                                                io.sock   = _sock;   \
4116                                                io.ip     = _ip;     \
4117                                                io.ip_len = _ip_len; \
4118                                                io.port   = _port;   \
4119                                              } while (0)
4120
4121 /* Connect worker thread */
4122 __NO_RETURN static void Th_Connect (IO_CONNECT *io) {
4123   uint32_t flags,xid;
4124
4125   for (;;) {
4126     /* Wait for the signal to select and execute the function */
4127     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_BIND |
4128                                F_CONNECT    | F_LISTEN     | F_CLOSE, osFlagsWaitAny, osWaitForever);
4129     xid   = io->xid;
4130     switch (flags) {
4131       case F_CREATE_TCP:
4132         /* Create stream socket */
4133         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
4134         break;
4135
4136       case F_CREATE_UDP:
4137         /* Create datagram socket */
4138         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
4139         break;
4140
4141       case F_BIND:
4142         /* Bind socket */
4143         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
4144         break;
4145
4146       case F_CONNECT:
4147         /* Connect on socket */
4148         io->rc = drv->SocketConnect (io->sock, io->ip, io->ip_len, io->port);
4149         break;
4150
4151       case F_LISTEN:
4152         /* Listen on socket */
4153         io->rc = drv->SocketListen (io->sock, 1);
4154         break;
4155
4156       case F_CLOSE:
4157         /* Close socket */
4158         io->rc = drv->SocketClose (io->sock);
4159         break;
4160     }
4161     /* Done, send signal to owner thread */
4162     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
4163     osDelay(1);
4164     osThreadFlagsSet (io->owner, flags);
4165     osThreadFlagsClear (F_ALL);
4166   }
4167 }
4168
4169 /**
4170 \brief  Test case: WIFI_SocketConnect
4171 \ingroup wifi_sock_api
4172 \details
4173 The test case \b WIFI_SocketConnect verifies the WiFi Driver \b SocketConnect function:
4174 \code
4175 int32_t (*SocketConnect) (int32_t socket, const uint8_t *ip, uint32_t  ip_len, uint16_t  port);
4176 \endcode
4177
4178 Stream socket test 1:
4179  - Create stream socket
4180  - Check function parameters
4181  - Connect to server, blocking mode
4182  - Connect again, already connected
4183  - Bind connected socket
4184  - Close socket
4185  - Connect on closed socket
4186
4187 Stream socket test 2:
4188  - Create stream socket
4189  - Connect to server, connection rejected
4190  - Close socket
4191
4192 Stream socket test 3:
4193  - Create stream socket
4194  - Connect to server, non-responding or non-existent
4195  - Close socket
4196
4197 Stream socket test 4:
4198  - Create stream socket
4199  - Bind socket
4200  - Start listening
4201  - Connect to server, blocking mode
4202  - Close socket
4203
4204 Datagram socket test:
4205  - Create datagram socket
4206  - Bind socket
4207  - Check function parameters
4208  - Connect to server, enable address filtering
4209  - Connect to unspecified address, disable filtering
4210  - Close socket
4211  - Connect again, closed socket
4212 */
4213 void WIFI_SocketConnect (void) {
4214   osThreadId_t worker;
4215   int32_t      rval;
4216   IO_CONNECT   io;
4217   int32_t      sock;
4218
4219   if (socket_funcs_exist == 0U) {
4220     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
4221     return;
4222   }
4223
4224   if (station_init (1) == 0) {
4225     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
4226     return;
4227   }
4228
4229   /* Create worker thread */
4230   worker = osThreadNew ((osThreadFunc_t)Th_Connect, &io, NULL);
4231   if (worker == NULL) {
4232     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
4233     return;
4234   }
4235
4236   ARG_INIT();
4237
4238   /* Create stream socket */
4239   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4240   if (io.rc < 0) {
4241     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4242   } else {
4243     sock = io.rc;
4244
4245     /* Check parameter (socket = -1) */
4246     ARG_CONNECT(-1, ip_socket_server, 4, DISCARD_PORT);
4247     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4248     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4249
4250     /* Check parameter (socket = INT32_MIN) */
4251     ARG_CONNECT(INT32_MIN, ip_socket_server, 4, DISCARD_PORT);
4252     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4253     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4254
4255     /* Check parameter (socket = INT32_MAX) */
4256     ARG_CONNECT(INT32_MAX, ip_socket_server, 4, DISCARD_PORT);
4257     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4258     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4259
4260     /* Check parameter (ip = NULL) */
4261     ARG_CONNECT(sock, NULL, 4, DISCARD_PORT);
4262     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4263     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4264
4265     /* Check parameter (ip = 0.0.0.0) */
4266     ARG_CONNECT(sock, ip_unspec, 4, DISCARD_PORT);
4267     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4268     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4269
4270     /* Check parameter (ip_len = 0) */
4271     ARG_CONNECT(sock, ip_socket_server, 0, DISCARD_PORT);
4272     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4273     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4274
4275     /* Check parameter (ip_len = 5) */
4276     ARG_CONNECT(sock, ip_socket_server, 5, DISCARD_PORT);
4277     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4278     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4279
4280     /* Check parameter (port = 0) */
4281     ARG_CONNECT(sock, ip_socket_server, 4, 0);
4282     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4283     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4284
4285     /* Connect to stream server */
4286     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4287     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4288     TH_ASSERT  (io.rc == 0);
4289
4290     /* Connect 2nd time */
4291     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4292     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4293     /* Should return error (socket already connected) */
4294     /* Strict: EISCONN, valid non-strict: OK, ERROR */
4295     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);
4296
4297     /* Bind connected socket */
4298     io.sock = sock;
4299     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4300     /* Should return error (socket already connected) */
4301     /* Strict: EISCONN, valid non-strict: ERROR */
4302     TH_ASSERT2 ((io.rc == ARM_SOCKET_EISCONN), (io.rc == ARM_SOCKET_ERROR), "bind on connected socket", io.rc, ARM_SOCKET_EISCONN);
4303
4304     /* Close socket */
4305     io.sock = sock;
4306     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4307     TH_ASSERT  (io.rc == 0);
4308
4309     /* Connect again, closed socket */
4310     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4311     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4312     /* Should return error (socket not created) */
4313     /* Strict: ESOCK, valid non-strict: ERROR */
4314     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "connect on closed socket", io.rc, ARM_SOCKET_ESOCK);
4315
4316     osDelay (10);
4317   }
4318
4319   /* Create stream socket */
4320   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4321   if (io.rc < 0) {
4322     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4323   } else {
4324     sock = io.rc;
4325
4326     /* Connect to stream server (connection rejected) */
4327     ARG_CONNECT(sock, ip_socket_server, 4, TCP_REJECTED_PORT);
4328     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4329     /* Should return error (connection rejected by the peer) */
4330     /* Strict: ECONNREFUSED, valid non-strict: ETIMEDOUT, ERROR */
4331     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);
4332
4333     /* Close socket */
4334     io.sock = sock;
4335     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4336     TH_ASSERT  (io.rc == 0);
4337
4338     osDelay (10);
4339   }
4340
4341   /* Create stream socket */
4342   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4343   if (io.rc < 0) {
4344     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4345   } else {
4346     sock = io.rc;
4347
4348     /* Connect to stream server (non-existent) */
4349     ARG_CONNECT(sock, ip_socket_server, 4, TCP_TIMEOUT_PORT);
4350     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4351     /* Should return error (connection timeout) */
4352     /* Strict: ETIMEDOUT, valid non-strict: ERROR */
4353     TH_ASSERT2 ((io.rc == ARM_SOCKET_ETIMEDOUT), (io.rc == ARM_SOCKET_ERROR), "connect to non-existent stream server", io.rc, ARM_SOCKET_ETIMEDOUT);
4354
4355     /* Close socket */
4356     io.sock = sock;
4357     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4358     TH_ASSERT  (io.rc == 0);
4359
4360     osDelay (10);
4361   }
4362
4363   /* Create stream socket */
4364   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4365   if (io.rc < 0) {
4366     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4367   } else {
4368     sock = io.rc;
4369
4370     /* Bind socket */
4371     io.sock = sock;
4372     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4373     TH_ASSERT  (io.rc == 0);
4374
4375     /* Start listening */
4376     io.sock = sock;
4377     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
4378     TH_ASSERT  (io.rc == 0);
4379
4380     /* Connect to stream server */
4381     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4382     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4383     /* Connect on listening socket should fail */
4384     /* Strict: EINVAL, valid non-strict: ERROR */
4385     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "connect on listening socket", io.rc, ARM_SOCKET_EINVAL);
4386
4387     /* Close socket */
4388     io.sock = sock;
4389     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4390     TH_ASSERT  (io.rc == 0);
4391
4392     osDelay (10);
4393   }
4394
4395   /* Create datagram socket */
4396   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
4397   if (io.rc < 0) {
4398     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
4399   } else {
4400     sock = io.rc;
4401
4402     /* Check parameter (socket = -1) */
4403     ARG_CONNECT(-1, ip_socket_server, 4, DISCARD_PORT);
4404     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4405     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4406
4407     /* Check parameter (socket = INT32_MIN) */
4408     ARG_CONNECT(INT32_MIN, ip_socket_server, 4, DISCARD_PORT);
4409     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4410     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4411
4412     /* Check parameter (socket = INT32_MAX) */
4413     ARG_CONNECT(INT32_MAX, ip_socket_server, 4, DISCARD_PORT);
4414     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4415     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4416
4417     /* Check parameter (ip = NULL) */
4418     ARG_CONNECT(sock, NULL, 4, DISCARD_PORT);
4419     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4420     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4421
4422     /* Check parameter (ip = 0.0.0.0) */
4423     ARG_CONNECT(sock, ip_unspec, 4, DISCARD_PORT);
4424     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4425     /* Datagram sockets may dissolve the association */
4426     /* by connecting to unspecified address.         */
4427     /* Strict: OK, valid non-strict: EINVAL, ERROR */
4428     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);
4429
4430     /* Check parameter (ip_len = 0) */
4431     ARG_CONNECT(sock, ip_socket_server, 0, DISCARD_PORT);
4432     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4433     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4434
4435     /* Check parameter (ip_len = 5) */
4436     ARG_CONNECT(sock, ip_socket_server, 5, DISCARD_PORT);
4437     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4438     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4439
4440     /* Check parameter (port = 0) */
4441     ARG_CONNECT(sock, ip_socket_server, 4, 0);
4442     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4443     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4444
4445     /* Connect to datagram server */
4446     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4447     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4448     TH_ASSERT  (io.rc == 0);
4449
4450     /* Connect to unspecified address (0.0.0.0) */
4451     ARG_CONNECT(sock, ip_unspec, 4, DISCARD_PORT);
4452     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4453     /* Datagram sockets may dissolve the association */
4454     /* by connecting to unspecified address.         */
4455     /* Should return ok (socket address deleted) */
4456     /* Strict: OK, valid non-strict: EINVAL, ERROR */
4457     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);
4458
4459     /* Close socket */
4460     io.sock = sock;
4461     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4462     TH_ASSERT  (io.rc == 0);
4463
4464     /* Connect again, closed socket */
4465     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4466     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4467     /* Should return error (socket not created) */
4468     /* Strict: ESOCK, valid non-strict: ERROR */
4469     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "connect on closed socket", io.rc, ARM_SOCKET_ESOCK);
4470
4471     osDelay (10);
4472   }
4473
4474   if (rval == 0) {
4475     station_uninit ();
4476   }
4477
4478   /* Terminate worker thread */
4479   osThreadTerminate (worker);
4480 }
4481
4482 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
4483
4484 /* Recv IO parameters */
4485 typedef struct {
4486   int32_t      sock;
4487   uint8_t     *buf;
4488   uint32_t     len;
4489   int32_t      rc;
4490   /* Control */
4491   osThreadId_t owner;
4492   uint32_t     xid;
4493   uint32_t     tval;
4494 } IO_RECV;
4495
4496 /* Assign arguments */
4497 #define ARG_RECV(_sock,_buf,_len) do {               \
4498                                     io.sock = _sock; \
4499                                     io.buf  = _buf;  \
4500                                     io.len  = _len;  \
4501                                   } while (0)
4502
4503 /* Recv worker thread */
4504 __NO_RETURN static void Th_Recv (IO_RECV *io) {
4505   uint32_t flags,xid;
4506
4507   for (;;) {
4508     /* Wait for the signal to select and execute the function */
4509     flags = osThreadFlagsWait (F_CREATE_TCP | F_BIND | F_CONNECT | F_LISTEN |
4510                                F_SETOPT     | F_RECV | F_CLOSE, osFlagsWaitAny, osWaitForever);
4511     xid   = io->xid;
4512     switch (flags) {
4513       case F_CREATE_TCP:
4514         /* Create stream socket */
4515         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
4516         break;
4517
4518       case F_BIND:
4519         /* Bind socket */
4520         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
4521         break;
4522
4523       case F_CONNECT:
4524         /* Connect on socket */
4525         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, (uint16_t)io->tval);
4526         break;
4527
4528       case F_LISTEN:
4529         /* Listen on socket */
4530         io->rc = drv->SocketListen (io->sock, 1);
4531         break;
4532
4533       case F_SETOPT:
4534         /* Set socket options */
4535         io->rc = drv->SocketSetOpt (io->sock, ARM_SOCKET_SO_RCVTIMEO, &io->tval, sizeof(io->tval));
4536         break;
4537
4538       case F_RECV:
4539         /* Recv on socket */
4540         if (io->buf != NULL) {
4541           memset((void *)io->buf, 0xCC, io->len);
4542         }
4543         io->rc = drv->SocketRecv (io->sock, io->buf, io->len);
4544         break;
4545
4546       case F_CLOSE:
4547         /* Close socket */
4548         io->rc = drv->SocketClose (io->sock);
4549         break;
4550     }
4551     /* Done, send signal to owner thread */
4552     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
4553     osDelay(1);
4554     osThreadFlagsSet (io->owner, flags);
4555     osThreadFlagsClear (F_ALL);
4556   }
4557 }
4558
4559 /**
4560 \brief  Test case: WIFI_SocketRecv
4561 \ingroup wifi_sock_api
4562 \details
4563 Test case \b WIFI_SocketRecv verifies the WiFi Driver \b SocketRecv function:
4564 \code
4565 int32_t (*SocketRecv) (int32_t socket, void *buf, uint32_t len);
4566 \endcode
4567
4568 Stream socket test 1:
4569  - Create stream socket
4570  - Connect to Chargen server
4571  - Check function parameters
4572  - Receive data in blocking mode
4573  - Close socket
4574  - Receive again, closed socket
4575
4576 Stream socket test 2:
4577  - Create stream socket
4578  - Receive data, created socket
4579  - Bind socket
4580  - Receive data, bound socket
4581  - Start listening
4582  - Receive data, listening socket
4583  - Close socket
4584
4585 Stream socket test 3:
4586  - Create stream socket
4587  - Connect to Discard server
4588  - Set receive timeout to 1 sec
4589  - Receive data, timeout expires
4590  - Close socket
4591 */
4592 void WIFI_SocketRecv (void) {
4593   uint8_t      buf[4];
4594   uint32_t     ticks,tout;
4595   osThreadId_t worker;
4596   int32_t      rval;
4597   IO_RECV      io;
4598   int32_t      sock;
4599
4600   if (socket_funcs_exist == 0U) {
4601     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
4602     return;
4603   }
4604
4605   if (station_init (1) == 0) {
4606     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
4607     return;
4608   }
4609
4610   /* Create worker thread */
4611   worker = osThreadNew ((osThreadFunc_t)Th_Recv, &io, NULL);
4612   if (worker == NULL) {
4613     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
4614     return;
4615   }
4616
4617   ARG_INIT();
4618
4619   /* Create stream socket */
4620   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4621   if (io.rc < 0) {
4622     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4623   } else {
4624     sock = io.rc;
4625
4626     /* Connect to stream server */
4627     io.sock = sock;
4628     io.tval = CHARGEN_PORT;
4629     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4630     TH_ASSERT  (io.rc == 0);
4631
4632     /* Check parameter (socket = -1) */
4633     ARG_RECV   (-1, buf, sizeof(buf));
4634     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4635     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4636
4637     /* Check parameter (socket = INT32_MIN) */
4638     ARG_RECV   (INT32_MIN, buf, sizeof(buf));
4639     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4640     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4641
4642     /* Check parameter (socket = INT32_MAX) */
4643     ARG_RECV   (INT32_MAX, buf, sizeof(buf));
4644     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4645     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4646
4647     /* Check parameter (buf = NULL) */
4648     ARG_RECV   (sock, NULL, sizeof(buf));
4649     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4650     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4651
4652     /* Check parameter (len = 0) */
4653     ARG_RECV   (sock, buf, 0);
4654     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4655     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4656
4657     /* Receive some data */
4658     ARG_RECV   (sock, buffer, sizeof(buffer));
4659     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
4660     TH_ASSERT  (io.rc >= 2);
4661
4662     /* Close socket */
4663     io.sock = sock;
4664     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4665     TH_ASSERT  (io.rc == 0);
4666
4667     /* Receive again, closed socket */
4668     ARG_RECV (sock, buffer, sizeof(buffer));
4669     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4670     /* Should return error (socket not created) */
4671     /* Strict: ESOCK, valid non-strict: ERROR */
4672     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "recv on closed socket", io.rc, ARM_SOCKET_ESOCK);
4673
4674     osDelay (10);
4675   }
4676
4677   /* Create stream socket */
4678   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4679   if (io.rc < 0) {
4680     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4681   } else {
4682     /* Test server mode */
4683     sock = io.rc;
4684
4685     /* Receive, created socket */
4686     ARG_RECV   (sock, buffer, sizeof(buffer));
4687     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4688     /* Should return error (socket not connected) */
4689     /* Strict: ENOTCONN, valid non-strict: ERROR */
4690     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on created socket", io.rc, ARM_SOCKET_ENOTCONN);
4691
4692     /* Bind socket */
4693     io.sock = sock;
4694     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4695     TH_ASSERT  (io.rc == 0);
4696
4697     /* Receive, bound socket */
4698     ARG_RECV   (sock, buffer, sizeof(buffer));
4699     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4700     /* Should return error (socket not connected) */
4701     /* Strict: ENOTCONN, valid non-strict: ERROR */
4702     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on bound socket", io.rc, ARM_SOCKET_ENOTCONN);
4703
4704     /* Start listening */
4705     io.sock = sock;
4706     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
4707     TH_ASSERT  (io.rc == 0);
4708
4709     /* Receive, listening socket */
4710     ARG_RECV   (sock, buffer, sizeof(buffer));
4711     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4712     /* Should return error (socket not connected) */
4713     /* Strict: ENOTCONN, valid non-strict: ERROR */
4714     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on listening socket", io.rc, ARM_SOCKET_ENOTCONN);
4715
4716     /* Close socket */
4717     io.sock = sock;
4718     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4719     TH_ASSERT  (io.rc == 0);
4720
4721     osDelay (10);
4722   }
4723
4724   /* Create stream socket */
4725   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4726   if (io.rc < 0) {
4727     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4728   } else {
4729     sock = io.rc;
4730
4731     /* Connect to stream server */
4732     io.sock = sock;
4733     io.tval = DISCARD_PORT;
4734     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4735     TH_ASSERT  (io.rc == 0);
4736
4737     /* Set receive timeout to 1 sec */
4738     io.sock = sock;
4739     io.tval = 1000;
4740     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
4741     TH_ASSERT  (io.rc == 0);
4742
4743     /* Receive until timeout, no data */
4744     ARG_RECV   (sock, buffer, sizeof(buffer));
4745     ticks = GET_SYSTICK();
4746     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4747     tout = GET_SYSTICK() - ticks;
4748     /* Should return EAGAIN (operation timed out) */
4749     TH_ASSERT  (io.rc == ARM_SOCKET_EAGAIN);
4750     /* Check receive timeout is in the range of 0.9 to 1.1 sec */
4751     TH_ASSERT  (tout > SYSTICK_MICROSEC(900000) && tout < SYSTICK_MICROSEC(1100000));
4752
4753     /* Close socket */
4754     io.sock = sock;
4755     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4756     TH_ASSERT  (io.rc == 0);
4757
4758     osDelay (10);
4759   }
4760
4761   if (rval == 0) {
4762     station_uninit ();
4763   }
4764
4765   /* Terminate worker thread */
4766   osThreadTerminate (worker);
4767 }
4768
4769 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
4770
4771 /* RecvFrom IO parameters */
4772 typedef struct {
4773   int32_t      sock;
4774   uint8_t     *buf;
4775   uint32_t     len;
4776   uint8_t     *ip;
4777   uint32_t    *ip_len;
4778   uint16_t    *port;
4779   int32_t      rc;
4780   /* Control */
4781   osThreadId_t owner;
4782   uint32_t     xid;
4783   uint32_t     tout;
4784 } IO_RECVFROM;
4785
4786 /* Assign arguments */
4787 #define ARG_RECVFROM(_sock,_buf,_len,_ip,_ip_len,_port) do {                   \
4788                                                           io.sock   = _sock;   \
4789                                                           io.buf    = _buf;    \
4790                                                           io.len    = _len;    \
4791                                                           io.ip     = _ip;     \
4792                                                           io.ip_len = _ip_len; \
4793                                                           io.port   = _port;   \
4794                                                         } while (0)
4795
4796 /* RecvFrom worker thread */
4797 __NO_RETURN static void Th_RecvFrom (IO_RECVFROM *io) {
4798   uint32_t flags,xid;
4799
4800   for (;;) {
4801     /* Wait for the signal to select and execute the function */
4802     flags = osThreadFlagsWait (F_CREATE_UDP | F_CONNECT | F_SETOPT |
4803                                F_RECVFROM   | F_SEND    | F_CLOSE, osFlagsWaitAny, osWaitForever);
4804     xid   = io->xid;
4805     switch (flags) {
4806       case F_CREATE_UDP:
4807         /* Create datagram socket */
4808         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
4809         break;
4810
4811       case F_CONNECT:
4812         /* Connect on socket */
4813         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, CHARGEN_PORT);
4814         break;
4815
4816       case F_SETOPT:
4817         /* Set socket options */
4818         io->rc = drv->SocketSetOpt (io->sock, ARM_SOCKET_SO_RCVTIMEO, &io->tout, sizeof(io->tout));
4819         break;
4820
4821       case F_RECVFROM:
4822         /* RecvFrom on socket */
4823         if (io->buf != NULL) {
4824           memset((void *)io->buf, 0xCC, io->len);
4825         }
4826         io->rc = drv->SocketRecvFrom (io->sock, io->buf, io->len, io->ip, io->ip_len, io->port);
4827         break;
4828
4829       case F_SEND:
4830         /* Send on socket */
4831         io->rc = drv->SocketSend (io->sock, "a", 1);
4832         break;
4833
4834       case F_CLOSE:
4835         /* Close socket */
4836         io->rc = drv->SocketClose (io->sock);
4837         break;
4838     }
4839     /* Done, send signal to owner thread */
4840     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
4841     osDelay(1);
4842     osThreadFlagsSet (io->owner, flags);
4843     osThreadFlagsClear (F_ALL);
4844   }
4845 }
4846
4847 /**
4848 \brief  Test case: WIFI_SocketRecvFrom
4849 \ingroup wifi_sock_api
4850 \details
4851 The test case \b WIFI_SocketRecvFrom verifies the WiFi Driver \b SocketRecvFrom function:
4852 \code
4853 int32_t (*SocketRecvFrom) (int32_t socket, void *buf, uint32_t len, uint8_t *ip, uint32_t *ip_len, uint16_t *port);
4854 \endcode
4855
4856 Datagram socket test 1:
4857  - Create datagram socket
4858  - Connect to Chargen server
4859  - Check function parameters
4860  - Receive data in blocking mode
4861  - Set receive timeout to 1 sec
4862  - Receive again, timeout expires
4863  - Close socket
4864  - Receive again, closed socket
4865 */
4866 void WIFI_SocketRecvFrom (void) {
4867   uint8_t      ip[4];
4868   uint32_t     ip_len,ticks,tout;
4869   uint16_t     port;
4870   uint8_t      buf[4];
4871   osThreadId_t worker;
4872   int32_t      rval;
4873   IO_RECVFROM  io;
4874   int32_t      sock;
4875
4876   if (socket_funcs_exist == 0U) {
4877     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
4878     return;
4879   }
4880
4881   if (station_init (1) == 0) {
4882     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
4883     return;
4884   }
4885
4886   /* Create worker thread */
4887   worker = osThreadNew ((osThreadFunc_t)Th_RecvFrom, &io, NULL);
4888   if (worker == NULL) {
4889     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
4890     return;
4891   }
4892
4893   ARG_INIT();
4894
4895   /* Create datagram socket */
4896   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
4897   if (io.rc < 0) {
4898     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
4899   } else {
4900     sock = io.rc;
4901
4902     /* Connect to datagram server */
4903     io.sock = sock;
4904     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4905     TH_ASSERT  (io.rc == 0);
4906
4907     /* Check parameter (socket = -1) */
4908     ip_len = sizeof(ip);
4909     ARG_RECVFROM (-1, buf, sizeof(buf), ip, &ip_len, &port);
4910     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
4911     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4912
4913     /* Check parameter (socket = INT32_MIN) */
4914     ARG_RECVFROM (INT32_MIN, buf, sizeof(buf), ip, &ip_len, &port);
4915     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
4916     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4917
4918     /* Check parameter (socket = INT32_MAX) */
4919     ARG_RECVFROM (INT32_MAX, buf, sizeof(buf), ip, &ip_len, &port);
4920     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
4921     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4922
4923     /* Check parameter (buf == NULL) */
4924     ARG_RECVFROM (sock, NULL, sizeof(buf), ip, &ip_len, &port);
4925     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
4926     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4927
4928     /* Check parameter (len = 0) */
4929     ARG_RECVFROM (sock, buf, 0, ip, &ip_len, &port);
4930     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
4931     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4932
4933     /* Send one byte of data to trigger a reply */
4934     io.sock = sock;
4935     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT_LONG);
4936     TH_ASSERT  (io.rc == 1);
4937
4938     /* Initialize buffers for return values */
4939     port   = 0;
4940     ip_len = sizeof(ip) + 1;
4941     memset ((void *)ip, 0, sizeof(ip));
4942     
4943     /* Receive some data */
4944     ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
4945     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT_LONG);
4946     /* Should receive at least 2 bytes */
4947     TH_ASSERT  (io.rc >= 2);
4948     /* IP address should be the address of the server */
4949     TH_ASSERT  ((memcmp ((const void *)ip, (const void *)ip_socket_server, 4) == 0) && (ip_len == 4));
4950     /* Port number should be the port of the CHARGEN server */
4951     TH_ASSERT  (port == CHARGEN_PORT);
4952
4953     /* Set receive timeout to 1 sec */
4954     io.sock = sock;
4955     io.tout = 1000;
4956     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
4957     TH_ASSERT  (io.rc == 0);
4958
4959     /* Receive until timeout, no data */
4960     ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
4961     ticks = GET_SYSTICK();
4962     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
4963     tout = GET_SYSTICK() - ticks;
4964     /* Should return EAGAIN (operation timed out) */
4965     TH_ASSERT  (io.rc == ARM_SOCKET_EAGAIN);
4966     /* Check receive timeout is in the range of 0.9 to 1.1 sec */
4967     TH_ASSERT  (tout > SYSTICK_MICROSEC(900000) && tout < SYSTICK_MICROSEC(1100000));
4968
4969     /* Close socket */
4970     io.sock = sock;
4971     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4972     TH_ASSERT  (io.rc == 0);
4973
4974     /* Receive again, closed socket */
4975     ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
4976     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
4977     /* Should return error (socket not created) */
4978     /* Strict: ESOCK, valid non-strict: ERROR */
4979     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "recvfrom on closed socket", io.rc, ARM_SOCKET_ESOCK);
4980
4981     osDelay (10);
4982   }
4983
4984   if (rval == 0) {
4985     station_uninit ();
4986   }
4987
4988   /* Terminate worker thread */
4989   osThreadTerminate (worker);
4990 }
4991
4992 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
4993
4994 /* Send IO parameters */
4995 typedef struct {
4996   int32_t        sock;
4997   const uint8_t *buf;
4998   uint32_t       len;
4999   int32_t        rc;
5000   /* Control */
5001   osThreadId_t owner;
5002   uint32_t     xid;
5003 } IO_SEND;
5004
5005 /* Assign arguments */
5006 #define ARG_SEND(_sock,_buf,_len) do {               \
5007                                     io.sock = _sock; \
5008                                     io.buf  = _buf;  \
5009                                     io.len  = _len;  \
5010                                   } while (0)
5011
5012 /* Send worker thread */
5013 __NO_RETURN static void Th_Send (IO_SEND *io) {
5014   uint32_t flags,xid;
5015
5016   for (;;) {
5017     /* Wait for the signal to select and execute the function */
5018     flags = osThreadFlagsWait (F_CREATE_TCP | F_BIND | F_CONNECT |
5019                                F_LISTEN     | F_SEND | F_CLOSE, osFlagsWaitAny, osWaitForever);
5020     xid   = io->xid;
5021     switch (flags) {
5022       case F_CREATE_TCP:
5023         /* Create stream socket */
5024         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
5025         break;
5026
5027       case F_BIND:
5028         /* Bind socket */
5029         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
5030         break;
5031
5032       case F_CONNECT:
5033         /* Connect on socket */
5034         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
5035         break;
5036
5037        case F_LISTEN:
5038         /* Listen on socket */
5039         io->rc = drv->SocketListen (io->sock, 1);
5040         break;
5041
5042      case F_SEND:
5043         /* Send on socket */
5044         io->rc = drv->SocketSend (io->sock, io->buf, io->len);
5045         break;
5046
5047       case F_CLOSE:
5048         /* Close socket */
5049         io->rc = drv->SocketClose (io->sock);
5050         break;
5051     }
5052     /* Done, send signal to owner thread */
5053     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
5054     osDelay(1);
5055     osThreadFlagsSet (io->owner, flags);
5056     osThreadFlagsClear (F_ALL);
5057   }
5058 }
5059
5060 /**
5061 \brief  Test case: WIFI_SocketSend
5062 \ingroup wifi_sock_api
5063 \details
5064 The test case \b WIFI_SocketSend verifies the WiFi Driver \b SocketSend function:
5065 \code
5066 int32_t (*SocketSend) (int32_t socket, const void *buf, uint32_t len);
5067 \endcode
5068
5069 Stream socket test 1:
5070  - Create stream socket
5071  - Connect to server, blocking mode
5072  - Check function parameters
5073  - Send data, blocking mode
5074  - Close socket
5075  - Send again, closed socket
5076
5077 Stream socket test 2:
5078  - Create stream socket
5079  - Connect to server, blocking mode
5080  - Send ESC data, server disconnects
5081  - Send again, disconnected socket
5082  - Close socket
5083
5084 Stream socket test 3:
5085  - Create stream socket
5086  - Send data, created socket
5087  - Bind socket
5088  - Send data, bound socket
5089  - Start listening
5090  - Send data, listening socket
5091  - Close socket
5092  - Send again, closed socket
5093 */
5094 void WIFI_SocketSend (void) {
5095   osThreadId_t worker;
5096   int32_t      rval;
5097   IO_SEND      io;
5098   int32_t      sock;
5099
5100   if (socket_funcs_exist == 0U) {
5101     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
5102     return;
5103   }
5104
5105   if (station_init (1) == 0) {
5106     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
5107     return;
5108   }
5109
5110   /* Create worker thread */
5111   worker = osThreadNew ((osThreadFunc_t)Th_Send, &io, NULL);
5112   if (worker == NULL) {
5113     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5114     return;
5115   }
5116
5117   ARG_INIT();
5118
5119   /* Create stream socket */
5120   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5121   if (io.rc < 0) {
5122     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5123   } else {
5124     sock = io.rc;
5125
5126     /* Connect to stream server */
5127     io.sock = sock;
5128     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
5129     TH_ASSERT  (io.rc == 0);
5130
5131     /* Check parameter (socket = -1) */
5132     ARG_SEND   (-1, test_msg, sizeof(test_msg));
5133     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5134     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5135
5136     /* Check parameter (socket = INT32_MIN) */
5137     ARG_SEND   (INT32_MIN, test_msg, sizeof(test_msg));
5138     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5139     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5140
5141     /* Check parameter (socket = INT32_MAX) */
5142     ARG_SEND   (INT32_MAX, test_msg, sizeof(test_msg));
5143     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5144     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5145
5146     /* Check parameter (buf = NULL) */
5147     ARG_SEND   (sock, NULL, sizeof(test_msg));
5148     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5149     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
5150
5151     /* Check parameter (len = 0) */
5152     ARG_SEND   (sock, test_msg, 0);
5153     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5154     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
5155
5156     /* Send some data */
5157     ARG_SEND   (sock, test_msg, sizeof(test_msg));
5158     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT_LONG);
5159     TH_ASSERT  (io.rc == sizeof(test_msg));
5160
5161     /* Close socket */
5162     io.sock = sock;
5163     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5164     TH_ASSERT  (io.rc == 0);
5165
5166     /* Send again, closed socket */
5167     ARG_SEND   (sock, test_msg, sizeof(test_msg));
5168     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5169     /* Should return error (socket not created) */
5170     /* Strict: ESOCK, valid non-strict: ERROR */
5171     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "send on closed socket", io.rc, ARM_SOCKET_ESOCK);
5172
5173     osDelay (10);
5174   }
5175
5176   /* Create stream socket */
5177   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5178   if (io.rc < 0) {
5179     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5180   } else {
5181     sock = io.rc;
5182
5183     /* Connect to stream server */
5184     io.sock = sock;
5185     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
5186     TH_ASSERT  (io.rc == 0);
5187
5188     /* Send ESC command, server disconnects */
5189     ARG_SEND   (sock, (uint8_t *)"\x1B", 1);
5190     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT_LONG);
5191     TH_ASSERT  (io.rc == 1);
5192
5193     /* Wait for the server to disconnect */
5194     osDelay (200);
5195
5196     /* Send again, disconnected socket */
5197     ARG_SEND   (sock, test_msg, sizeof(test_msg));
5198     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5199     /* Should return error (connection reset by the peer) */
5200     /* Strict: ECONNRESET, valid non-strict: ERROR */
5201     TH_ASSERT2 ((io.rc == ARM_SOCKET_ECONNRESET), (io.rc == ARM_SOCKET_ERROR), "send on disconnected socket", io.rc, ARM_SOCKET_ECONNRESET);
5202
5203     /* Close socket */
5204     io.sock = sock;
5205     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5206     TH_ASSERT  (io.rc == 0);
5207
5208     osDelay (10);
5209   }
5210
5211   /* Create stream socket */
5212   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5213   if (io.rc < 0) {
5214     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5215   } else {
5216     sock = io.rc;
5217
5218     /* Send data, created socket */
5219     ARG_SEND   (sock, test_msg, sizeof(test_msg));
5220     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5221     /* Should return error (socket not connected) */
5222     /* Strict: ENOTCONN, valid non-strict: ERROR */
5223     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "send on created socket", io.rc, ARM_SOCKET_ENOTCONN);
5224
5225     /* Bind socket */
5226     io.sock = sock;
5227     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
5228     TH_ASSERT  (io.rc == 0);
5229
5230     /* Send data, bound socket */
5231     ARG_SEND (sock, test_msg, sizeof(test_msg));
5232     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5233     /* Should return error (socket not connected) */
5234     /* Strict: ENOTCONN, valid non-strict: ERROR */
5235     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "send on bound socket", io.rc, ARM_SOCKET_ENOTCONN);
5236
5237     /* Start listening */
5238     io.sock = sock;
5239     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
5240     TH_ASSERT  (io.rc == 0);
5241
5242     /* Send data, listening socket */
5243     ARG_SEND (sock, test_msg, sizeof(test_msg));
5244     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5245     /* Should return error (socket not connected) */
5246     /* Strict: ENOTCONN, valid non-strict: ERROR */
5247     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "send on listening socket", io.rc, ARM_SOCKET_ENOTCONN);
5248
5249     /* Close socket */
5250     io.sock = sock;
5251     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5252     TH_ASSERT  (io.rc == 0);
5253
5254     /* Send again, closed socket */
5255     ARG_SEND (sock, test_msg, sizeof(test_msg));
5256     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5257     /* Should return error (socket not created) */
5258     /* Strict: ESOCK, valid non-strict: ERROR */
5259     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "send on closed socket", io.rc, ARM_SOCKET_ESOCK);
5260
5261     osDelay (10);
5262   }
5263
5264   if (rval == 0) {
5265     station_uninit ();
5266   }
5267
5268   /* Terminate worker thread */
5269   osThreadTerminate (worker);
5270 }
5271
5272 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
5273
5274 /* SendTo IO parameters */
5275 typedef struct {
5276   int32_t        sock;
5277   const uint8_t *buf;
5278   uint32_t       len;
5279   const uint8_t *ip;
5280   uint32_t       ip_len;
5281   uint16_t       port;
5282   uint16_t       reserved;
5283   int32_t        rc;
5284   /* Control */
5285   osThreadId_t owner;
5286   uint32_t     xid;
5287 } IO_SENDTO;
5288
5289 /* Assign arguments */
5290 #define ARG_SENDTO(_sock,_buf,_len,_ip,_ip_len,_port) do {                   \
5291                                                         io.sock   = _sock;   \
5292                                                         io.buf    = _buf;    \
5293                                                         io.len    = _len;    \
5294                                                         io.ip     = _ip;     \
5295                                                         io.ip_len = _ip_len; \
5296                                                         io.port   = _port;   \
5297                                                       } while (0)
5298
5299 /* SendTo worker thread */
5300 __NO_RETURN static void Th_SendTo (IO_SENDTO *io) {
5301   uint32_t flags,xid;
5302
5303   for (;;) {
5304     /* Wait for the signal to select and execute the function */
5305     flags = osThreadFlagsWait (F_CREATE_UDP | F_SENDTO | F_RECV | F_CLOSE, osFlagsWaitAny, osWaitForever);
5306     xid   = io->xid;
5307     switch (flags) {
5308       case F_CREATE_UDP:
5309         /* Create datagram socket */
5310         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
5311         break;
5312
5313       case F_SENDTO:
5314         /* SendTo on socket */
5315         io->rc = drv->SocketSendTo (io->sock, io->buf, io->len, io->ip, io->ip_len, io->port);
5316         break;
5317
5318       case F_RECV:
5319         /* Recv on socket */
5320         memset((void *)buffer, 0xCC, sizeof(buffer));
5321         io->rc = drv->SocketRecv (io->sock, buffer, sizeof(buffer));
5322         break;
5323
5324       case F_CLOSE:
5325         /* Close socket */
5326         io->rc = drv->SocketClose (io->sock);
5327         break;
5328     }
5329     /* Done, send signal to owner thread */
5330     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
5331     osDelay(1);
5332     osThreadFlagsSet (io->owner, flags);
5333     osThreadFlagsClear (F_ALL);
5334   }
5335 }
5336
5337 /**
5338 \brief  Test case: WIFI_SocketSendTo
5339 \ingroup wifi_sock_api
5340 \details
5341 The test case \b WIFI_SocketSend verifies the WiFi Driver \b SocketSendTo function:
5342 \code
5343 int32_t (*SocketSendTo) (int32_t socket, const void *buf, uint32_t len, const uint8_t *ip, uint32_t ip_len, uint16_t port);
5344 \endcode
5345
5346 Datagram socket test:
5347  - Create datagram socket
5348  - Check function parameters
5349  - Send data, blocking mode
5350  - Receive echo data, verify if the same
5351  - Close socket
5352  - Send again, closed socket
5353 */
5354 void WIFI_SocketSendTo (void) {
5355   osThreadId_t worker;
5356   int32_t      rval;
5357   IO_SENDTO    io;
5358   int32_t      sock;
5359
5360   if (socket_funcs_exist == 0U) {
5361     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
5362     return;
5363   }
5364
5365   if (station_init (1) == 0) {
5366     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
5367     return;
5368   }
5369
5370   /* Create worker thread */
5371   worker = osThreadNew ((osThreadFunc_t)Th_SendTo, &io, NULL);
5372   if (worker == NULL) {
5373     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5374     return;
5375   }
5376
5377   ARG_INIT();
5378
5379   /* Create datagram socket */
5380   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
5381   if (io.rc < 0) {
5382     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
5383   } else {
5384     sock = io.rc;
5385
5386     /* Check parameter (socket = -1) */
5387     ARG_SENDTO (-1, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5388     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5389     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5390
5391     /* Check parameter (socket = INT32_MIN) */
5392     ARG_SENDTO (INT32_MIN, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5393     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5394     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5395
5396     /* Check parameter (socket = INT32_MAX) */
5397     ARG_SENDTO (INT32_MAX, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5398     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5399     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5400
5401     /* Check parameter (buf == NULL) */
5402     ARG_SENDTO (sock, NULL, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5403     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5404     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
5405
5406     /* Check parameter (len = 0) */
5407     ARG_SENDTO (sock, test_msg, 0, ip_socket_server, 4, ECHO_PORT);
5408     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5409     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
5410
5411     /* Send some data */
5412     ARG_SENDTO (sock, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5413     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT_LONG);
5414     TH_ASSERT  (io.rc == sizeof(test_msg));
5415
5416     /* Receive the echoed data */
5417     io.sock = sock;
5418     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
5419     /* Should receive the same data (ECHO protocol) */
5420     TH_ASSERT  ((io.rc == sizeof(test_msg)) && (memcmp ((const void *)test_msg, (const void *)buffer, sizeof(test_msg)) == 0));
5421
5422     /* Close socket */
5423     io.sock = sock;
5424     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5425     TH_ASSERT  (io.rc == 0);
5426
5427     /* Send again, closed socket */
5428     ARG_SENDTO (sock, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
5429     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
5430     /* Should return error (socket not created) */
5431     /* Strict: ESOCK, valid non-strict: ERROR */
5432     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "sendto on closed socket", io.rc, ARM_SOCKET_ESOCK);
5433
5434     osDelay (10);
5435   }
5436
5437   if (rval == 0) {
5438     station_uninit ();
5439   }
5440
5441   /* Terminate worker thread */
5442   osThreadTerminate (worker);
5443 }
5444
5445 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
5446
5447 /* GetSockName IO parameters */
5448 typedef struct {
5449   int32_t      sock;
5450   uint8_t     *ip;
5451   uint32_t    *ip_len;
5452   uint16_t    *port;
5453   int32_t      rc;
5454   /* Control */
5455   osThreadId_t owner;
5456   uint32_t     xid;
5457 } IO_GETSOCKNAME;
5458
5459 /* Assign arguments */
5460 #define ARG_GETSOCKNAME(_sock,_ip,_ip_len,_port) do {                   \
5461                                                    io.sock   = _sock;   \
5462                                                    io.ip     = _ip;     \
5463                                                    io.ip_len = _ip_len; \
5464                                                    io.port   = _port;   \
5465                                                  } while (0)
5466
5467 /* GetSockName worker thread */
5468 __NO_RETURN static void Th_GetSockName (IO_GETSOCKNAME *io) {
5469   uint32_t flags,xid;
5470
5471   for (;;) {
5472     /* Wait for the signal to select and execute the function */
5473     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP  | F_BIND |
5474                                F_CONNECT    | F_GETSOCKNAME | F_CLOSE, osFlagsWaitAny, osWaitForever);
5475     xid   = io->xid;
5476     switch (flags) {
5477       case F_CREATE_TCP:
5478         /* Create stream socket */
5479         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
5480         break;
5481
5482       case F_CREATE_UDP:
5483         /* Create datagram socket */
5484         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
5485         break;
5486
5487       case F_BIND:
5488         /* Bind socket */
5489         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
5490         break;
5491
5492       case F_CONNECT:
5493         /* Connect on socket */
5494         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
5495         break;
5496
5497       case F_GETSOCKNAME:
5498         /* Get socket name */
5499         io->rc = drv->SocketGetSockName (io->sock, io->ip, io->ip_len, io->port);
5500         break;
5501
5502       case F_CLOSE:
5503         /* Close socket */
5504         io->rc = drv->SocketClose (io->sock);
5505         break;
5506     }
5507     /* Done, send signal to owner thread */
5508     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
5509     osDelay(1);
5510     osThreadFlagsSet (io->owner, flags);
5511     osThreadFlagsClear (F_ALL);
5512   }
5513 }
5514
5515 /**
5516 \brief  Test case: WIFI_SocketGetSockName
5517 \ingroup wifi_sock_api
5518 \details
5519 The test case \b WIFI_SocketGetSockName verifies the WiFi Driver \b SocketGetSockName function:
5520 \code
5521 int32_t (*SocketGetSockName) (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t *port);
5522 \endcode
5523
5524 Stream socket test 1:
5525  - Create stream socket
5526  - Connect to server, blocking mode
5527  - Check function parameters
5528  - Get socket name
5529  - Close socket
5530  - Get socket name again, closed socket
5531
5532 Stream socket test 1:
5533  - Create stream socket
5534  - Get socket name, not bound
5535  - Bind socket
5536  - Get socket name, bound
5537  - Close socket
5538
5539 Datagram socket test 1:
5540  - Create datagram socket
5541  - Connect to server, enable packet filtering
5542  - Check function parameters
5543  - Get socket name
5544  - Close socket
5545  - Get socket name again, closed socket
5546
5547 Datagram socket test 1:
5548  - Create datagram socket
5549  - Get socket name, not bound
5550  - Bind socket
5551  - Get socket name, bound
5552  - Close socket
5553 */
5554 void WIFI_SocketGetSockName (void) {
5555   uint8_t        local_ip[4];
5556   uint16_t       local_port;
5557   uint32_t       ip_len;
5558   osThreadId_t   worker;
5559   int32_t        rval;
5560   IO_GETSOCKNAME io;
5561   int32_t        sock;
5562
5563   if (socket_funcs_exist == 0U) {
5564     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
5565     return;
5566   }
5567
5568   if (station_init (1) == 0) {
5569     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
5570     return;
5571   }
5572
5573   /* Create worker thread */
5574   worker = osThreadNew ((osThreadFunc_t)Th_GetSockName, &io, NULL);
5575   if (worker == NULL) {
5576     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5577     return;
5578   }
5579
5580   ARG_INIT();
5581
5582   /* Create stream socket */
5583   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5584   if (io.rc < 0) {
5585     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5586   } else {
5587     /* Test client mode */
5588     sock = io.rc;
5589
5590     /* Connect to stream server */
5591     io.sock = sock;
5592     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
5593     TH_ASSERT  (io.rc == 0);
5594
5595     /* Check parameter (socket = -1) */
5596     ip_len = sizeof(local_ip);
5597     ARG_GETSOCKNAME (-1, local_ip, &ip_len, &local_port);
5598     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5599     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5600
5601     /* Check parameter (socket = INT32_MIN) */
5602     ARG_GETSOCKNAME (INT32_MIN, local_ip, &ip_len, &local_port);
5603     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5604     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5605
5606     /* Check parameter (socket = INT32_MAX) */
5607     ARG_GETSOCKNAME (INT32_MAX, local_ip, &ip_len, &local_port);
5608     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5609     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5610
5611     /* Check parameter (port = NULL) */
5612     ip_len = sizeof(local_ip);
5613     ARG_GETSOCKNAME (sock, local_ip, &ip_len, NULL);
5614     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5615     /* Request IP address only should be accepted */
5616     TH_ASSERT  (io.rc == 0);
5617
5618     /* Check parameter (ip = NULL, ip_len = NULL) */
5619     ARG_GETSOCKNAME (sock, NULL, NULL, &local_port);
5620     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5621     /* Request port only should be accepted */
5622     TH_ASSERT  (io.rc == 0);
5623
5624     /* Initialize buffers for return values */
5625     local_port = 0;
5626     ip_len     = sizeof(local_ip) + 1;
5627     memcpy (local_ip, ip_bcast, sizeof(local_ip));
5628
5629     /* Retrieve socket name */
5630     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5631     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5632     TH_ASSERT  (io.rc == 0);
5633     /* IP address should be different from broadcast */
5634     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_bcast, 4) != 0) && (ip_len == 4));
5635     /* Port number should be non-zero */
5636     TH_ASSERT  (local_port != 0);
5637
5638     /* Close socket */
5639     io.sock = sock;
5640     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5641     TH_ASSERT  (io.rc == 0);
5642
5643     /* Retrieve socket name again */
5644     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5645     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5646     /* Should return error (socket not created) */
5647     /* Strict: ESOCK, valid non-strict: ERROR */
5648     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockname on closed socket", io.rc, ARM_SOCKET_ESOCK);
5649
5650     osDelay (10);
5651   }
5652
5653   /* Create stream socket */
5654   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5655   if (io.rc < 0) {
5656     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5657   } else {
5658     /* Test server mode */
5659     sock = io.rc;
5660
5661     /* Retrieve socket name, not bound */
5662     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5663     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5664     /* Should return error (socket not bound) */
5665     /* Strict: EINVAL, valid non-strict: ERROR */
5666     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "getsockname on unbound socket", io.rc, ARM_SOCKET_EINVAL);
5667
5668     /* Initialize buffers for return values */
5669     local_port = 0;
5670     ip_len     = sizeof(local_ip) + 1;
5671     memcpy (local_ip, ip_bcast, sizeof(local_ip));
5672
5673     /* Bind socket */
5674     io.sock = sock;
5675     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
5676     TH_ASSERT  (io.rc == 0);
5677
5678     /* Retrieve socket name, bound */
5679     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5680     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5681     TH_ASSERT  (io.rc == 0);
5682     /* IP address should be unspecified */
5683     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_unspec, 4) == 0) && (ip_len == 4));
5684     /* Port number should be listening port */
5685     TH_ASSERT  (local_port == DISCARD_PORT);
5686
5687     /* Close socket */
5688     io.sock = sock;
5689     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5690     TH_ASSERT  (io.rc == 0);
5691
5692     osDelay (10);
5693   }
5694
5695   /* Create datagram socket */
5696   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
5697   if (io.rc < 0) {
5698     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
5699   } else {
5700     /* Test client mode */
5701     sock = io.rc;
5702
5703     /* Connect to datagram server */
5704     io.sock = sock;
5705     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
5706     TH_ASSERT  (io.rc == 0);
5707
5708     /* Check parameter (socket = -1) */
5709     ARG_GETSOCKNAME (-1, local_ip, &ip_len, &local_port);
5710     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5711     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5712
5713     /* Check parameter (socket = INT32_MIN) */
5714     ARG_GETSOCKNAME (INT32_MIN, local_ip, &ip_len, &local_port);
5715     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5716     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5717
5718     /* Check parameter (socket = INT32_MAX) */
5719     ARG_GETSOCKNAME (INT32_MAX, local_ip, &ip_len, &local_port);
5720     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5721     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5722
5723     /* Check parameter (port = NULL) */
5724     ip_len = sizeof(local_ip);
5725     ARG_GETSOCKNAME (sock, local_ip, &ip_len, NULL);
5726     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5727     /* Request IP address only should be accepted */
5728     TH_ASSERT  (io.rc == 0);
5729
5730     /* Check parameter (ip = NULL, ip_len = NULL) */
5731     ARG_GETSOCKNAME (sock, NULL, NULL, &local_port);
5732     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5733     /* Request port only should be accepted */
5734     TH_ASSERT  (io.rc == 0);
5735
5736     /* Initialize buffers for return values */
5737     local_port = 0;
5738     ip_len     = sizeof(local_ip) + 1;
5739     memcpy (local_ip, ip_bcast, sizeof(local_ip));
5740
5741     /* Retrieve socket name */
5742     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5743     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5744     TH_ASSERT  (io.rc == 0);
5745     /* IP address should be different from broadcast */
5746     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_bcast, 4) != 0) && (ip_len == 4));
5747     /* Port number should be non-zero */
5748     TH_ASSERT  (local_port != 0);
5749
5750     /* Close socket */
5751     io.sock = sock;
5752     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5753     TH_ASSERT  (io.rc == 0);
5754
5755     /* Retrieve socket name again */
5756     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5757     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5758     /* Should return error (socket not created) */
5759     /* Strict: ESOCK, valid non-strict: ERROR */
5760     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockname on closed socket", io.rc, ARM_SOCKET_ESOCK);
5761
5762     osDelay (10);
5763   }
5764
5765   /* Create datagram socket */
5766   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
5767   if (io.rc < 0) {
5768     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
5769   } else {
5770     /* Test server mode */
5771     sock = io.rc;
5772
5773     /* Retrieve socket name, not bound */
5774     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5775     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5776     /* Should return error (socket not bound) */
5777     /* Strict: EINVAL, valid non-strict: ERROR */
5778     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "getsockname on unbound socket", io.rc, ARM_SOCKET_EINVAL);
5779
5780     /* Initialize buffers for return values */
5781     local_port = 0;
5782     ip_len     = sizeof(local_ip) + 1;
5783     memcpy (local_ip, ip_bcast, sizeof(local_ip));
5784
5785     /* Bind socket */
5786     io.sock = sock;
5787     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
5788     TH_ASSERT  (io.rc == 0);
5789
5790     /* Retrieve socket name, bound */
5791     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
5792     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
5793     TH_ASSERT  (io.rc == 0);
5794     /* IP address should be unspecified */
5795     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_unspec, 4) == 0) && (ip_len == 4));
5796     /* Port number should be listening port */
5797     TH_ASSERT  (local_port == DISCARD_PORT);
5798
5799     /* Close socket */
5800     io.sock = sock;
5801     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5802     TH_ASSERT  (io.rc == 0);
5803
5804     osDelay (10);
5805   }
5806
5807   if (rval == 0) {
5808     station_uninit ();
5809   }
5810
5811   /* Terminate worker thread */
5812   osThreadTerminate (worker);
5813 }
5814
5815 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
5816
5817 /* GetPeerName IO parameters */
5818 typedef struct {
5819   int32_t      sock;
5820   uint8_t     *ip;
5821   uint32_t    *ip_len;
5822   uint16_t    *port;
5823   int32_t      rc;
5824   /* Control */
5825   osThreadId_t owner;
5826   uint32_t     xid;
5827 } IO_GETPEERNAME;
5828
5829 /* Assign arguments */
5830 #define ARG_GETPEERNAME(_sock,_ip,_ip_len,_port) do {                   \
5831                                                    io.sock   = _sock;   \
5832                                                    io.ip     = _ip;     \
5833                                                    io.ip_len = _ip_len; \
5834                                                    io.port   = _port;   \
5835                                                  } while (0)
5836
5837 /* GetPeerName worker thread */
5838 __NO_RETURN static void Th_GetPeerName (IO_GETPEERNAME *io) {
5839   uint32_t flags,xid;
5840
5841   for (;;) {
5842     /* Wait for the signal to select and execute the function */
5843     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP  | F_BIND | F_CONNECT |
5844                                F_LISTEN     | F_GETPEERNAME | F_CLOSE, osFlagsWaitAny, osWaitForever);
5845     xid   = io->xid;
5846     switch (flags) {
5847       case F_CREATE_TCP:
5848         /* Create stream socket */
5849         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
5850         break;
5851
5852       case F_CREATE_UDP:
5853         /* Create datagram socket */
5854         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
5855         break;
5856
5857       case F_BIND:
5858         /* Bind socket */
5859         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
5860         break;
5861
5862       case F_CONNECT:
5863         /* Connect on socket */
5864         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
5865         break;
5866
5867        case F_LISTEN:
5868         /* Listen on socket */
5869         io->rc = drv->SocketListen (io->sock, 1);
5870         break;
5871
5872       case F_GETPEERNAME:
5873         /* Get peer name  */
5874         io->rc = drv->SocketGetPeerName (io->sock, io->ip, io->ip_len, io->port);
5875         break;
5876
5877       case F_CLOSE:
5878         /* Close socket */
5879         io->rc = drv->SocketClose (io->sock);
5880         break;
5881     }
5882     /* Done, send signal to owner thread */
5883     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
5884     osDelay(1);
5885     osThreadFlagsSet (io->owner, flags);
5886     osThreadFlagsClear (F_ALL);
5887   }
5888 }
5889
5890 /**
5891 \brief  Test case: WIFI_SocketGetPeerName
5892 \ingroup wifi_sock_api
5893 \details
5894 The test case \b WIFI_SocketGetPeerName verifies the WiFi Driver \b SocketGetPeerName function:
5895 \code
5896 int32_t (*SocketGetPeerName) (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t *port);
5897 \endcode
5898
5899 Stream socket test  1:
5900  - Create stream socket
5901  - Connect to server, blocking mode
5902  - Check function parameters
5903  - Get peer name
5904  - Close socket
5905  - Get peer name, closed socket
5906
5907 Stream socket test  2:
5908  - Create stream socket
5909  - Get peer name, created socket
5910  - Bind socket
5911  - Get peer name, bound socket
5912  - Start listening
5913  - Get peer name, listening socket
5914  - Close socket
5915
5916 Datagram socket test:
5917  - Create datagram socket
5918  - Connect to server, enable packet filtering
5919  - Check function parameters
5920  - Get peer name
5921  - Close socket
5922  - Get peer name, closed socket
5923 */
5924 void WIFI_SocketGetPeerName (void) {
5925   uint8_t        peer_ip[4];
5926   uint16_t       peer_port;
5927   uint32_t       ip_len;
5928   osThreadId_t   worker;
5929   int32_t        rval;
5930   IO_GETPEERNAME io;
5931   int32_t        sock;
5932
5933   if (socket_funcs_exist == 0U) {
5934     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
5935     return;
5936   }
5937
5938   if (station_init (1) == 0) {
5939     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
5940     return;
5941   }
5942
5943   /* Create worker thread */
5944   worker = osThreadNew ((osThreadFunc_t)Th_GetPeerName, &io, NULL);
5945   if (worker == NULL) {
5946     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5947     return;
5948   }
5949
5950   ARG_INIT();
5951
5952   /* Create stream socket */
5953   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5954   if (io.rc < 0) {
5955     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5956   } else {
5957     sock = io.rc;
5958
5959     /* Connect to stream server */
5960     io.sock = sock;
5961     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
5962     TH_ASSERT  (io.rc == 0);
5963
5964     /* Check parameter (socket = -1) */
5965     ip_len = sizeof(peer_ip);
5966     ARG_GETPEERNAME (-1, peer_ip, &ip_len, &peer_port);
5967     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
5968     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5969
5970     /* Check parameter (socket = INT32_MIN) */
5971     ARG_GETPEERNAME (INT32_MIN, peer_ip, &ip_len, &peer_port);
5972     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
5973     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5974
5975     /* Check parameter (socket = INT32_MAX) */
5976     ARG_GETPEERNAME (INT32_MAX, peer_ip, &ip_len, &peer_port);
5977     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
5978     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5979
5980     /* Check parameter (port = NULL) */
5981     ip_len = sizeof(peer_ip);
5982     ARG_GETPEERNAME (sock, peer_ip, &ip_len, NULL);
5983     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
5984     /* Request IP address only should be accepted */
5985     TH_ASSERT  (io.rc == 0);
5986
5987     /* Check parameter (ip = NULL, ip_len = NULL) */
5988     ARG_GETPEERNAME (sock, NULL, NULL, &peer_port);
5989     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
5990     /* Request port only should be accepted */
5991     TH_ASSERT  (io.rc == 0);
5992
5993     /* Initialize buffers for return values */
5994     peer_port = 0;
5995     ip_len    = sizeof(peer_ip) + 1;
5996     memcpy (peer_ip, ip_bcast, sizeof(peer_ip));
5997
5998     /* Retrieve peer name */
5999     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6000     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6001     TH_ASSERT  (io.rc == 0);
6002     /* IP address should be the address of the server */
6003     TH_ASSERT  ((memcmp ((const void *)peer_ip, (const void *)ip_socket_server, 4) == 0) && (ip_len == 4));
6004     /* Port number should be the DISCARD port */
6005     TH_ASSERT  (peer_port == DISCARD_PORT);
6006
6007     /* Close stream socket */
6008     io.sock = sock;
6009     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6010     TH_ASSERT  (io.rc == 0);
6011
6012     /* Retrieve peer name again */
6013     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6014     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6015     /* Should return error (socket not created) */
6016     /* Strict: ESOCK, valid non-strict: ERROR */
6017     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getpeername on closed socket", io.rc, ARM_SOCKET_ESOCK);
6018
6019     osDelay (10);
6020   }
6021
6022   /* Create stream socket */
6023   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6024   if (io.rc < 0) {
6025     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6026   } else {
6027     sock = io.rc;
6028
6029     /* Get peer name, created socket */
6030     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6031     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6032     /* Should return error (socket not connected) */
6033     /* Strict: ENOTCONN, valid non-strict: ERROR */
6034     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "getpeername on created socket", io.rc, ARM_SOCKET_ENOTCONN);
6035
6036     /* Bind socket */
6037     io.sock = sock;
6038     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
6039     TH_ASSERT  (io.rc == 0);
6040
6041     /* Get peer name, bound socket */
6042     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6043     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6044     /* Should return error (socket not connected) */
6045     /* Strict: ENOTCONN, valid non-strict: ERROR */
6046     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "getpeername on bound socket", io.rc, ARM_SOCKET_ENOTCONN);
6047
6048     /* Start listening */
6049     io.sock = sock;
6050     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
6051     TH_ASSERT  (io.rc == 0);
6052
6053     /* Get peer name, listening socket */
6054     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6055     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6056     /* Should return error (socket not connected) */
6057     /* Strict: ENOTCONN, valid non-strict: ERROR */
6058     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "getpeername on listening socket", io.rc, ARM_SOCKET_ENOTCONN);
6059
6060     /* Close socket */
6061     io.sock = sock;
6062     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6063     TH_ASSERT  (io.rc == 0);
6064
6065     osDelay (10);
6066   }
6067
6068   /* Create datagram socket */
6069   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
6070   if (io.rc < 0) {
6071     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
6072   } else {
6073     sock = io.rc;
6074
6075     /* Connect to datagram server */
6076     io.sock = sock;
6077     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
6078     TH_ASSERT  (io.rc == 0);
6079
6080     /* Check parameter (socket = -1) */
6081     ip_len =  sizeof(peer_ip);
6082     ARG_GETPEERNAME (-1, peer_ip, &ip_len, &peer_port);
6083     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6084     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6085
6086     /* Check parameter (socket = INT32_MIN) */
6087     ARG_GETPEERNAME (INT32_MIN, peer_ip, &ip_len, &peer_port);
6088     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6089     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6090
6091     /* Check parameter (socket = INT32_MAX) */
6092     ARG_GETPEERNAME (INT32_MAX, peer_ip, &ip_len, &peer_port);
6093     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6094     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6095
6096     /* Check parameter (port = NULL) */
6097     ip_len = sizeof(peer_ip);
6098     ARG_GETPEERNAME (sock, peer_ip, &ip_len, NULL);
6099     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6100     /* Request IP address only should be accepted */
6101     TH_ASSERT  (io.rc == 0);
6102
6103     /* Check parameter (ip = NULL, ip_len = NULL) */
6104     ARG_GETPEERNAME (sock, NULL, NULL, &peer_port);
6105     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6106     /* Request port only should be accepted */
6107     TH_ASSERT  (io.rc == 0);
6108
6109     /* Initialize buffers for return values */
6110     peer_port = 0;
6111     ip_len    = sizeof(peer_ip) + 1;
6112     memcpy (peer_ip, ip_bcast, sizeof(peer_ip));
6113
6114     /* Retrieve peer name */
6115     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6116     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6117     TH_ASSERT  (io.rc == 0);
6118     /* IP address should be the address of the server */
6119     TH_ASSERT  ((memcmp ((const void *)peer_ip, (const void *)ip_socket_server, 4) == 0) && (ip_len == 4));
6120     /* Port number should be the DISCARD port */
6121     TH_ASSERT  (peer_port == DISCARD_PORT);
6122
6123     /* Close socket */
6124     io.sock = sock;
6125     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6126     TH_ASSERT  (io.rc == 0);
6127
6128     /* Retrieve peer name again */
6129     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6130     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6131     /* Should return error (socket not created) */
6132     /* Strict: ESOCK, valid non-strict: ERROR */
6133     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getpeername on closed socket", io.rc, ARM_SOCKET_ESOCK);
6134
6135     osDelay (10);
6136   }
6137
6138   if (rval == 0) {
6139     station_uninit ();
6140   }
6141
6142   /* Terminate worker thread */
6143   osThreadTerminate (worker);
6144 }
6145
6146 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
6147
6148 /* GetOpt IO parameters */
6149 typedef struct {
6150   int32_t      sock;
6151   int32_t      opt_id;
6152   void        *opt_val;
6153   uint32_t    *opt_len;
6154   int32_t      rc;
6155   /* Control */
6156   osThreadId_t owner;
6157   uint32_t     xid;
6158 } IO_GETOPT;
6159
6160 /* Assign arguments */
6161 #define ARG_GETOPT(_sock,_opt_id,_opt_val,_opt_len) do {                     \
6162                                                       io.sock    = _sock;    \
6163                                                       io.opt_id  = _opt_id;  \
6164                                                       io.opt_val = _opt_val; \
6165                                                       io.opt_len = _opt_len; \
6166                                                     } while (0)
6167
6168 /* GetOpt worker thread */
6169 __NO_RETURN static void Th_GetOpt (IO_GETOPT *io) {
6170   uint32_t flags,xid;
6171
6172   for (;;) {
6173     /* Wait for the signal to select and execute the function */
6174     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP |
6175                                F_GETOPT     | F_CLOSE, osFlagsWaitAny, osWaitForever);
6176     xid   = io->xid;
6177     switch (flags) {
6178       case F_CREATE_TCP:
6179         /* Create stream socket */
6180         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
6181         break;
6182
6183       case F_CREATE_UDP:
6184         /* Create datagram socket */
6185         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
6186         break;
6187
6188       case F_GETOPT:
6189         /* Get socket options */
6190         io->rc = drv->SocketGetOpt (io->sock, io->opt_id, io->opt_val, io->opt_len);
6191         break;
6192
6193       case F_CLOSE:
6194         /* Close socket */
6195         io->rc = drv->SocketClose (io->sock);
6196         break;
6197     }
6198     /* Done, send signal to owner thread */
6199     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
6200     osDelay(1);
6201     osThreadFlagsSet (io->owner, flags);
6202     osThreadFlagsClear (F_ALL);
6203   }
6204 }
6205
6206 /**
6207 \brief  Test case: WIFI_SocketGetOpt
6208 \ingroup wifi_sock_api
6209 \details
6210 The test case \b WIFI_SocketGetOpt verifies the WiFi Driver \b SocketGetOpt function:
6211 \code
6212 int32_t (*SocketGetOpt) (int32_t socket, int32_t opt_id, void *opt_val, uint32_t *opt_len);
6213 \endcode
6214
6215 Stream socket test:
6216  - Create stream socket
6217  - Check function parameters
6218  - Get socket options
6219  - Close socket
6220  - Get socket options again, closed socket
6221
6222 Datagram socket test:
6223  - Create datagram socket
6224  - Get socket type
6225  - Close socket
6226  - Get socket type
6227 */
6228 void WIFI_SocketGetOpt (void) {
6229   uint32_t     opt_val;
6230   uint32_t     opt_len;
6231   osThreadId_t worker;
6232   int32_t      rval;
6233   IO_GETOPT    io;
6234   int32_t      sock;
6235
6236   if (socket_funcs_exist == 0U) {
6237     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
6238     return;
6239   }
6240
6241   if (station_init (1) == 0) {
6242     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
6243     return;
6244   }
6245
6246   /* Create worker thread */
6247   worker = osThreadNew ((osThreadFunc_t)Th_GetOpt, &io, NULL);
6248   if (worker == NULL) {
6249     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
6250     return;
6251   }
6252
6253   ARG_INIT();
6254
6255   /* Create stream socket */
6256   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6257   if (io.rc < 0) {
6258     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6259   } else {
6260     sock = io.rc;
6261  
6262     /* Check parameter (socket = -1) */
6263     opt_len = sizeof(opt_val);
6264     ARG_GETOPT (-1, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6265     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6266     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6267
6268     /* Check parameter (socket = INT32_MIN) */
6269     ARG_GETOPT (INT32_MIN, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6270     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6271     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6272
6273     /* Check parameter (socket = INT32_MAX) */
6274     ARG_GETOPT (INT32_MAX, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6275     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6276     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6277
6278     /* Check parameter (opt_id = -1) */
6279     ARG_GETOPT (sock, -1, &opt_val, &opt_len);
6280     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6281     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6282
6283     /* Check parameter (opt_id = INT32_MIN) */
6284     ARG_GETOPT (sock, INT32_MIN, &opt_val, &opt_len);
6285     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6286     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6287
6288     /* Check parameter (opt_id = INT32_MAX) */
6289     ARG_GETOPT (sock, INT32_MAX, &opt_val, &opt_len);
6290     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6291     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6292
6293     /* Check parameter (opt_val = NULL) */
6294     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, NULL, &opt_len);
6295     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6296     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6297
6298     /* Check parameter (opt_len = NULL) */
6299     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, NULL);
6300     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6301     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6302
6303     /* Check parameter (*opt_len = 0) */
6304     opt_len = 0;
6305     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6306     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6307     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6308
6309     /* Check parameter (*opt_len = 5) */
6310     opt_len = 5;
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 == 0) && (opt_len == 4));
6314
6315     /* Get option FIONBIO (set only) */
6316     opt_len = sizeof(opt_val);
6317     ARG_GETOPT (sock, ARM_SOCKET_IO_FIONBIO, &opt_val, &opt_len);
6318     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6319     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6320
6321     /* Get option RCVTIMEO */
6322     opt_len = sizeof(opt_val) + 1;
6323     opt_val = 0xE2A5A241;
6324     ARG_GETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, &opt_len);
6325     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6326     TH_ASSERT  (io.rc == 0);
6327     /* Should be different from the initial value */
6328     TH_ASSERT  ((opt_val != 0xE2A5A241) && (opt_len == 4));
6329
6330     /* Get option SNDTIMEO */
6331     opt_len = sizeof(opt_val) + 1;
6332     opt_val = 0xE2A5A241;
6333     ARG_GETOPT (sock, ARM_SOCKET_SO_SNDTIMEO, &opt_val, &opt_len);
6334     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6335     TH_ASSERT  (io.rc == 0);
6336     /* Should be different from the initial value */
6337     TH_ASSERT  ((opt_val != 0xE2A5A241) && (opt_len == 4));
6338
6339     /* Get option KEEPALIVE */
6340     opt_len = sizeof(opt_val) + 1;
6341     opt_val = 0xE2A5A241;
6342     ARG_GETOPT (sock, ARM_SOCKET_SO_KEEPALIVE, &opt_val, &opt_len);
6343     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6344     TH_ASSERT  (io.rc == 0);
6345     /* Should be different from the initial value */
6346     TH_ASSERT  ((opt_val != 0xE2A5A241) && (opt_len == 4));
6347
6348     /* Get option socket TYPE */
6349     opt_len = sizeof(opt_val) + 1;
6350     opt_val = UINT32_MAX;
6351     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6352     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6353     TH_ASSERT  (io.rc == 0);
6354     /* Should be SOCK_STREAM type */
6355     TH_ASSERT  ((opt_val == ARM_SOCKET_SOCK_STREAM) && (opt_len == 4));
6356
6357     /* Close stream socket */
6358     io.sock = sock;
6359     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6360     TH_ASSERT  (io.rc == 0);
6361
6362     /* Get option socket TYPE again */
6363     opt_len = sizeof(opt_val);
6364     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6365     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6366     /* Should return error (socket not created) */
6367     /* Strict: ESOCK, valid non-strict: ERROR */
6368     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
6369
6370     osDelay (10);
6371   }
6372
6373   /* Create datagram socket */
6374   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
6375   if (io.rc < 0) {
6376     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
6377   } else {
6378     sock = io.rc;
6379
6380     /* Get option socket TYPE */
6381     opt_len = sizeof(opt_val) + 1;
6382     opt_val = UINT32_MAX;
6383     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6384     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6385     TH_ASSERT  (io.rc == 0);
6386     /* Should be SOCK_DGRAM type */
6387     TH_ASSERT  ((opt_val == ARM_SOCKET_SOCK_DGRAM) && (opt_len == 4));
6388
6389     /* Close socket */
6390     io.sock = sock;
6391     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6392     TH_ASSERT  (io.rc == 0);
6393
6394     /* Get option socket TYPE again */
6395     opt_len = sizeof(opt_val);
6396     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
6397     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
6398     /* Should return error (socket not created) */
6399     /* Strict: ESOCK, valid non-strict: ERROR */
6400     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
6401
6402     osDelay (10);
6403   }
6404
6405   if (rval == 0) {
6406     station_uninit ();
6407   }
6408
6409   /* Terminate worker thread */
6410   osThreadTerminate (worker);
6411 }
6412
6413 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
6414
6415 /* SetOpt IO parameters */
6416 typedef struct {
6417   int32_t      sock;
6418   int32_t      opt_id;
6419   const void  *opt_val;
6420   uint32_t     opt_len;
6421   int32_t      rc;
6422   /* Control */
6423   osThreadId_t owner;
6424   uint32_t     xid;
6425 } IO_SETOPT;
6426
6427 /* Assign arguments */
6428 #define ARG_SETOPT(_sock,_opt_id,_opt_val,_opt_len) do {                     \
6429                                                       io.sock    = _sock;    \
6430                                                       io.opt_id  = _opt_id;  \
6431                                                       io.opt_val = _opt_val; \
6432                                                       io.opt_len = _opt_len; \
6433                                                     } while (0)
6434
6435 /* SetOpt worker thread */
6436 __NO_RETURN static void Th_SetOpt (IO_SETOPT *io) {
6437   uint32_t flags,xid;
6438
6439   for (;;) {
6440     /* Wait for the signal to select and execute the function */
6441     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_SETOPT | F_CLOSE, osFlagsWaitAny, osWaitForever);
6442     xid   = io->xid;
6443     switch (flags) {
6444       case F_CREATE_TCP:
6445         /* Create stream socket */
6446         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
6447         break;
6448
6449       case F_CREATE_UDP:
6450         /* Create datagram socket */
6451         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
6452         break;
6453
6454       case F_SETOPT:
6455         /* Set socket options */
6456         io->rc = drv->SocketSetOpt (io->sock, io->opt_id, io->opt_val, io->opt_len);
6457         break;
6458
6459       case F_CLOSE:
6460         /* Close socket */
6461         io->rc = drv->SocketClose (io->sock);
6462         break;
6463     }
6464     /* Done, send signal to owner thread */
6465     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
6466     osDelay(1);
6467     osThreadFlagsSet (io->owner, flags);
6468     osThreadFlagsClear (F_ALL);
6469   }
6470 }
6471
6472 /**
6473 \brief  Test case: WIFI_SocketSetOpt
6474 \ingroup wifi_sock_api
6475 \details
6476 The test case \b WIFI_SocketSetOpt verifies the WiFi Driver \b SocketSetOpt function:
6477 \code
6478 int32_t (*SocketSetOpt) (int32_t socket, int32_t opt_id, const void *opt_val, uint32_t opt_len);
6479 \endcode
6480
6481 Stream socket test:
6482  - Create stream socket
6483  - Check function parameters
6484  - Set socket options
6485  - Close socket
6486  - Set socket option again, closed socket
6487
6488 Datagram socket test:
6489  - Create datagram socket
6490  - Set socket options
6491  - Close socket
6492  - Set socket option again, closed socket
6493 */
6494
6495 void WIFI_SocketSetOpt (void) {
6496   uint32_t     opt_val;
6497   osThreadId_t worker;
6498   int32_t      rval;
6499   IO_SETOPT    io;
6500   int32_t      sock;
6501
6502   if (socket_funcs_exist == 0U) {
6503     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
6504     return;
6505   }
6506
6507   if (station_init (1) == 0) {
6508     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
6509     return;
6510   }
6511
6512   /* Create worker thread */
6513   worker = osThreadNew ((osThreadFunc_t)Th_SetOpt, &io, NULL);
6514   if (worker == NULL) {
6515     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
6516     return;
6517   }
6518
6519   ARG_INIT();
6520
6521   /* Create stream socket */
6522   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6523   if (io.rc < 0) {
6524     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6525   } else {
6526     sock = io.rc;
6527  
6528     /* Check parameter (socket = -1) */
6529     opt_val = 5000;
6530     ARG_SETOPT (-1, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6531     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6532     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6533
6534     /* Check parameter (socket = INT32_MIN) */
6535     ARG_SETOPT (-1, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6536     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6537     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6538
6539     /* Check parameter (socket = INT32_MAX) */
6540     ARG_SETOPT (-1, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6541     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6542     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6543
6544     /* Check parameter (opt_id = -1) */
6545     ARG_SETOPT (sock, -1, &opt_val, sizeof(opt_val));
6546     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6547     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6548
6549     /* Check parameter (opt_id = INT32_MIN) */
6550     ARG_SETOPT (sock, INT32_MIN, &opt_val, sizeof(opt_val));
6551     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6552     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6553
6554     /* Check parameter (opt_id = INT32_MAX) */
6555     ARG_SETOPT (sock, INT32_MAX, &opt_val, sizeof(opt_val));
6556     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6557     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6558
6559     /* Check parameter (opt_val = NULL) */
6560     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, NULL, sizeof(opt_val));
6561     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6562     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6563
6564     /* Check parameter (opt_len = 0) */
6565     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, 0);
6566     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6567     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6568
6569     /* Check parameter (opt_len = 3) */
6570     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, 3);
6571     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6572     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6573
6574     /* Set option FIONBIO (set only) */
6575     opt_val = 0;
6576     ARG_SETOPT (sock, ARM_SOCKET_IO_FIONBIO, &opt_val, sizeof(opt_val));
6577     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6578     TH_ASSERT  (io.rc == 0);
6579
6580     /* Set option RCVTIMEO */
6581     opt_val = 5000;
6582     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6583     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6584     TH_ASSERT  (io.rc == 0);
6585
6586     /* Set option SNDTIMEO */
6587     opt_val = 2000;
6588     ARG_SETOPT (sock, ARM_SOCKET_SO_SNDTIMEO, &opt_val, sizeof(opt_val));
6589     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6590     TH_ASSERT  (io.rc == 0);
6591
6592     /* Set option KEEPALIVE */
6593     opt_val = 1;
6594     ARG_SETOPT (sock, ARM_SOCKET_SO_KEEPALIVE, &opt_val, sizeof(opt_val));
6595     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6596     TH_ASSERT  (io.rc == 0);
6597
6598     /* Set option socket TYPE (get only) */
6599     opt_val = ARM_SOCKET_SOCK_STREAM;
6600     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, sizeof(opt_val));
6601     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6602     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6603
6604     /* Close stream socket */
6605     io.sock = sock;
6606     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6607     TH_ASSERT  (io.rc == 0);
6608
6609     /* Set option RCVTIMEO again */
6610     opt_val = 5000;
6611     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6612     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6613     /* Should return error (socket not created) */
6614     /* Strict: ESOCK, valid non-strict: ERROR */
6615     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "setsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
6616
6617     osDelay (10);
6618   }
6619
6620   /* Create datagram socket */
6621   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
6622   if (io.rc < 0) {
6623     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
6624   } else {
6625     sock = io.rc;
6626
6627     /* Set option RCVTIMEO */
6628     opt_val = 5000;
6629     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6630     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6631     TH_ASSERT  (io.rc == 0);
6632
6633     /* Close socket */
6634     io.sock = sock;
6635     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6636     TH_ASSERT  (io.rc == 0);
6637
6638     /* Set option RCVTIMEO again */
6639     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
6640     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
6641     /* Should return error (socket not created) */
6642     /* Strict: ESOCK, valid non-strict: ERROR */
6643     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "setsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
6644
6645     osDelay (10);
6646   }
6647
6648   if (rval == 0) {
6649     station_uninit ();
6650   }
6651
6652   /* Terminate worker thread */
6653   osThreadTerminate (worker);
6654 }
6655
6656 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
6657
6658 /* Close IO parameters */
6659 typedef struct {
6660   int32_t      sock;
6661   int32_t      rc;
6662   /* Control */
6663   osThreadId_t owner;
6664   uint32_t     xid;
6665 } IO_CLOSE;
6666
6667 /* Assign arguments */
6668 #define ARG_CLOSE(_sock) do {               \
6669                            io.sock = _sock; \
6670                          } while (0)
6671
6672 /* Close worker thread */
6673 __NO_RETURN static void Th_Close (IO_CLOSE *io) {
6674   uint32_t flags,xid;
6675
6676   for (;;) {
6677     /* Wait for the signal to select and execute the function */
6678     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_BIND |
6679                                F_CONNECT    | F_LISTEN     | F_CLOSE, osFlagsWaitAny, osWaitForever);
6680     xid   = io->xid;
6681     switch (flags) {
6682       case F_CREATE_TCP:
6683         /* Create stream socket */
6684         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
6685         break;
6686
6687       case F_CREATE_UDP:
6688         /* Create datagram socket */
6689         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
6690         break;
6691
6692       case F_BIND:
6693         /* Bind socket */
6694         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
6695         break;
6696
6697       case F_CONNECT:
6698         /* Connect on socket */
6699         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
6700         break;
6701
6702       case F_LISTEN:
6703         /* Listen on socket */
6704         io->rc = drv->SocketListen (io->sock, 1);
6705         break;
6706
6707       case F_CLOSE:
6708         /* Close socket */
6709         io->rc = drv->SocketClose (io->sock);
6710         break;
6711     }
6712     /* Done, send signal to owner thread */
6713     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
6714     osDelay(1);
6715     osThreadFlagsSet (io->owner, flags);
6716     osThreadFlagsClear (F_ALL);
6717   }
6718 }
6719
6720 /**
6721 \brief  Test case: WIFI_SocketClose
6722 \ingroup wifi_sock_api
6723 \details
6724 The test case \b WIFI_SocketClose verifies the WiFi Driver \b SocketClose function:
6725 \code
6726 int32_t (*SocketClose) (int32_t socket);
6727 \endcode
6728
6729 Stream socket test 1:
6730  - Create stream socket
6731  - Bind socket
6732  - Connect to server
6733  - Check function parameters
6734  - Close socket
6735  - Close socket again
6736
6737 Stream socket test 2:
6738  - Create stream socket
6739  - Bind socket
6740  - Start listening
6741  - Close socket
6742  - Close socket again
6743
6744 Datagram socket test:
6745  - Create datagram socket
6746  - Bind socket
6747  - Check function parameters
6748  - Close socket
6749  - Close socket again
6750 */
6751 void WIFI_SocketClose (void) {
6752   osThreadId_t worker;
6753   int32_t      rval;
6754   IO_CLOSE     io;
6755   int32_t      sock;
6756
6757   if (socket_funcs_exist == 0U) {
6758     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
6759     return;
6760   }
6761
6762   if (station_init (1) == 0) {
6763     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
6764     return;
6765   }
6766
6767   /* Create worker thread */
6768   worker = osThreadNew ((osThreadFunc_t)Th_Close, &io, NULL);
6769   if (worker == NULL) {
6770     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
6771     return;
6772   }
6773
6774   ARG_INIT();
6775
6776   /* Create stream socket */
6777   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6778   if (io.rc < 0) {
6779     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6780   } else {
6781     sock = io.rc;
6782
6783     /* Connect to stream server */
6784     io.sock = sock;
6785     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
6786     TH_ASSERT  (io.rc == 0);
6787
6788     /* Check parameter (socket = -1) */
6789     ARG_CLOSE  (-1);
6790     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6791     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6792
6793     /* Check parameter (socket = INT32_MIN) */
6794     ARG_CLOSE  (INT32_MIN);
6795     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6796     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6797
6798     /* Check parameter (socket = INT32_MAX) */
6799     ARG_CLOSE  (INT32_MAX);
6800     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6801     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6802
6803     /* Close socket */
6804     ARG_CLOSE  (sock);
6805     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6806     TH_ASSERT  (io.rc == 0);
6807
6808     /* Close again, closed socket */
6809     ARG_CLOSE  (sock);
6810     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6811     /* Should return error (socket not created) */
6812     /* Strict: ESOCK, valid non-strict: OK */
6813     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == 0), "close already closed socket", io.rc, ARM_SOCKET_ESOCK);
6814
6815     osDelay (10);
6816   }
6817
6818   /* Create stream socket */
6819   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6820   if (io.rc < 0) {
6821     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6822   } else {
6823     sock = io.rc;
6824
6825     /* Bind socket */
6826     io.sock = sock;
6827     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
6828     TH_ASSERT  (io.rc == 0);
6829
6830     /* Start listening */
6831     io.sock = sock;
6832     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
6833     TH_ASSERT  (io.rc == 0);
6834
6835     /* Close socket */
6836     ARG_CLOSE (sock);
6837     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6838     TH_ASSERT  (io.rc == 0);
6839
6840     /* Close again, closed socket */
6841     ARG_CLOSE (sock);
6842     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6843     /* Should return error (socket not created) */
6844     /* Strict: ESOCK, valid non-strict: OK */
6845     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == 0), "close already closed socket", io.rc, ARM_SOCKET_ESOCK);
6846
6847     osDelay (10);
6848   }
6849
6850   /* Create datagram socket */
6851   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
6852   if (io.rc < 0) {
6853     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
6854   } else {
6855     sock = io.rc;
6856
6857     /* Bind socket */
6858     io.sock = sock;
6859     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
6860     TH_ASSERT  (io.rc == 0);
6861
6862     /* Check parameter (socket = -1) */
6863     ARG_CLOSE  (-1);
6864     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6865     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6866
6867     /* Check parameter (socket = INT32_MIN) */
6868     ARG_CLOSE  (INT32_MIN);
6869     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6870     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6871
6872     /* Check parameter (socket = INT32_MAX) */
6873     ARG_CLOSE  (INT32_MAX);
6874     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6875     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6876
6877     /* Close socket */
6878     ARG_CLOSE  (sock);
6879     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6880     TH_ASSERT  (io.rc == 0);
6881
6882     /* Close again, closed socket */
6883     ARG_CLOSE  (sock);
6884     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6885     /* Should return error (socket not created) */
6886     /* Strict: ESOCK, valid non-strict: OK */
6887     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == 0), "close already closed socket", io.rc, ARM_SOCKET_ESOCK);
6888
6889     osDelay (10);
6890   }
6891
6892   if (rval == 0) {
6893     station_uninit ();
6894   }
6895
6896   /* Terminate worker thread */
6897   osThreadTerminate (worker);
6898 }
6899
6900 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
6901
6902 /* GetHostByName IO parameters */
6903 typedef struct {
6904   const char  *name;
6905   int32_t      af;
6906   uint8_t     *ip;
6907   uint32_t    *ip_len;
6908   int32_t      rc;
6909   /* Control */
6910   osThreadId_t owner;
6911   uint32_t     xid;
6912 } IO_GETHOST;
6913
6914 /* Assign arguments */
6915 #define ARG_GETHOST(_name,_af,_ip,_ip_len) do {                   \
6916                                              io.name   = _name;   \
6917                                              io.af     = _af;     \
6918                                              io.ip     = _ip;     \
6919                                              io.ip_len = _ip_len; \
6920                                            } while (0)
6921
6922 /* GetHostByName worker thread */
6923 __NO_RETURN static void Th_GetHostByName (IO_GETHOST *io) {
6924   uint32_t flags,xid;
6925
6926   for (;;) {
6927     /* Wait for the signal to select and execute the function */
6928     flags = osThreadFlagsWait (F_GETHOSTBYNAME, osFlagsWaitAny, osWaitForever);
6929     xid   = io->xid;
6930     switch (flags) {
6931       case F_GETHOSTBYNAME:
6932         /* Resolve host */
6933         io->rc = drv->SocketGetHostByName (io->name, io->af, io->ip, io->ip_len);
6934         break;
6935     }
6936     /* Done, send signal to owner thread */
6937     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
6938     osDelay(1);
6939     osThreadFlagsSet (io->owner, flags);
6940     osThreadFlagsClear (F_ALL);
6941   }
6942 }
6943
6944 /**
6945 \brief  Test case: WIFI_SocketGetHostByName
6946 \ingroup wifi_sock_api
6947 \details
6948 The test case \b WIFI_SocketGetHostByName the WiFi Driver \b SocketGetHostByName function:
6949 \code
6950 int32_t (*SocketGetHostByName) (const char *name, int32_t af, uint8_t *ip, uint32_t *ip_len);
6951 \endcode
6952
6953 Function test:
6954  - Check function parameters
6955  - Resolve host
6956  - Resolve non-existent host
6957
6958 \note
6959 This test requires internet connectivity to DNS server.
6960 */
6961 void WIFI_SocketGetHostByName (void) {
6962   const char  *host_name = "www.arm.com";
6963   uint8_t      host_ip[4];
6964   uint32_t     ip_len;
6965   osThreadId_t worker;
6966   int32_t      rval;
6967   IO_GETHOST   io;
6968
6969   if (socket_funcs_exist == 0U) {
6970     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
6971     return;
6972   }
6973
6974   if (station_init (1) == 0) {
6975     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
6976     return;
6977   }
6978
6979   /* Create worker thread */
6980   worker = osThreadNew ((osThreadFunc_t)Th_GetHostByName, &io, NULL);
6981   if (worker == NULL) {
6982     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
6983     return;
6984   }
6985
6986   ARG_INIT();
6987
6988   /* Check parameter (name = NULL) */
6989   ip_len = sizeof(host_ip);
6990   ARG_GETHOST(NULL, ARM_SOCKET_AF_INET, host_ip, &ip_len);
6991   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
6992   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6993
6994   /* Check parameter (af = -1) */
6995   ARG_GETHOST(host_name, -1, host_ip, &ip_len);
6996   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
6997   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6998
6999   /* Check parameter (af = INT32_MIN) */
7000   ARG_GETHOST(host_name, INT32_MIN, host_ip, &ip_len);
7001   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7002   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7003
7004   /* Check parameter (af = INT32_MAX) */
7005   ARG_GETHOST(host_name, INT32_MAX, host_ip, &ip_len);
7006   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7007   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7008
7009   /* Check parameter (ip = NULL) */
7010   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, NULL, &ip_len);
7011   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7012   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7013
7014   /* Check parameter (ip_len = NULL) */
7015   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, host_ip, NULL);
7016   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7017   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7018
7019   /* Check parameter (*ip_len = 0) */
7020   ip_len = 0;
7021   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, host_ip, &ip_len);
7022   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7023   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7024
7025   /* Check parameter (*ip_len = 3) */
7026   ip_len = 3;
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   /* Resolve valid host */
7032   ip_len = sizeof(host_ip) + 1;
7033   memset((void *)host_ip, 0, sizeof(host_ip));
7034   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, host_ip, &ip_len);
7035   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT_LONG);
7036   /* IP address should be valid */
7037   TH_ASSERT  ((memcmp((const void *)host_ip, (const void *)ip_unspec, 4) != 0) && (ip_len == 4));
7038
7039   /* Resolve non-existent host */
7040   ip_len = sizeof(host_ip);
7041   ARG_GETHOST("non.existent.host", ARM_SOCKET_AF_INET, host_ip, &ip_len);
7042   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT_LONG);
7043   /* Should return error (host not found) */
7044   /* Strict: EHOSTNOTFOUND, valid non-strict: ERROR */
7045   TH_ASSERT2 ((io.rc == ARM_SOCKET_EHOSTNOTFOUND), (io.rc == ARM_SOCKET_ERROR), "gethostbyname for non-existing host", io.rc, ARM_SOCKET_EHOSTNOTFOUND);
7046
7047   if (rval == 0) {
7048     station_uninit ();
7049   }
7050
7051   /* Terminate worker thread */
7052   osThreadTerminate (worker);
7053 }
7054
7055 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
7056
7057 /* Ping IO parameters */
7058 typedef struct {
7059   const uint8_t *ip;
7060   uint32_t       ip_len;
7061   int32_t        rc;
7062   /* Control */
7063   osThreadId_t owner;
7064   uint32_t     xid;
7065 } IO_PING;
7066
7067 /* Assign arguments */
7068 #define ARG_PING(_ip,_ip_len) do {                   \
7069                                 io.ip     = _ip;     \
7070                                 io.ip_len = _ip_len; \
7071                               } while (0)
7072
7073 /* Ping worker thread */
7074 __NO_RETURN static void Th_Ping (IO_PING *io) {
7075   uint32_t flags,xid;
7076
7077   for (;;) {
7078     /* Wait for the signal to select and execute the function */
7079     flags = osThreadFlagsWait (F_PING, osFlagsWaitAny, osWaitForever);
7080     xid   = io->xid;
7081     switch (flags) {
7082       case F_PING:
7083         /* Ping host */
7084         io->rc = drv->Ping (io->ip, io->ip_len);
7085         break;
7086     }
7087     /* Done, send signal to owner thread */
7088     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
7089     osDelay(1);
7090     osThreadFlagsSet (io->owner, flags);
7091     osThreadFlagsClear (F_ALL);
7092   }
7093 }
7094
7095 /**
7096 \brief  Test case: WIFI_Ping
7097 \ingroup wifi_sock_api
7098 \details
7099 The test case \b WIFI_Ping verifies the WiFi Driver \b Ping function:
7100 \code
7101 int32_t (*Ping) (const uint8_t *ip, uint32_t ip_len);
7102 \endcode
7103
7104 Function test:
7105  - Check function parameters
7106  - Ping host
7107 */
7108 void WIFI_Ping (void) {
7109   osThreadId_t worker;
7110   int32_t      rval;
7111   IO_PING      io;
7112
7113   if (drv->Ping == NULL) {
7114     TEST_ASSERT_MESSAGE(0,"[FAILED] Ping function not available");
7115     return;
7116   }
7117
7118   if (station_init (1) == 0) {
7119     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7120     return;
7121   }
7122
7123   /* Create worker thread */
7124   worker = osThreadNew ((osThreadFunc_t)Th_Ping, &io, NULL);
7125   if (worker == NULL) {
7126     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7127     return;
7128   }
7129
7130   ARG_INIT();
7131
7132   /* Check parameter (ip = NULL) */
7133   ARG_PING   (NULL, 4);
7134   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
7135   TH_ASSERT  (io.rc == ARM_DRIVER_ERROR_PARAMETER);
7136
7137   /* Check parameter (ip_len = 0) */
7138   ARG_PING   (ip_socket_server, 0);
7139   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
7140   TH_ASSERT  (io.rc == ARM_DRIVER_ERROR_PARAMETER);
7141
7142   /* Check parameter (ip_len = 5) */
7143   ARG_PING   (ip_socket_server, 5);
7144   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
7145   TH_ASSERT  (io.rc == ARM_DRIVER_ERROR_PARAMETER);
7146
7147   /* Ping server */
7148   ARG_PING   (ip_socket_server, 4);
7149   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
7150   TH_ASSERT  (io.rc == ARM_DRIVER_OK);
7151
7152   if (rval == 0) {
7153     station_uninit ();
7154   }
7155
7156   /* Terminate worker thread */
7157   osThreadTerminate (worker);
7158 }
7159
7160 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
7161
7162 /**
7163 \defgroup wifi_sock_op WiFi Socket Operation
7164 \ingroup wifi_funcs
7165 \details 
7166 These tests verify operation of the WiFi socket functions.
7167 */
7168
7169 /* Worker thread is used for the following tests:
7170    - WIFI_Transfer_Fixed
7171    - WIFI_Transfer_Incremental
7172    - WIFI_Send_Fragmented
7173    - WIFI_Recv_Fragmented
7174    - WIFI_Test_Speed
7175    - WIFI_Concurrent_Socket
7176 */
7177
7178 /* Transfer IO parameters */
7179 typedef struct {
7180   int32_t      sock;
7181   uint32_t     len;
7182   uint32_t     size;
7183   int32_t      rc;
7184   /* Control */
7185   osThreadId_t owner;
7186   uint32_t     xid;
7187 } IO_TRANSFER;
7188
7189 /* Assign arguments */
7190 #define ARG_TRANSFER(_sock,_len,_size) do {               \
7191                                          io.sock = _sock; \
7192                                          io.len  = _len;  \
7193                                          io.size = _size; \
7194                                        } while (0)
7195
7196 /* Transfer worker thread */
7197 __NO_RETURN static void Th_Transfer (IO_TRANSFER *io) {
7198   uint32_t flags,xid,i;
7199   int32_t  rc = 0;
7200
7201   for (;;) {
7202     /* Wait for the signal to select and execute the function */
7203     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP |
7204                                F_CONNECT    | F_CLOSE      |
7205                                F_XFER_FIXED | F_XFER_INCR  |
7206                                F_SEND_FRAG  | F_RECV_FRAG, osFlagsWaitAny, osWaitForever);
7207     xid   = io->xid;
7208     switch (flags) {
7209       case F_CREATE_TCP:
7210         /* Create stream socket */
7211         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
7212         break;
7213
7214       case F_CREATE_UDP:
7215         /* Create datagram socket */
7216         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
7217         break;
7218
7219       case F_CONNECT:
7220         /* Connect on socket */
7221         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, ECHO_PORT);
7222         break;
7223
7224       case F_CLOSE:
7225         /* Close socket */
7226         io->rc = drv->SocketClose (io->sock);
7227         break;
7228
7229       case F_XFER_FIXED:
7230         /* Transfer Fixed size blocks */
7231         memset ((void *)buffer, 0xCC, io->len);
7232         /* Send and receive in small blocks */
7233         for (i = 0; i < io->len; i += io->size) {
7234           rc = drv->SocketSend (io->sock, &test_buf[i], io->size);
7235           if (rc <= 0) break;
7236           rc = drv->SocketRecv (io->sock, &buffer[i], io->size);
7237           if (rc <= 0) break;
7238         }
7239         if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
7240           rc = (int32_t)i;
7241         }
7242         io->rc = rc;
7243         break;
7244
7245       case F_XFER_INCR:
7246         /* Transfer Increased size blocks */
7247         memset ((void *)buffer, 0xCC, io->len);
7248         /* Send and receive in enlarged block sizes */
7249         for (i = 0; i < io->len; i += io->size++) {
7250           rc = drv->SocketSend (io->sock, &test_buf[i], io->size);
7251           if (rc <= 0) break;
7252           rc = drv->SocketRecv (io->sock, &buffer[i], io->size);
7253           if (rc <= 0) break;
7254         }
7255         if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
7256           rc = (int32_t)i;
7257         }
7258         io->rc = rc;
7259         break;
7260
7261       case F_SEND_FRAG:
7262         /* Send Fragmented blocks */
7263         memset ((void *)buffer, 0xCC, io->len);
7264         /* Send in small blocks */
7265         for (i = 0; i < io->len; i += io->size) {
7266           rc = drv->SocketSend (io->sock, &test_buf[i], io->size);
7267           if (rc <= 0) break;
7268         }
7269         /* Receive in single block */
7270         if (rc > 0) {
7271           /* Small delay that blocks are received */
7272           osDelay (100);
7273           for (i = 0; i < io->len; i += (uint32_t)rc) {
7274             /* Returns any data available, up to requested amount */
7275             rc = drv->SocketRecv (io->sock, &buffer[i], io->len-i);
7276             if (rc <= 0) break;
7277           }
7278           if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
7279             rc = (int32_t)i;
7280           }
7281         }
7282         io->rc = rc;
7283         break;
7284
7285       case F_RECV_FRAG:
7286         /* Receive Fragmented blocks */
7287         memset ((void *)buffer, 0xCC, io->len);
7288         /* Send single block */
7289         rc = drv->SocketSend (io->sock, test_buf, io->len);
7290         if (rc > 0) {
7291           osDelay (100);
7292           /* Receive in small blocks */
7293           for (i = 0; i < io->len; i += io->size) {
7294             rc = drv->SocketRecv (io->sock, &buffer[i], io->size);
7295           }
7296           if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
7297             rc = (int32_t)i;
7298           }
7299         }
7300         io->rc = rc;
7301         break;
7302     }
7303     /* Done, send signal to owner thread */
7304     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
7305     osDelay(1);
7306     osThreadFlagsSet (io->owner, flags);
7307     osThreadFlagsClear (F_ALL);
7308   }
7309 }
7310
7311 /**
7312 \brief  Test case: WIFI_Transfer_Fixed
7313 \ingroup wifi_sock_op
7314 \details
7315 The test case \b WIFI_Transfer_Fixed verifies data transfer in fixed size blocks.
7316  
7317 Stream socket test: 
7318  - Create stream socket
7319  - Transfer 128 blocks of   16 bytes
7320  - Transfer  32 blocks of   64 bytes
7321  - Transfer   8 blocks of  256 bytes
7322  - Transfer   2 blocks of 1024 bytes
7323  - Transfer   1 block  of 1440 bytes
7324  - Close socket
7325
7326 Datagram socket test:
7327  - Create datagram socket
7328  - Transfer 128 blocks of   16 bytes
7329  - Transfer  32 blocks of   64 bytes
7330  - Transfer   8 blocks of  256 bytes
7331  - Transfer   2 blocks of 1024 bytes
7332  - Transfer   1 block  of 1460 bytes
7333  - Close socket
7334 */
7335 void WIFI_Transfer_Fixed (void) {
7336   osThreadId_t worker;
7337   int32_t      rval;
7338   IO_TRANSFER  io;
7339   int32_t      sock;
7340
7341   if (station_init (1) == 0) {
7342     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7343     return;
7344   }
7345
7346   /* Create worker thread */
7347   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
7348   if (worker == NULL) {
7349     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7350     return;
7351   }
7352
7353   ARG_INIT();
7354
7355   /* Create stream socket */
7356   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7357   if (io.rc < 0) {
7358     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7359   } else {
7360     sock = io.rc;
7361
7362     /* Connect to stream server */
7363     io.sock = sock;
7364     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7365     TH_ASSERT  (io.rc == 0);
7366
7367     /* Transfer 16-byte block(s) */
7368     ARG_TRANSFER (sock, 2048, 16);
7369     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7370     TH_ASSERT  (io.rc == 2048);
7371
7372     /* Transfer 64-byte block(s) */
7373     ARG_TRANSFER (sock, 2048, 64);
7374     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7375     TH_ASSERT  (io.rc == 2048);
7376
7377     /* Transfer 256-byte block(s) */
7378     ARG_TRANSFER (sock, 2048, 256);
7379     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7380     TH_ASSERT  (io.rc == 2048);
7381
7382     /* Transfer 1024-byte block(s) */
7383     ARG_TRANSFER (sock, 2048, 1024);
7384     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7385     TH_ASSERT  (io.rc == 2048);
7386
7387     /* Transfer 1440-byte block */
7388     ARG_TRANSFER (sock, 1440, 1440);
7389     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7390     TH_ASSERT  (io.rc == 1440);
7391
7392     /* Close stream socket */
7393     io.sock = sock;
7394     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7395     TH_ASSERT  (io.rc == 0);
7396
7397     osDelay (10);
7398   }
7399
7400   /* Create datagram socket */
7401   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
7402   if (io.rc < 0) {
7403     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
7404   } else {
7405     sock = io.rc;
7406
7407     /* Connect to datagram server */
7408     io.sock = sock;
7409     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
7410     TH_ASSERT  (io.rc == 0);
7411
7412     /* Transfer 16-byte block(s) */
7413     ARG_TRANSFER (sock, 2048, 16);
7414     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7415     TH_ASSERT  (io.rc == 2048);
7416
7417     /* Transfer 64-byte block(s) */
7418     ARG_TRANSFER (sock, 2048, 64);
7419     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7420     TH_ASSERT  (io.rc == 2048);
7421
7422     /* Transfer 256-byte block(s) */
7423     ARG_TRANSFER (sock, 2048, 256);
7424     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7425     TH_ASSERT  (io.rc == 2048);
7426
7427     /* Transfer 1024-byte block(s) */
7428     ARG_TRANSFER (sock, 2048, 1024);
7429     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7430     TH_ASSERT  (io.rc == 2048);
7431
7432     /* Transfer 1460-byte block */
7433     ARG_TRANSFER (sock, 1460, 1460);
7434     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7435     TH_ASSERT  (io.rc == 1460);
7436
7437     /* Close datagram socket */
7438     io.sock = sock;
7439     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7440     TH_ASSERT  (io.rc == 0);
7441
7442     osDelay (10);
7443   }
7444
7445   if (rval == 0) {
7446     station_uninit ();
7447   }
7448
7449   /* Terminate worker thread */
7450   osThreadTerminate (worker);
7451 }
7452
7453 /**
7454 \brief  Test case: WIFI_Transfer_Incremental
7455 \ingroup wifi_sock_op
7456 \details
7457 The test case \b WIFI_Transfer_Incremental verifies data transfer in ascending size blocks.
7458 Each subsequent block that the socket sends is one byte larger than the previous block.
7459
7460 Stream socket test:
7461  - Create stream socket
7462  - Transfer 51 blocks of   1 -  50 bytes
7463  - Transfer 30 blocks of  51 -  80 bytes
7464  - Transfer 20 blocks of  81 - 100 bytes
7465  - Transfer 13 blocks of 120 - 132 bytes
7466  - Transfer  8 blocks of 252 - 259 bytes
7467  - Transfer  4 blocks of 510 - 513 bytes
7468  - Close socket
7469
7470 Datagram socket test:
7471  - Create datagram socket
7472  - Transfer 51 blocks of   1 -  50 bytes
7473  - Transfer 30 blocks of  51 -  80 bytes
7474  - Transfer 20 blocks of  81 - 100 bytes
7475  - Transfer 13 blocks of 120 - 132 bytes
7476  - Transfer  8 blocks of 252 - 259 bytes
7477  - Transfer  4 blocks of 510 - 513 bytes
7478  - Close socket
7479 */
7480 void WIFI_Transfer_Incremental (void) {
7481   osThreadId_t worker;
7482   int32_t      rval;
7483   IO_TRANSFER  io;
7484   int32_t      sock;
7485
7486   if (station_init (1) == 0) {
7487     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7488     return;
7489   }
7490
7491   /* Create worker thread */
7492   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
7493   if (worker == NULL) {
7494     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7495     return;
7496   }
7497
7498   ARG_INIT();
7499
7500   /* Create stream socket */
7501   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7502   if (io.rc < 0) {
7503     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7504   } else {
7505     sock = io.rc;
7506
7507     /* Connect to stream server */
7508     io.sock = sock;
7509     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7510     TH_ASSERT  (io.rc == 0);
7511
7512     /* Transfer 1 byte - 50 byte blocks */
7513     ARG_TRANSFER (sock, 1275, 1);
7514     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7515     TH_ASSERT  (io.rc == 1275);
7516
7517     /* Transfer 51 byte - 80-byte blocks */
7518     ARG_TRANSFER (sock, 1965, 51);
7519     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7520     TH_ASSERT  (io.rc == 1965);
7521
7522     /* Transfer 81 byte - 100 byte blocks */
7523     ARG_TRANSFER (sock, 1810, 81);
7524     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7525     TH_ASSERT  (io.rc == 1810);
7526
7527     /* Transfer 120 byte - 132 byte blocks */
7528     ARG_TRANSFER (sock, 1905, 120);
7529     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7530     TH_ASSERT  (io.rc == 1905);
7531
7532     /* Transfer 252 byte - 259 byte blocks */
7533     ARG_TRANSFER (sock, 2044, 252);
7534     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7535     TH_ASSERT  (io.rc == 2044);
7536
7537     /* Transfer 510 byte - 513 byte blocks */
7538     ARG_TRANSFER (sock, 2046, 510);
7539     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7540     TH_ASSERT  (io.rc == 2046);
7541
7542     /* Close stream socket */
7543     io.sock = sock;
7544     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7545     TH_ASSERT  (io.rc == 0);
7546
7547     osDelay (10);
7548   }
7549
7550   /* Create datagram socket */
7551   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
7552   if (io.rc < 0) {
7553     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
7554   } else {
7555     sock = io.rc;
7556
7557     /* Connect to datagram server */
7558     io.sock = sock;
7559     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
7560     TH_ASSERT  (io.rc == 0);
7561
7562     /* Transfer 1 byte - 50 byte blocks */
7563     ARG_TRANSFER (sock, 1275, 1);
7564     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7565     TH_ASSERT  (io.rc == 1275);
7566
7567     /* Transfer 51 byte - 80-byte blocks */
7568     ARG_TRANSFER (sock, 1965, 51);
7569     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7570     TH_ASSERT  (io.rc == 1965);
7571
7572     /* Transfer 81 byte - 100 byte blocks */
7573     ARG_TRANSFER (sock, 1810, 81);
7574     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7575     TH_ASSERT  (io.rc == 1810);
7576
7577     /* Transfer 120 byte - 132 byte blocks */
7578     ARG_TRANSFER (sock, 1905, 120);
7579     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7580     TH_ASSERT  (io.rc == 1905);
7581
7582     /* Transfer 252 byte - 259 byte blocks */
7583     ARG_TRANSFER (sock, 2044, 252);
7584     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7585     TH_ASSERT  (io.rc == 2044);
7586
7587     /* Transfer 510 byte - 513 byte blocks */
7588     ARG_TRANSFER (sock, 2046, 510);
7589     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
7590     TH_ASSERT  (io.rc == 2046);
7591
7592     /* Close datagram socket */
7593     io.sock = sock;
7594     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7595     TH_ASSERT  (io.rc == 0);
7596
7597     osDelay (10);
7598   }
7599
7600   if (rval == 0) {
7601     station_uninit ();
7602   }
7603
7604   /* Terminate worker thread */
7605   osThreadTerminate (worker);
7606 }
7607
7608 /**
7609 \brief  Test case: WIFI_Send_Fragmented
7610 \ingroup wifi_sock_op
7611 \details
7612 The test case \b WIFI_Send_Fragmented verifies data transfer in chunks.
7613
7614 Stream socket test:
7615  - Create stream socket
7616  - Send 16 blocks of  16 bytes, receive 1 block of  256 bytes
7617  - Send 16 blocks of  64 bytes, receive 1 block of 1024 bytes
7618  - Send  5 blocks of 256 bytes, receive 1 block of 1280 bytes
7619  - Send  2 blocks of 720 bytes, receive 1 block of 1440 bytes
7620  - Close socket
7621 */
7622 void WIFI_Send_Fragmented (void) {
7623   osThreadId_t worker;
7624   int32_t      rval;
7625   IO_TRANSFER  io;
7626   int32_t      sock;
7627
7628   if (station_init (1) == 0) {
7629     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7630     return;
7631   }
7632
7633   /* Create worker thread */
7634   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
7635   if (worker == NULL) {
7636     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7637     return;
7638   }
7639
7640   ARG_INIT();
7641
7642   /* Create stream socket */
7643   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7644   if (io.rc < 0) {
7645     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7646   } else {
7647     sock = io.rc;
7648
7649     /* Connect to stream server */
7650     io.sock = sock;
7651     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7652     TH_ASSERT  (io.rc == 0);
7653
7654     /* Transfer 16-byte block(s) */
7655     ARG_TRANSFER (sock, 256, 16);
7656     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7657     TH_ASSERT  (io.rc == 256);
7658
7659     /* Transfer 64-byte block(s) */
7660     ARG_TRANSFER (sock, 1024, 64);
7661     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7662     TH_ASSERT  (io.rc == 1024);
7663
7664     /* Transfer 256-byte block(s) */
7665     ARG_TRANSFER (sock, 1280, 256);
7666     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7667     TH_ASSERT  (io.rc == 1280);
7668
7669     /* Transfer 1024-byte block(s) */
7670     ARG_TRANSFER (sock, 1440, 720);
7671     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7672     TH_ASSERT  (io.rc == 1440);
7673
7674     /* Close stream socket */
7675     io.sock = sock;
7676     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7677     TH_ASSERT  (io.rc == 0);
7678
7679     osDelay (10);
7680   }
7681
7682   if (rval == 0) {
7683     station_uninit ();
7684   }
7685
7686   /* Terminate worker thread */
7687   osThreadTerminate (worker);
7688 }
7689
7690 /**
7691 \brief  Test case: WIFI_Recv_Fragmented
7692 \ingroup wifi_sock_op
7693 \details
7694 The test case \b WIFI_Recv_Fragmented verifies data transfer in chunks.
7695
7696 Stream socket test:
7697  - Create stream socket
7698  - Send block of  256 bytes, receive 16 blocks of  16 bytes
7699  - Send block of 1024 bytes, receive 16 blocks of  64 bytes
7700  - Send block of 1280 bytes, receive  5 blocks of 256 bytes
7701  - Send block of 1440 bytes, receive  2 blocks of 720 bytes
7702  - Close socket
7703 */
7704 void WIFI_Recv_Fragmented (void) {
7705   osThreadId_t worker;
7706   int32_t      rval;
7707   IO_TRANSFER  io;
7708   int32_t      sock;
7709
7710   if (station_init (1) == 0) {
7711     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7712     return;
7713   }
7714
7715   /* Create worker thread */
7716   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
7717   if (worker == NULL) {
7718     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7719     return;
7720   }
7721
7722   ARG_INIT();
7723
7724   /* Create stream socket */
7725   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7726   if (io.rc < 0) {
7727     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7728   } else {
7729     sock = io.rc;
7730
7731     /* Connect to stream server */
7732     io.sock = sock;
7733     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7734     TH_ASSERT  (io.rc == 0);
7735
7736     /* Transfer 16-byte block(s) */
7737     ARG_TRANSFER (sock, 256, 16);
7738     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7739     TH_ASSERT  (io.rc == 256);
7740
7741     /* Transfer 64-byte block(s) */
7742     ARG_TRANSFER (sock, 1024, 64);
7743     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7744     TH_ASSERT  (io.rc == 1024);
7745
7746     /* Transfer 256-byte block(s) */
7747     ARG_TRANSFER (sock, 1280, 256);
7748     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7749     TH_ASSERT  (io.rc == 1280);
7750
7751     /* Transfer 720-byte block(s) */
7752     ARG_TRANSFER (sock, 1440, 720);
7753     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
7754     TH_ASSERT  (io.rc == 1440);
7755
7756     /* Close stream socket */
7757     io.sock = sock;
7758     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7759     TH_ASSERT (io.rc == 0);
7760
7761     osDelay (10);
7762   }
7763
7764   if (rval == 0) {
7765     station_uninit ();
7766   }
7767
7768   /* Terminate worker thread */
7769   osThreadTerminate (worker);
7770 }
7771
7772 /**
7773 \brief  Test case: WIFI_Test_Speed
7774 \ingroup wifi_sock_op
7775 \details
7776 The test case \b WIFI_Test_Speed tests data transfer speed.
7777
7778 Stream socket test:
7779  - Create stream socket
7780  - Transfer for 4 seconds, send and receive
7781  - Calculate transfer rate
7782  - Close socket
7783
7784 Datagram socket test:
7785  - Create datagram socket
7786  - Transfer for 4 seconds, send and receive
7787  - Calculate transfer rate
7788  - Close socket
7789 */
7790 void WIFI_Test_Speed (void) {
7791   uint32_t     ticks,tout;
7792   osThreadId_t worker;
7793   int32_t      rval,n_bytes;
7794   IO_TRANSFER  io;
7795   int32_t      sock;
7796
7797   if (station_init (1) == 0) {
7798     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7799     return;
7800   }
7801
7802   /* Create worker thread */
7803   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
7804   if (worker == NULL) {
7805     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7806     return;
7807   }
7808
7809   ARG_INIT();
7810
7811   /* Create stream socket */
7812   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7813   if (io.rc < 0) {
7814     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7815   } else {
7816     sock = io.rc;
7817
7818     /* Connect to stream server */
7819     io.sock = sock;
7820     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7821     TH_ASSERT  (io.rc == 0);
7822
7823     /* Transfer for 4 seconds */
7824     tout  = SYSTICK_MICROSEC(4000000);
7825     ticks = GET_SYSTICK();
7826     n_bytes = 0;
7827     do {
7828       ARG_TRANSFER (sock, 1440, 1440);
7829       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7830       if (io.rc > 0) n_bytes += io.rc;
7831       else           break;
7832     } while (GET_SYSTICK() - ticks < tout);
7833     /* Check transfer rate */
7834     if (n_bytes < 10000) {
7835       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
7836       TEST_MESSAGE(msg_buf);
7837     }
7838
7839     /* Close stream socket */
7840     io.sock = sock;
7841     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7842     TH_ASSERT  (io.rc == 0);
7843
7844     osDelay (10);
7845   }
7846
7847   /* Create datagram socket */
7848   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
7849   if (io.rc < 0) {
7850     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
7851   } else {
7852     sock = io.rc;
7853
7854     /* Connect to datagram server */
7855     io.sock = sock;
7856     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
7857     TH_ASSERT  (io.rc == 0);
7858
7859     /* Transfer for 4 seconds */
7860     tout  = SYSTICK_MICROSEC(4000000);
7861     ticks = GET_SYSTICK();
7862     n_bytes = 0;
7863     do {
7864       ARG_TRANSFER (sock, 1460, 1460);
7865       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
7866       if (io.rc > 0) n_bytes += io.rc;
7867       else           break;
7868     } while (GET_SYSTICK() - ticks < tout);
7869     /* Check transfer rate */
7870     if (n_bytes < 10000) {
7871       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
7872       TEST_MESSAGE(msg_buf);
7873     }
7874
7875     /* Close datagram socket */
7876     io.sock = sock;
7877     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7878     TH_ASSERT  (io.rc == 0);
7879
7880     osDelay (10);
7881   }
7882
7883   if (rval == 0) {
7884     station_uninit ();
7885   }
7886
7887   /* Terminate worker thread */
7888   osThreadTerminate (worker);
7889 }
7890
7891 /* Sidekick IO parameters */
7892 typedef struct {
7893   int32_t  sock;
7894   uint32_t count;
7895 } IO_SIDEKICK;
7896
7897 /* Concurrent coworker thread */
7898 __NO_RETURN static void Th_Sidekick (IO_SIDEKICK *io2) {
7899   uint8_t buff[48];
7900   int32_t rc;
7901
7902   for (;;) {
7903     if (osThreadFlagsWait (SK_TERMINATE, osFlagsWaitAny, 100) == SK_TERMINATE) {
7904       break;
7905     }
7906     memset ((void *)buff, 0xCC, sizeof(buff));
7907     rc = drv->SocketSend (io2->sock, test_msg, sizeof(test_msg));
7908     if (rc <= 0) break;
7909     rc = drv->SocketRecv (io2->sock, buff, sizeof(test_msg));
7910     if (rc <= 0) break;
7911     if (memcmp ((const void *)buff, (const void *)test_msg, sizeof(test_msg)) == 0) {
7912       io2->count += sizeof(test_msg);
7913     }
7914   }
7915   /* Owner deletes this thread */
7916   while (1) osDelay (osWaitForever);
7917 }
7918
7919 /**
7920 \brief  Test case: WIFI_Concurrent_Socket
7921 \ingroup wifi_sock_op
7922 \details
7923 The test case \b WIFI_Concurrent_Socket verifies transfer of two concurrent sockets.
7924
7925 Stream socket test:
7926  - Create two stream sockets
7927  - Start transfer on 2nd socket with 100ms intervals
7928  - Transfer on main socket, full speed
7929  - Calculate transfer rate
7930  - Close sockets
7931
7932 Datagram socket test:
7933  - Create datagram and stream sockets
7934  - Start transfer on stream socket with 100ms intervals
7935  - Transfer on main socket, full speed
7936  - Calculate transfer rate
7937  - Close sockets
7938 \note
7939 The test runs with a coherent thread, that performs an additional stream socket io.
7940 */
7941 void WIFI_Concurrent_Socket (void) {
7942   uint32_t     ticks,tout;
7943   osThreadId_t worker,spawn;
7944   int32_t      rval,n_bytes;
7945   IO_TRANSFER  io;
7946   IO_SIDEKICK  io2;
7947   int32_t      sock;
7948
7949   if (station_init (1) == 0) {
7950     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7951     return;
7952   }
7953
7954   /* Create worker thread */
7955   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
7956   if (worker == NULL) {
7957     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7958     return;
7959   }
7960
7961   ARG_INIT();
7962
7963   /* The test connects two stream sockets to the ECHO server and then    */
7964   /* performs simultaneous data transfer. The main socket transmits at   */
7965   /* full speed, and the other socket sends messages at 100ms intervals. */
7966   /* Both sockets record the number of bytes of data transferred, and    */
7967   /* the transfer rate is calculated.                                    */
7968
7969   /* Create stream socket */
7970   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7971   if (io.rc < 0) {
7972     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7973   } else {
7974     sock = io.rc;
7975
7976     /* Create 2nd stream socket */
7977     TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7978     if (io.rc < 0) {
7979       TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7980     }
7981     io2.sock  = io.rc;
7982     io2.count = 0;
7983
7984     /* Connect sockets */
7985     io.sock = sock;
7986     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7987     TH_ASSERT  (io.rc == 0);
7988
7989     io.sock = io2.sock;
7990     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7991     TH_ASSERT  (io.rc == 0);
7992
7993     /* Create spawned thread */
7994     spawn = osThreadNew ((osThreadFunc_t)Th_Sidekick, &io2, NULL);
7995     TEST_ASSERT(spawn != NULL);
7996
7997     /* Transfer for 4 seconds */
7998     tout  = SYSTICK_MICROSEC(4000000);
7999     ticks = GET_SYSTICK();
8000     n_bytes = 0;
8001     do {
8002       ARG_TRANSFER (sock, 1440, 1440);
8003       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8004       if (io.rc > 0) n_bytes += io.rc;
8005       else           break;
8006     } while (GET_SYSTICK() - ticks < tout);
8007     /* Check transfer rate */
8008     if (n_bytes < 10000) {
8009       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
8010       TEST_MESSAGE(msg_buf);
8011     }
8012
8013     /* 2nd socket sends at 100ms intervals */
8014     TH_ASSERT (io2.count > 1000);
8015
8016     /* Terminate spawned thread */
8017     osThreadFlagsSet (spawn, SK_TERMINATE);
8018     osDelay(100);
8019     osThreadTerminate (spawn);
8020
8021     /* Close stream sockets */
8022     io.sock = io2.sock;
8023     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8024     TH_ASSERT  (io.rc == 0);
8025
8026     io.sock = sock;
8027     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8028     TH_ASSERT  (io.rc == 0);
8029
8030     osDelay (10);
8031   }
8032
8033   /* The test connects datagram and stream sockets to the ECHO server     */
8034   /* and then performs simultaneous data transfer. The datagram socket    */
8035   /* transmits at full speed, and the stream socket sends messages at     */
8036   /* 100ms intervals. The number of bytes of transferred data is recorded */
8037   /* and the rate of transmission is calculated.                          */
8038
8039   /* Create datagram socket */
8040   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
8041   if (io.rc < 0) {
8042     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
8043   } else {
8044     sock = io.rc;
8045
8046     /* Connect datagram socket */
8047     io.sock = sock;
8048     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
8049     TH_ASSERT  (io.rc == 0);
8050
8051     /* Create stream socket */
8052     TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8053     if (io.rc < 0) {
8054       TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8055     }
8056     io2.sock  = io.rc;
8057     io2.count = 0;
8058
8059     /* Connect stream socket */
8060     io.sock = io2.sock;
8061     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
8062     TH_ASSERT  (io.rc == 0);
8063
8064     /* Create spawned thread */
8065     spawn = osThreadNew ((osThreadFunc_t)Th_Sidekick, &io2, NULL);
8066     TEST_ASSERT(spawn != NULL);
8067
8068     /* Transfer for 4 seconds */
8069     tout  = SYSTICK_MICROSEC(4000000);
8070     ticks = GET_SYSTICK();
8071     n_bytes = 0;
8072     do {
8073       ARG_TRANSFER (sock, 1460, 1460);
8074       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8075       if (io.rc > 0) n_bytes += io.rc;
8076       else           break;
8077     } while (GET_SYSTICK() - ticks < tout);
8078     /* Check transfer rate */
8079     if (n_bytes < 10000) {
8080       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
8081       TEST_MESSAGE(msg_buf);
8082     }
8083
8084     /* 2nd socket sends at 100ms intervals */
8085     TH_ASSERT (io2.count > 1000);
8086
8087     /* Terminate spawned thread */
8088     osThreadFlagsSet (spawn, SK_TERMINATE);
8089     osDelay(100);
8090     osThreadTerminate (spawn);
8091
8092     /* Close sockets */
8093     io.sock = io2.sock;
8094     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8095     TH_ASSERT  (io.rc == 0);
8096
8097     io.sock = sock;
8098     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8099     TH_ASSERT  (io.rc == 0);
8100
8101     osDelay (10);
8102   }
8103
8104   if (rval == 0) {
8105     station_uninit ();
8106   }
8107
8108   /* Terminate worker thread */
8109   osThreadTerminate (worker);
8110 }
8111
8112 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
8113
8114 /* TestAssistant commands */
8115 #define CMD_SEND_TCP        "SEND TCP,1420,4000"
8116 #define CMD_RECV_TCP        "RECV TCP,1420"
8117 #define TEST_BSIZE          1420
8118
8119 /* StreamRate IO parameters */
8120 typedef struct {
8121   int32_t      sock;
8122   int32_t      rc;
8123   /* Control */
8124   osThreadId_t owner;
8125   uint32_t     xid;
8126   int32_t      loss;
8127   const char  *cmd;
8128 } IO_STREAMRATE;
8129
8130 /* StreamRate coworker thread */
8131 __NO_RETURN static void Th_StreamRate (IO_STREAMRATE *io) {
8132   uint32_t flags,xid,ticks,tout;
8133   int32_t  n,rc,i,val;
8134
8135   for (;;) {
8136     flags = osThreadFlagsWait (F_CREATE_TCP | F_DOWNLOAD | F_UPLOAD |
8137                                F_SEND_CTRL  | F_CLOSE, osFlagsWaitAny, osWaitForever);
8138     xid   = io->xid;
8139     switch (flags) {
8140       case F_CREATE_TCP:
8141         /* Create stream socket */
8142         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
8143         break;
8144
8145       case F_DOWNLOAD:
8146         /* Downstream test, server is sender */
8147         for (n = 0; ; n += rc) {
8148           rc = drv->SocketRecv (io->sock, buffer, TEST_BSIZE);
8149           if (strncmp ((char *)buffer, "STAT", 4) == 0) {
8150             /* Server completed the test */
8151             sscanf ((char *)buffer+4, "%d", &val);
8152             if (val > n) io->loss = val - n;
8153             break;
8154           }
8155           if (rc <= 0) break;
8156         }
8157         io->rc = n;
8158         break;
8159
8160       case F_UPLOAD:
8161         /* Upstream test, server is receiver */
8162         memset ((void *)buffer, 'a', TEST_BSIZE);
8163         tout  = SYSTICK_MICROSEC(4000000);
8164         ticks = GET_SYSTICK();
8165         i = n = 0;
8166         do {
8167           snprintf ((char *)buffer, sizeof(buffer), "Block[%d]", ++i);
8168           rc = drv->SocketSend (io->sock, buffer, TEST_BSIZE);
8169           if (rc > 0) n += rc;
8170         } while (GET_SYSTICK() - ticks < tout);
8171         rc = snprintf ((char *)buffer, sizeof(buffer), "STOP %d bytes.", n);
8172         drv->SocketSend (io->sock, buffer, (uint32_t)rc);
8173         /* Receive report from server */
8174         drv->SocketRecv (io->sock, buffer, TEST_BSIZE);
8175         if (strncmp ((char *)buffer, "STAT", 4) == 0) {
8176           sscanf ((char *)buffer+4, "%d", &val);
8177           if (n > val) io->loss = n - val;
8178         }
8179         io->rc = n;
8180         break;
8181
8182       case F_CLOSE:
8183         /* Close socket */
8184         io->rc = drv->SocketClose (io->sock);
8185         break;
8186
8187       case F_SEND_CTRL:
8188         /* Send control command to TestAssistant */
8189         drv->SocketConnect (io->sock, ip_socket_server, 4, ASSISTANT_PORT);
8190         io->rc = drv->SocketSend (io->sock, io->cmd, strlen(io->cmd));
8191         break;
8192     }
8193     /* Done, send signal to owner thread */
8194     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
8195     osDelay(1);
8196     osThreadFlagsSet (io->owner, flags);
8197     osThreadFlagsClear (F_ALL);
8198   }
8199 }
8200
8201 /**
8202 \brief  Test case: WIFI_Downstream_Rate
8203 \ingroup wifi_sock_op
8204 \details
8205 The test case \b WIFI_Downstream_Rate tests the maximum rate at which the data
8206 can be received.
8207 */
8208 void WIFI_Downstream_Rate (void) {
8209   osThreadId_t  worker;
8210   int32_t       rval;
8211   IO_STREAMRATE io;
8212
8213   if (station_init (1) == 0) {
8214     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8215     return;
8216   }
8217
8218   /* Create worker thread */
8219   worker = osThreadNew ((osThreadFunc_t)Th_StreamRate, &io, NULL);
8220   if (worker == NULL) {
8221     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8222     return;
8223   }
8224
8225   ARG_INIT();
8226
8227   /* Create stream socket */
8228   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8229   if (io.rc < 0) {
8230     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8231   } else {
8232     io.sock = io.rc;
8233
8234     /* Send command to start the download */
8235     io.cmd = CMD_SEND_TCP;
8236     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
8237     TH_ASSERT  (io.rc > 0);
8238
8239     /* Wait for transfer to complete */
8240     io.loss = 0;
8241     TH_EXECUTE (F_DOWNLOAD, 5000 + WIFI_SOCKET_TIMEOUT);
8242     TH_ASSERT  (io.rc > 0);
8243
8244     /* Check data loss */
8245     if (io.loss) {
8246       snprintf(msg_buf, sizeof(msg_buf), "[FAILED] Data loss %d byte(s)", io.loss);
8247       TEST_ASSERT_MESSAGE(0,msg_buf);
8248     }
8249     else if (rval != 0) {
8250       snprintf(msg_buf, sizeof(msg_buf), "[INFO] Speed %d KB/s", io.rc/4000);
8251       TEST_MESSAGE(msg_buf);
8252     }
8253
8254     /* Close stream socket */
8255     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8256     TH_ASSERT  (io.rc == 0);
8257
8258     osDelay (10);
8259   }
8260
8261   if (rval == 0) {
8262     station_uninit ();
8263   }
8264
8265   /* Terminate worker thread */
8266   osThreadTerminate (worker);
8267 }
8268
8269 /**
8270 \brief  Test case: WIFI_Upstream_Rate
8271 \ingroup wifi_sock_op
8272 \details
8273 The test case \b WIFI_Upstream_Rate tests the maximum rate at which the data
8274 can be sent.
8275 */
8276 void WIFI_Upstream_Rate (void) {
8277   osThreadId_t  worker;
8278   int32_t       rval;
8279   IO_STREAMRATE io;
8280
8281   if (station_init (1) == 0) {
8282     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8283     return;
8284   }
8285
8286   /* Create worker thread */
8287   worker = osThreadNew ((osThreadFunc_t)Th_StreamRate, &io, NULL);
8288   if (worker == NULL) {
8289     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8290     return;
8291   }
8292
8293   ARG_INIT();
8294
8295   /* Create stream socket */
8296   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8297   if (io.rc < 0) {
8298     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8299   } else {
8300     io.sock = io.rc;
8301
8302     /* Send command to start the upload */
8303     io.cmd = CMD_RECV_TCP;
8304     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
8305     TH_ASSERT  (io.rc > 0);
8306
8307     /* Wait for transfer to complete */
8308     io.loss = 0;
8309     TH_EXECUTE (F_UPLOAD, 5000 + WIFI_SOCKET_TIMEOUT);
8310     TH_ASSERT  (io.rc > 0);
8311
8312     /* Check data loss */
8313     if (io.loss) {
8314       snprintf(msg_buf, sizeof(msg_buf), "[FAILED] Data loss %d byte(s)", io.loss);
8315       TEST_ASSERT_MESSAGE(0,msg_buf);
8316     }
8317     else if (rval != 0) {
8318       snprintf(msg_buf, sizeof(msg_buf), "[INFO] Speed %d KB/s", io.rc/4000);
8319       TEST_MESSAGE(msg_buf);
8320     }
8321
8322     /* Close stream socket */
8323     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8324     TH_ASSERT  (io.rc == 0);
8325
8326     osDelay (10);
8327   }
8328
8329   if (rval == 0) {
8330     station_uninit ();
8331   }
8332
8333   /* Terminate worker thread */
8334   osThreadTerminate (worker);
8335 }