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