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