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