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