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