]> begriffs open source - cmsis-driver-validation/blob - Source/DV_WIFI.c
Update to WiFi Driver testing
[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   /* Create worker thread */
4181   worker = osThreadNew ((osThreadFunc_t)Th_Accept, &io, NULL);
4182   if (worker == NULL) {
4183     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
4184     return;
4185   }
4186
4187   ARG_INIT();
4188
4189   /* Create stream socket */
4190   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4191   if (io.rc < 0) {
4192     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4193   } else {
4194     sock = io.rc;
4195
4196     /* Set socket non-blocking */
4197     io.sock = sock;
4198     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
4199     TH_ASSERT  (io.rc == 0);
4200
4201     /* Bind socket */
4202     io.sock = sock;
4203     io.tval = TEST_PORT_NB;
4204     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4205     TH_ASSERT  (io.rc == 0);
4206
4207     /* Start listening */
4208     io.sock = sock;
4209     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
4210     TH_ASSERT  (io.rc == 0);
4211
4212     /* Check parameter (socket = -1) */
4213     ip_len = sizeof(ip);
4214     ARG_ACCEPT (-1, ip, &ip_len, &port);
4215     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
4216     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4217
4218     /* Check parameter (socket = INT32_MIN) */
4219     ARG_ACCEPT (INT32_MIN, ip, &ip_len, &port);
4220     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
4221     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4222
4223     /* Check parameter (socket = INT32_MAX) */
4224     ARG_ACCEPT (INT32_MAX, ip, &ip_len, &port);
4225     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
4226     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4227
4228     /* Parameters 'ip', 'ip_len' and 'port' are optional, can be NULL */
4229
4230     /* Request a remote server to connect to us */
4231     io.cmd = CMD_CONNECT_TCP_NB;
4232     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
4233     TH_ASSERT  (io.rc > 0);
4234
4235     /* Accept connection, polling mode */
4236     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT_LONG*1000);
4237     ticks = GET_SYSTICK();
4238     do {
4239       /* Accept connection with NULL parameters */
4240       ARG_ACCEPT (sock, NULL, NULL, NULL);
4241       TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
4242       if (io.rc != ARM_SOCKET_EAGAIN) break;
4243     } while (GET_SYSTICK() - ticks < tout);
4244     /* Accepted socket should be different */
4245     TH_ASSERT  ((io.rc != io.sock) && (io.rc >= 0));
4246
4247     /* Receive SockServer id string, polling mode */
4248     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT*1000);
4249     ticks = GET_SYSTICK();
4250     do {
4251       io.sock = io.rc;
4252       TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4253       if (io.rc > 0) break;
4254     } while (GET_SYSTICK() - ticks < tout);
4255     TH_ASSERT (io.rc > 0);
4256
4257     /* Close accepted socket, polling mode */
4258     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT*1000);
4259     ticks = GET_SYSTICK();
4260     do {
4261       TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4262       if (io.rc == 0) break;
4263     } while (GET_SYSTICK() - ticks < tout);
4264     TH_ASSERT  (io.rc == 0);
4265
4266     osDelay (500);
4267
4268     /* Request from remote server to connect to us */
4269     io.cmd = CMD_CONNECT_TCP_NB;
4270     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
4271     TH_ASSERT  (io.rc > 0);
4272
4273     /* Initialize buffers for return values */
4274     port   = 0;
4275     ip_len = sizeof(ip) + 1;
4276     memset (ip, 0, sizeof(ip));
4277
4278     /* Accept again, polling mode */
4279     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT_LONG*1000);
4280     ticks = GET_SYSTICK();
4281     do {
4282       /* Accept again, return ip address and port */
4283       ARG_ACCEPT (sock, &ip[0], &ip_len, &port);
4284       TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
4285       if (io.rc != ARM_SOCKET_EAGAIN) break;
4286     } while (GET_SYSTICK() - ticks < tout);
4287     /* Accepted socket should be different */
4288     TH_ASSERT  ((io.rc != io.sock) && (io.rc >= 0));
4289     /* IP address should be the address of the server */
4290     TH_ASSERT  ((memcmp (ip, ip_socket_server, 4) == 0) && (ip_len == 4));
4291     /* Port number of remote peer should be non-zero */
4292     TH_ASSERT  (port != 0);
4293
4294     /* Receive SockServer id string, polling mode */
4295     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT_LONG*1000);
4296     ticks = GET_SYSTICK();
4297     do {
4298       io.sock = io.rc;
4299       TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4300       if (io.rc > 0) break;
4301     } while (GET_SYSTICK() - ticks < tout);
4302     TH_ASSERT (io.rc > 0);
4303
4304     /* SockServer disconnects after 500ms */
4305     osDelay (1000);
4306
4307     /* Receive again, no data */
4308     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
4309     /* Should return error (connection reset) */
4310     /* Strict: ECONNRESET, valid non-strict: ERROR */
4311     TH_ASSERT2 ((io.rc == ARM_SOCKET_ECONNRESET), (io.rc == ARM_SOCKET_ERROR), "receive on disconnected socket", io.rc, ARM_SOCKET_ECONNRESET);
4312
4313     /* Close accepted socket, polling mode */
4314     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT*1000);
4315     ticks = GET_SYSTICK();
4316     do {
4317       TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4318       if (io.rc == 0) break;
4319     } while (GET_SYSTICK() - ticks < tout);
4320     TH_ASSERT  (io.rc == 0);
4321
4322     /* Close listening socket, polling mode  */
4323     io.sock = sock;
4324     ticks = GET_SYSTICK();
4325     do {
4326       TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4327       if (io.rc == 0) break;
4328     } while (GET_SYSTICK() - ticks < tout);
4329     TH_ASSERT  (io.rc == 0);
4330
4331     /* Accept again, closed socket */
4332     ip_len = 4;
4333     ARG_ACCEPT (sock, &ip[0], &ip_len, &port);
4334     TH_EXECUTE (F_ACCEPT, WIFI_SOCKET_TIMEOUT);
4335     /* Should return error (socket not created) */
4336     /* Strict: ESOCK, valid non-strict: ERROR */
4337     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "accept on closed socket", io.rc, ARM_SOCKET_ESOCK);
4338
4339     osDelay (10);
4340   }
4341
4342   /* Terminate worker thread */
4343   osThreadTerminate (worker);
4344 }
4345
4346 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
4347
4348 /* Connect IO parameters */
4349 #ifndef __DOXYGEN__                     // Exclude form the documentation
4350 typedef struct {
4351   int32_t        sock;
4352   const uint8_t *ip;
4353   uint32_t       ip_len;
4354   uint16_t       port;
4355   uint16_t       reserved;
4356   int32_t        rc;
4357   /* Control */
4358   osThreadId_t   owner;
4359   uint32_t       xid;
4360 } IO_CONNECT;
4361 #endif
4362
4363 /* Assign arguments */
4364 #define ARG_CONNECT(_sock,_ip,_ip_len,_port) do {                   \
4365                                                io.sock   = _sock;   \
4366                                                io.ip     = _ip;     \
4367                                                io.ip_len = _ip_len; \
4368                                                io.port   = _port;   \
4369                                              } while (0)
4370
4371 /* Connect worker thread */
4372 __NO_RETURN static void Th_Connect (IO_CONNECT *io) {
4373   uint32_t flags,xid;
4374
4375   for (;;) {
4376     /* Wait for the signal to select and execute the function */
4377     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_BIND | F_SETOPT |
4378                                F_CONNECT    | F_LISTEN     | F_CLOSE, osFlagsWaitAny, osWaitForever);
4379     xid   = io->xid;
4380     switch (flags) {
4381       case F_CREATE_TCP:
4382         /* Create stream socket */
4383         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
4384         break;
4385
4386       case F_CREATE_UDP:
4387         /* Create datagram socket */
4388         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
4389         break;
4390
4391       case F_BIND:
4392         /* Bind socket */
4393         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
4394         break;
4395
4396       case F_CONNECT:
4397         /* Connect on socket */
4398         io->rc = drv->SocketConnect (io->sock, io->ip, io->ip_len, io->port);
4399         break;
4400
4401       case F_LISTEN:
4402         /* Listen on socket */
4403         io->rc = drv->SocketListen (io->sock, 1);
4404         break;
4405
4406       case F_CLOSE:
4407         /* Close socket */
4408         io->rc = drv->SocketClose (io->sock);
4409         break;
4410
4411       case F_SETOPT: {
4412         /* Set socket non-blocking mode */
4413         const uint32_t nbio = 1;
4414         io->rc = drv->SocketSetOpt (io->sock, ARM_SOCKET_IO_FIONBIO, &nbio, sizeof(nbio));
4415       } break;
4416     }
4417     /* Done, send signal to owner thread */
4418     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
4419     osDelay(1);
4420     osThreadFlagsSet (io->owner, flags);
4421     osThreadFlagsClear (F_ALL);
4422   }
4423 }
4424
4425 /**
4426 \brief  Function: WIFI_SocketConnect
4427 \ingroup wifi_sock_api
4428 \details
4429 The test function \b WIFI_SocketConnect verifies the WiFi Driver \b SocketConnect function:
4430 \code
4431 int32_t (*SocketConnect) (int32_t socket, const uint8_t *ip, uint32_t  ip_len, uint16_t  port);
4432 \endcode
4433
4434 Stream socket test 1:
4435  - Create stream socket
4436  - Check function parameters
4437  - Connect to server, blocking mode
4438  - Connect again, already connected
4439  - Bind connected socket
4440  - Close socket
4441  - Connect on closed socket
4442
4443 Stream socket test 2:
4444  - Create stream socket
4445  - Connect to server, connection rejected
4446  - Close socket
4447
4448 Stream socket test 3:
4449  - Create stream socket
4450  - Connect to server, non-responding or non-existent
4451  - Close socket
4452
4453 Stream socket test 4:
4454  - Create stream socket
4455  - Bind socket
4456  - Start listening
4457  - Connect to server, blocking mode
4458  - Close socket
4459
4460 Datagram socket test:
4461  - Create datagram socket
4462  - Bind socket
4463  - Check function parameters
4464  - Connect to server, enable address filtering
4465  - Connect to unspecified address, disable filtering
4466  - Close socket
4467  - Connect again, closed socket
4468 */
4469 void WIFI_SocketConnect (void) {
4470   osThreadId_t worker;
4471   int32_t      rval;
4472   IO_CONNECT   io;
4473   int32_t      sock;
4474
4475   if (socket_funcs_exist == 0U) {
4476     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
4477     return;
4478   }
4479
4480   if (station_init (1) == 0) {
4481     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
4482     return;
4483   }
4484
4485   /* Create worker thread */
4486   worker = osThreadNew ((osThreadFunc_t)Th_Connect, &io, NULL);
4487   if (worker == NULL) {
4488     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
4489     return;
4490   }
4491
4492   ARG_INIT();
4493
4494   /* Create stream socket */
4495   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4496   if (io.rc < 0) {
4497     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4498   } else {
4499     sock = io.rc;
4500
4501     /* Check parameter (socket = -1) */
4502     ARG_CONNECT(-1, ip_socket_server, 4, DISCARD_PORT);
4503     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4504     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4505
4506     /* Check parameter (socket = INT32_MIN) */
4507     ARG_CONNECT(INT32_MIN, ip_socket_server, 4, DISCARD_PORT);
4508     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4509     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4510
4511     /* Check parameter (socket = INT32_MAX) */
4512     ARG_CONNECT(INT32_MAX, 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 (ip = NULL) */
4517     ARG_CONNECT(sock, NULL, 4, DISCARD_PORT);
4518     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4519     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4520
4521     /* Check parameter (ip = 0.0.0.0) */
4522     ARG_CONNECT(sock, ip_unspec, 4, DISCARD_PORT);
4523     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4524     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4525
4526     /* Check parameter (ip_len = 0) */
4527     ARG_CONNECT(sock, ip_socket_server, 0, DISCARD_PORT);
4528     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4529     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4530
4531     /* Check parameter (ip_len = 5) */
4532     ARG_CONNECT(sock, ip_socket_server, 5, DISCARD_PORT);
4533     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4534     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4535
4536     /* Check parameter (port = 0) */
4537     ARG_CONNECT(sock, ip_socket_server, 4, 0);
4538     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4539     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4540
4541     /* Connect to stream server */
4542     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4543     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4544     TH_ASSERT  (io.rc == 0);
4545
4546     /* Connect 2nd time */
4547     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4548     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4549     /* Should return error (socket already connected) */
4550     /* Strict: EISCONN, valid non-strict: OK, ERROR */
4551     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);
4552
4553     /* Bind connected socket */
4554     io.sock = sock;
4555     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4556     /* Should return error (socket already connected) */
4557     /* Strict: EISCONN, valid non-strict: ERROR */
4558     TH_ASSERT2 ((io.rc == ARM_SOCKET_EISCONN), (io.rc == ARM_SOCKET_ERROR), "bind on connected socket", io.rc, ARM_SOCKET_EISCONN);
4559
4560     /* Close socket */
4561     io.sock = sock;
4562     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4563     TH_ASSERT  (io.rc == 0);
4564
4565     /* Connect again, closed socket */
4566     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4567     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4568     /* Should return error (socket not created) */
4569     /* Strict: ESOCK, valid non-strict: ERROR */
4570     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "connect on closed socket", io.rc, ARM_SOCKET_ESOCK);
4571
4572     osDelay (10);
4573   }
4574
4575   /* Create stream socket */
4576   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4577   if (io.rc < 0) {
4578     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4579   } else {
4580     sock = io.rc;
4581
4582     /* Connect to stream server (connection rejected) */
4583     ARG_CONNECT(sock, ip_socket_server, 4, TCP_REJECTED_PORT);
4584     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4585     /* Should return error (connection rejected by the peer) */
4586     /* Strict: ECONNREFUSED, valid non-strict: ETIMEDOUT, ERROR */
4587     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);
4588
4589     /* Close socket */
4590     io.sock = sock;
4591     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4592     TH_ASSERT  (io.rc == 0);
4593
4594     osDelay (10);
4595   }
4596
4597   /* Create stream socket */
4598   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4599   if (io.rc < 0) {
4600     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4601   } else {
4602     sock = io.rc;
4603
4604     /* Connect to stream server (non-existent) */
4605     ARG_CONNECT(sock, ip_socket_server, 4, TCP_TIMEOUT_PORT);
4606     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4607     /* Should return error (connection timeout) */
4608     /* Strict: ETIMEDOUT, valid non-strict: ERROR */
4609     TH_ASSERT2 ((io.rc == ARM_SOCKET_ETIMEDOUT), (io.rc == ARM_SOCKET_ERROR), "connect to non-existent stream server", io.rc, ARM_SOCKET_ETIMEDOUT);
4610
4611     /* Close socket */
4612     io.sock = sock;
4613     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4614     TH_ASSERT  (io.rc == 0);
4615
4616     osDelay (10);
4617   }
4618
4619   /* Create stream socket */
4620   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4621   if (io.rc < 0) {
4622     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4623   } else {
4624     sock = io.rc;
4625
4626     /* Bind socket */
4627     io.sock = sock;
4628     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4629     TH_ASSERT  (io.rc == 0);
4630
4631     /* Start listening */
4632     io.sock = sock;
4633     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
4634     TH_ASSERT  (io.rc == 0);
4635
4636     /* Connect to stream server */
4637     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4638     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
4639     /* Connect on listening socket should fail */
4640     /* Strict: EINVAL, valid non-strict: ERROR */
4641     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "connect on listening socket", io.rc, ARM_SOCKET_EINVAL);
4642
4643     /* Close socket */
4644     io.sock = sock;
4645     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4646     TH_ASSERT  (io.rc == 0);
4647
4648     osDelay (10);
4649   }
4650
4651   /* Create datagram socket */
4652   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
4653   if (io.rc < 0) {
4654     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
4655   } else {
4656     sock = io.rc;
4657
4658     /* Check parameter (socket = -1) */
4659     ARG_CONNECT(-1, ip_socket_server, 4, DISCARD_PORT);
4660     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4661     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4662
4663     /* Check parameter (socket = INT32_MIN) */
4664     ARG_CONNECT(INT32_MIN, ip_socket_server, 4, DISCARD_PORT);
4665     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4666     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4667
4668     /* Check parameter (socket = INT32_MAX) */
4669     ARG_CONNECT(INT32_MAX, 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 (ip = NULL) */
4674     ARG_CONNECT(sock, NULL, 4, DISCARD_PORT);
4675     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4676     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4677
4678     /* Check parameter (ip = 0.0.0.0) */
4679     ARG_CONNECT(sock, ip_unspec, 4, DISCARD_PORT);
4680     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4681     /* Datagram sockets may dissolve the association */
4682     /* by connecting to unspecified address.         */
4683     /* Strict: OK, valid non-strict: EINVAL, ERROR */
4684     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);
4685
4686     /* Check parameter (ip_len = 0) */
4687     ARG_CONNECT(sock, ip_socket_server, 0, DISCARD_PORT);
4688     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4689     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4690
4691     /* Check parameter (ip_len = 5) */
4692     ARG_CONNECT(sock, ip_socket_server, 5, DISCARD_PORT);
4693     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4694     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4695
4696     /* Check parameter (port = 0) */
4697     ARG_CONNECT(sock, ip_socket_server, 4, 0);
4698     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4699     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4700
4701     /* Connect to datagram server */
4702     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4703     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4704     TH_ASSERT  (io.rc == 0);
4705
4706     /* Connect to unspecified address (0.0.0.0) */
4707     ARG_CONNECT(sock, ip_unspec, 4, DISCARD_PORT);
4708     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4709     /* Datagram sockets may dissolve the association */
4710     /* by connecting to unspecified address.         */
4711     /* Should return ok (socket address deleted) */
4712     /* Strict: OK, valid non-strict: EINVAL, ERROR */
4713     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);
4714
4715     /* Close socket */
4716     io.sock = sock;
4717     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4718     TH_ASSERT  (io.rc == 0);
4719
4720     /* Connect again, closed socket */
4721     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4722     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4723     /* Should return error (socket not created) */
4724     /* Strict: ESOCK, valid non-strict: ERROR */
4725     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "connect on closed socket", io.rc, ARM_SOCKET_ESOCK);
4726
4727     osDelay (10);
4728   }
4729
4730   if (rval == 0) {
4731     station_uninit ();
4732   }
4733
4734   /* Terminate worker thread */
4735   osThreadTerminate (worker);
4736 }
4737
4738 /**
4739 \brief  Test case: WIFI_SocketConnect_nbio
4740 \ingroup wifi_sock_api
4741 \details
4742 The test case \b WIFI_SocketConnect_nbio verifies the WiFi Driver \b SocketConnect function
4743 running in non-blocking mode.
4744
4745 Stream socket test 1:
4746  - Create stream socket
4747  - Set non-blocking mode
4748  - Check function parameters
4749  - Connect to server, non-blocking mode
4750  - Connect again, already connected
4751  - Bind connected socket
4752  - Close socket
4753  - Connect on closed socket
4754
4755 Stream socket test 2:
4756  - Create stream socket
4757  - Set non-blocking mode
4758  - Connect to server, connection rejected
4759  - Close socket
4760
4761 Stream socket test 3:
4762  - Create stream socket
4763  - Set non-blocking mode
4764  - Connect to server, non-responding or non-existent
4765  - Close socket
4766
4767 Stream socket test 4:
4768  - Create stream socket
4769  - Set non-blocking mode
4770  - Bind socket
4771  - Start listening
4772  - Connect to server, non-blocking mode
4773  - Close socket
4774 */
4775 void WIFI_SocketConnect_nbio (void) {
4776   uint32_t     ticks,tout;
4777   osThreadId_t worker;
4778   int32_t      rval;
4779   IO_CONNECT   io;
4780   int32_t      sock;
4781
4782   /* Create worker thread */
4783   worker = osThreadNew ((osThreadFunc_t)Th_Connect, &io, NULL);
4784   if (worker == NULL) {
4785     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
4786     return;
4787   }
4788
4789   ARG_INIT();
4790
4791   /* Create stream socket */
4792   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4793   if (io.rc < 0) {
4794     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4795   } else {
4796     sock = io.rc;
4797
4798     /* Set socket non-blocking */
4799     io.sock = sock;
4800     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
4801     TH_ASSERT  (io.rc == 0);
4802
4803     /* Check parameter (socket = -1) */
4804     ARG_CONNECT(-1, ip_socket_server, 4, DISCARD_PORT);
4805     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4806     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4807
4808     /* Check parameter (socket = INT32_MIN) */
4809     ARG_CONNECT(INT32_MIN, ip_socket_server, 4, DISCARD_PORT);
4810     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4811     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4812
4813     /* Check parameter (socket = INT32_MAX) */
4814     ARG_CONNECT(INT32_MAX, ip_socket_server, 4, DISCARD_PORT);
4815     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4816     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
4817
4818     /* Check parameter (ip = NULL) */
4819     ARG_CONNECT(sock, NULL, 4, DISCARD_PORT);
4820     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4821     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4822
4823     /* Check parameter (ip = 0.0.0.0) */
4824     ARG_CONNECT(sock, ip_unspec, 4, DISCARD_PORT);
4825     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4826     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4827
4828     /* Check parameter (ip_len = 0) */
4829     ARG_CONNECT(sock, ip_socket_server, 0, DISCARD_PORT);
4830     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4831     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4832
4833     /* Check parameter (ip_len = 5) */
4834     ARG_CONNECT(sock, ip_socket_server, 5, DISCARD_PORT);
4835     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4836     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4837
4838     /* Check parameter (port = 0) */
4839     ARG_CONNECT(sock, ip_socket_server, 4, 0);
4840     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4841     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
4842
4843     /* Connect to stream server, start non-blocking */
4844     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4845     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4846     TH_ASSERT  (io.rc == ARM_SOCKET_EINPROGRESS);
4847
4848     /* Connect, polling mode */
4849     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT_LONG*1000);
4850     ticks = GET_SYSTICK();
4851     do {
4852       ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4853       TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4854       if (io.rc != ARM_SOCKET_EALREADY) break;
4855     } while (GET_SYSTICK() - ticks < tout);
4856     TH_ASSERT  (io.rc == ARM_SOCKET_EISCONN);
4857
4858     /* Connect 2nd time */
4859     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4860     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4861     /* Should return error (socket already connected) */
4862     /* Strict: EISCONN, valid non-strict: OK, ERROR */
4863     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);
4864
4865     /* Bind connected socket */
4866     io.sock = sock;
4867     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4868     /* Should return error (socket already connected) */
4869     /* Strict: EISCONN, valid non-strict: ERROR */
4870     TH_ASSERT2 ((io.rc == ARM_SOCKET_EISCONN), (io.rc == ARM_SOCKET_ERROR), "bind on connected socket", io.rc, ARM_SOCKET_EISCONN);
4871
4872     /* Close socket, polling mode */
4873     io.sock = sock;
4874     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT*1000);
4875     ticks = GET_SYSTICK();
4876     do {
4877       TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4878       if (io.rc == 0) break;
4879     } while (GET_SYSTICK() - ticks < tout);
4880     TH_ASSERT  (io.rc == 0);
4881
4882     /* Connect again, closed socket */
4883     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
4884     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4885     /* Should return error (socket not created) */
4886     /* Strict: ESOCK, valid non-strict: ERROR */
4887     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "connect on closed socket", io.rc, ARM_SOCKET_ESOCK);
4888
4889     osDelay (10);
4890   }
4891
4892   /* Create stream socket */
4893   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4894   if (io.rc < 0) {
4895     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4896   } else {
4897     sock = io.rc;
4898
4899     /* Set socket non-blocking */
4900     io.sock = sock;
4901     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
4902     TH_ASSERT  (io.rc == 0);
4903
4904     /* Connect to stream server (connection rejected) */
4905     ARG_CONNECT(sock, ip_socket_server, 4, TCP_REJECTED_PORT);
4906     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4907     TH_ASSERT  (io.rc == ARM_SOCKET_EINPROGRESS);
4908
4909     /* Connect, polling mode */
4910     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT_LONG*1000);
4911     ticks = GET_SYSTICK();
4912     do {
4913       ARG_CONNECT(sock, ip_socket_server, 4, TCP_REJECTED_PORT);
4914       TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4915       if (io.rc != ARM_SOCKET_EALREADY) break;
4916     } while (GET_SYSTICK() - ticks < tout);
4917     /* Should return error (connection rejected by the peer) */
4918     /* Strict: ECONNREFUSED, valid non-strict: ERROR */
4919     TH_ASSERT2 ((io.rc == ARM_SOCKET_ECONNREFUSED), (io.rc == ARM_SOCKET_ERROR), "connect to non-existent port", io.rc, ARM_SOCKET_ECONNREFUSED);
4920
4921     /* Close socket, polling mode */
4922     io.sock = sock;
4923     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT*1000);
4924     ticks = GET_SYSTICK();
4925     do {
4926       TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4927       if (io.rc == 0) break;
4928     } while (GET_SYSTICK() - ticks < tout);
4929     TH_ASSERT  (io.rc == 0);
4930
4931     osDelay (10);
4932   }
4933
4934   /* Create stream socket */
4935   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4936   if (io.rc < 0) {
4937     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4938   } else {
4939     sock = io.rc;
4940
4941     /* Set socket non-blocking */
4942     io.sock = sock;
4943     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
4944     TH_ASSERT  (io.rc == 0);
4945
4946     /* Connect to stream server (non-existent), start non-blocking */
4947     ARG_CONNECT(sock, ip_socket_server, 4, TCP_TIMEOUT_PORT);
4948     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4949     TH_ASSERT  (io.rc == ARM_SOCKET_EINPROGRESS);
4950
4951     /* Connect, polling mode */
4952     tout  = SYSTICK_MICROSEC((18000 + WIFI_SOCKET_TIMEOUT)*1000);
4953     ticks = GET_SYSTICK();
4954     do {
4955       ARG_CONNECT(sock, ip_socket_server, 4, TCP_TIMEOUT_PORT);
4956       TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
4957       if (io.rc != ARM_SOCKET_EALREADY) break;
4958     } while (GET_SYSTICK() - ticks < tout);
4959     /* Should return error (connection timeout) */
4960     /* Strict: ETIMEDOUT, valid non-strict: ERROR */
4961     TH_ASSERT2 ((io.rc == ARM_SOCKET_ETIMEDOUT), (io.rc == ARM_SOCKET_ERROR), "connect to non-existent stream server", io.rc, ARM_SOCKET_ETIMEDOUT);
4962
4963     /* Close socket, polling mode */
4964     io.sock = sock;
4965     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT*1000);
4966     ticks = GET_SYSTICK();
4967     do {
4968       TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
4969       if (io.rc == 0) break;
4970     } while (GET_SYSTICK() - ticks < tout);
4971     TH_ASSERT  (io.rc == 0);
4972
4973     osDelay (10);
4974   }
4975
4976   /* Create stream socket */
4977   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
4978   if (io.rc < 0) {
4979     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
4980   } else {
4981     sock = io.rc;
4982
4983     /* Set socket non-blocking */
4984     io.sock = sock;
4985     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
4986     TH_ASSERT  (io.rc == 0);
4987
4988     /* Bind socket */
4989     io.sock = sock;
4990     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
4991     TH_ASSERT  (io.rc == 0);
4992
4993     /* Start listening */
4994     io.sock = sock;
4995     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
4996     TH_ASSERT  (io.rc == 0);
4997
4998     /* Connect to stream server */
4999     ARG_CONNECT(sock, ip_socket_server, 4, DISCARD_PORT);
5000     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
5001     /* Connect on listening socket should fail */
5002     /* Strict: EINVAL, valid non-strict: ERROR */
5003     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "connect on listening socket", io.rc, ARM_SOCKET_EINVAL);
5004
5005     /* Close socket, polling mode */
5006     io.sock = sock;
5007     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT*1000);
5008     ticks = GET_SYSTICK();
5009     do {
5010       TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5011       if (io.rc == 0) break;
5012     } while (GET_SYSTICK() - ticks < tout);
5013     TH_ASSERT  (io.rc == 0);
5014
5015     osDelay (10);
5016   }
5017
5018   /* Terminate worker thread */
5019   osThreadTerminate (worker);
5020 }
5021
5022 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
5023
5024 /* Recv IO parameters */
5025 #ifndef __DOXYGEN__                     // Exclude form the documentation
5026 typedef struct {
5027   int32_t      sock;
5028   uint8_t     *buf;
5029   uint32_t     len;
5030   int32_t      rc;
5031   /* Control */
5032   osThreadId_t owner;
5033   uint32_t     xid;
5034   uint32_t     tval;
5035 } IO_RECV;
5036 #endif
5037
5038 /* Assign arguments */
5039 #define ARG_RECV(_sock,_buf,_len) do {               \
5040                                     io.sock = _sock; \
5041                                     io.buf  = _buf;  \
5042                                     io.len  = _len;  \
5043                                   } while (0)
5044
5045 /* Recv worker thread */
5046 __NO_RETURN static void Th_Recv (IO_RECV *io) {
5047   uint32_t flags,xid;
5048
5049   for (;;) {
5050     /* Wait for the signal to select and execute the function */
5051     flags = osThreadFlagsWait (F_CREATE_TCP | F_BIND | F_CONNECT | F_LISTEN |
5052                                F_SETOPT     | F_RECV | F_CLOSE, osFlagsWaitAny, osWaitForever);
5053     xid   = io->xid;
5054     switch (flags) {
5055       case F_CREATE_TCP:
5056         /* Create stream socket */
5057         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
5058         break;
5059
5060       case F_BIND:
5061         /* Bind socket */
5062         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
5063         break;
5064
5065       case F_CONNECT:
5066         /* Connect on socket */
5067         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, (uint16_t)io->tval);
5068         break;
5069
5070       case F_LISTEN:
5071         /* Listen on socket */
5072         io->rc = drv->SocketListen (io->sock, 1);
5073         break;
5074
5075       case F_SETOPT: {
5076         /* Set socket options */
5077         int32_t opt_id = (io->tval > 1) ? ARM_SOCKET_SO_RCVTIMEO : ARM_SOCKET_IO_FIONBIO;
5078         io->rc = drv->SocketSetOpt (io->sock, opt_id, &io->tval, sizeof(io->tval));
5079       } break;
5080
5081       case F_RECV:
5082         /* Recv on socket */
5083         if (io->buf != NULL) {
5084           memset((void *)io->buf, 0xCC, io->len);
5085         }
5086         io->rc = drv->SocketRecv (io->sock, io->buf, io->len);
5087         break;
5088
5089       case F_CLOSE:
5090         /* Close socket */
5091         io->rc = drv->SocketClose (io->sock);
5092         break;
5093     }
5094     /* Done, send signal to owner thread */
5095     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
5096     osDelay(1);
5097     osThreadFlagsSet (io->owner, flags);
5098     osThreadFlagsClear (F_ALL);
5099   }
5100 }
5101
5102 /**
5103 \brief  Function: WIFI_SocketRecv
5104 \ingroup wifi_sock_api
5105 \details
5106 Test case \b WIFI_SocketRecv verifies the WiFi Driver \b SocketRecv function:
5107 \code
5108 int32_t (*SocketRecv) (int32_t socket, void *buf, uint32_t len);
5109 \endcode
5110
5111 Stream socket test 1:
5112  - Create stream socket
5113  - Connect to Chargen server
5114  - Check function parameters
5115  - Receive data in blocking mode
5116  - Close socket
5117  - Receive again, closed socket
5118
5119 Stream socket test 2:
5120  - Create stream socket
5121  - Receive data, created socket
5122  - Bind socket
5123  - Receive data, bound socket
5124  - Start listening
5125  - Receive data, listening socket
5126  - Close socket
5127
5128 Stream socket test 3:
5129  - Create stream socket
5130  - Connect to Discard server
5131  - Set receive timeout to 1 sec
5132  - Receive data, timeout expires
5133  - Close socket
5134 */
5135 void WIFI_SocketRecv (void) {
5136   uint8_t      buf[4];
5137   uint32_t     ticks,tout;
5138   osThreadId_t worker;
5139   int32_t      rval;
5140   IO_RECV      io;
5141   int32_t      sock;
5142
5143   if (socket_funcs_exist == 0U) {
5144     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
5145     return;
5146   }
5147
5148   if (station_init (1) == 0) {
5149     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
5150     return;
5151   }
5152
5153   /* Create worker thread */
5154   worker = osThreadNew ((osThreadFunc_t)Th_Recv, &io, NULL);
5155   if (worker == NULL) {
5156     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5157     return;
5158   }
5159
5160   ARG_INIT();
5161
5162   /* Create stream socket */
5163   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5164   if (io.rc < 0) {
5165     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5166   } else {
5167     sock = io.rc;
5168
5169     /* Connect to stream server */
5170     io.sock = sock;
5171     io.tval = CHARGEN_PORT;
5172     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
5173     TH_ASSERT  (io.rc == 0);
5174
5175     /* Check parameter (socket = -1) */
5176     ARG_RECV   (-1, buf, sizeof(buf));
5177     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5178     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5179
5180     /* Check parameter (socket = INT32_MIN) */
5181     ARG_RECV   (INT32_MIN, buf, sizeof(buf));
5182     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5183     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5184
5185     /* Check parameter (socket = INT32_MAX) */
5186     ARG_RECV   (INT32_MAX, buf, sizeof(buf));
5187     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5188     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5189
5190     /* Check parameter (buf = NULL) */
5191     ARG_RECV   (sock, NULL, sizeof(buf));
5192     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5193     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
5194
5195     /* Receive no data (check that received data is available) */
5196     ARG_RECV   (sock, buf, 0);
5197     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5198     TH_ASSERT  (io.rc == 0);
5199
5200     /* Receive some data */
5201     ARG_RECV   (sock, buffer, sizeof(buffer));
5202     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
5203     TH_ASSERT  (io.rc >= 2);
5204
5205     /* Close socket */
5206     io.sock = sock;
5207     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5208     TH_ASSERT  (io.rc == 0);
5209
5210     /* Receive again, closed socket */
5211     ARG_RECV (sock, buffer, sizeof(buffer));
5212     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5213     /* Should return error (socket not created) */
5214     /* Strict: ESOCK, valid non-strict: ERROR */
5215     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "recv on closed socket", io.rc, ARM_SOCKET_ESOCK);
5216
5217     osDelay (10);
5218   }
5219
5220   /* Create stream socket */
5221   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5222   if (io.rc < 0) {
5223     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5224   } else {
5225     /* Test server mode */
5226     sock = io.rc;
5227
5228     /* Receive, created socket */
5229     ARG_RECV   (sock, buffer, sizeof(buffer));
5230     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5231     /* Should return error (socket not connected) */
5232     /* Strict: ENOTCONN, valid non-strict: ERROR */
5233     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on created socket", io.rc, ARM_SOCKET_ENOTCONN);
5234
5235     /* Bind socket */
5236     io.sock = sock;
5237     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
5238     TH_ASSERT  (io.rc == 0);
5239
5240     /* Receive, bound socket */
5241     ARG_RECV   (sock, buffer, sizeof(buffer));
5242     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5243     /* Should return error (socket not connected) */
5244     /* Strict: ENOTCONN, valid non-strict: ERROR */
5245     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on bound socket", io.rc, ARM_SOCKET_ENOTCONN);
5246
5247     /* Start listening */
5248     io.sock = sock;
5249     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
5250     TH_ASSERT  (io.rc == 0);
5251
5252     /* Receive, listening socket */
5253     ARG_RECV   (sock, buffer, sizeof(buffer));
5254     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5255     /* Should return error (socket not connected) */
5256     /* Strict: ENOTCONN, valid non-strict: ERROR */
5257     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on listening socket", io.rc, ARM_SOCKET_ENOTCONN);
5258
5259     /* Close socket */
5260     io.sock = sock;
5261     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5262     TH_ASSERT  (io.rc == 0);
5263
5264     osDelay (10);
5265   }
5266
5267   /* Create stream socket */
5268   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5269   if (io.rc < 0) {
5270     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5271   } else {
5272     sock = io.rc;
5273
5274     /* Connect to stream server */
5275     io.sock = sock;
5276     io.tval = DISCARD_PORT;
5277     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
5278     TH_ASSERT  (io.rc == 0);
5279
5280     /* Set receive timeout to 1 sec */
5281     io.sock = sock;
5282     io.tval = 1000;
5283     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
5284     TH_ASSERT  (io.rc == 0);
5285
5286     /* Receive until timeout, no data */
5287     ARG_RECV   (sock, buffer, sizeof(buffer));
5288     ticks = GET_SYSTICK();
5289     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5290     tout = GET_SYSTICK() - ticks;
5291     /* Should return EAGAIN (operation timed out) */
5292     TH_ASSERT  (io.rc == ARM_SOCKET_EAGAIN);
5293     /* Check receive timeout is in the range of 0.9 to 1.1 sec */
5294     TH_ASSERT  (tout > SYSTICK_MICROSEC(900000) && tout < SYSTICK_MICROSEC(1100000));
5295
5296     /* Close socket */
5297     io.sock = sock;
5298     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5299     TH_ASSERT  (io.rc == 0);
5300
5301     osDelay (10);
5302   }
5303
5304   if (rval == 0) {
5305     station_uninit ();
5306   }
5307
5308   /* Terminate worker thread */
5309   osThreadTerminate (worker);
5310 }
5311
5312 /**
5313 \brief  Test case: WIFI_SocketRecv_nbio
5314 \ingroup wifi_sock_api
5315 \details
5316 Test case \b WIFI_SocketRecv_nbio verifies the WiFi Driver \b SocketRecv function
5317 running in non-blocking mode.
5318
5319 Stream socket test 1:
5320  - Create stream socket
5321  - Set non-blocking mode
5322  - Connect to Chargen server
5323  - Check function parameters
5324  - Receive data in non-blocking mode
5325  - Close socket
5326  - Receive again, closed socket
5327
5328 Stream socket test 2:
5329  - Create stream socket
5330  - Set non-blocking mode
5331  - Receive data, created socket
5332  - Bind socket
5333  - Receive data, bound socket
5334  - Start listening
5335  - Receive data, listening socket
5336  - Close socket
5337
5338 Stream socket test 3:
5339  - Create stream socket
5340  - Set non-blocking mode
5341  - Connect to Discard server
5342  - Receive data for 1 sec, timeout expires
5343  - Close socket
5344 */
5345 void WIFI_SocketRecv_nbio (void) {
5346   uint8_t      buf[4];
5347   uint32_t     ticks,tout,npoll;
5348   osThreadId_t worker;
5349   int32_t      rval;
5350   IO_RECV      io;
5351   int32_t      sock;
5352
5353   /* Create worker thread */
5354   worker = osThreadNew ((osThreadFunc_t)Th_Recv, &io, NULL);
5355   if (worker == NULL) {
5356     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5357     return;
5358   }
5359
5360   ARG_INIT();
5361
5362   /* Create stream socket */
5363   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5364   if (io.rc < 0) {
5365     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5366   } else {
5367     sock = io.rc;
5368
5369     /* Connect to stream server, blocking */
5370     io.sock = sock;
5371     io.tval = CHARGEN_PORT;
5372     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
5373     TH_ASSERT  (io.rc == 0);
5374
5375     /* Set socket non-blocking */
5376     io.tval = 1;
5377     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
5378     TH_ASSERT  (io.rc == 0);
5379
5380     /* Check parameter (socket = -1) */
5381     ARG_RECV   (-1, buf, sizeof(buf));
5382     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5383     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5384
5385     /* Check parameter (socket = INT32_MIN) */
5386     ARG_RECV   (INT32_MIN, buf, sizeof(buf));
5387     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5388     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5389
5390     /* Check parameter (socket = INT32_MAX) */
5391     ARG_RECV   (INT32_MAX, buf, sizeof(buf));
5392     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5393     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5394
5395     /* Check parameter (buf = NULL) */
5396     ARG_RECV   (sock, NULL, sizeof(buf));
5397     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5398     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
5399
5400     /* Check if socket readable (len = 0) */
5401     ARG_RECV   (sock, buf, 0);
5402     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5403     TH_ASSERT  (io.rc == 0);
5404
5405     /* Receive some data, polling mode */
5406     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT_LONG*1000);
5407     ticks = GET_SYSTICK();
5408     do {
5409       ARG_RECV   (sock, buffer, sizeof(buffer));
5410       TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5411       if (io.rc != ARM_SOCKET_EAGAIN) break;
5412     } while (GET_SYSTICK() - ticks < tout);
5413     TH_ASSERT  (io.rc >= 2);
5414
5415     /* Close socket, polling mode */
5416     io.sock = sock;
5417     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT*1000);
5418     ticks = GET_SYSTICK();
5419     do {
5420       TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5421       if (io.rc == 0) break;
5422     } while (GET_SYSTICK() - ticks < tout);
5423     TH_ASSERT  (io.rc == 0);
5424
5425     /* Receive again, closed socket */
5426     ARG_RECV (sock, buffer, sizeof(buffer));
5427     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5428     /* Should return error (socket not created) */
5429     /* Strict: ESOCK, valid non-strict: ERROR */
5430     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "recv on closed socket", io.rc, ARM_SOCKET_ESOCK);
5431
5432     osDelay (10);
5433   }
5434
5435   /* Create stream socket */
5436   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5437   if (io.rc < 0) {
5438     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5439   } else {
5440     /* Test server mode */
5441     sock = io.rc;
5442
5443     /* Set socket non-blocking */
5444     io.sock = sock;
5445     io.tval = 1;
5446     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
5447     TH_ASSERT  (io.rc == 0);
5448
5449     /* Receive, created socket */
5450     ARG_RECV   (sock, buffer, sizeof(buffer));
5451     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5452     /* Should return error (socket not connected) */
5453     /* Strict: ENOTCONN, valid non-strict: ERROR */
5454     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on created socket", io.rc, ARM_SOCKET_ENOTCONN);
5455
5456     /* Bind socket */
5457     io.sock = sock;
5458     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
5459     TH_ASSERT  (io.rc == 0);
5460
5461     /* Receive, bound socket */
5462     ARG_RECV   (sock, buffer, sizeof(buffer));
5463     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5464     /* Should return error (socket not connected) */
5465     /* Strict: ENOTCONN, valid non-strict: ERROR */
5466     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on bound socket", io.rc, ARM_SOCKET_ENOTCONN);
5467
5468     /* Start listening */
5469     io.sock = sock;
5470     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
5471     TH_ASSERT  (io.rc == 0);
5472
5473     /* Receive, listening socket */
5474     ARG_RECV   (sock, buffer, sizeof(buffer));
5475     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5476     /* Should return error (socket not connected) */
5477     /* Strict: ENOTCONN, valid non-strict: ERROR */
5478     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "recv on listening socket", io.rc, ARM_SOCKET_ENOTCONN);
5479
5480     /* Close socket, polling mode */
5481     io.sock = sock;
5482     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT*1000);
5483     ticks = GET_SYSTICK();
5484     do {
5485       TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5486       if (io.rc == 0) break;
5487     } while (GET_SYSTICK() - ticks < tout);
5488     TH_ASSERT  (io.rc == 0);
5489
5490     osDelay (10);
5491   }
5492
5493   /* Create stream socket */
5494   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
5495   if (io.rc < 0) {
5496     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
5497   } else {
5498     sock = io.rc;
5499
5500     /* Connect to stream server */
5501     io.sock = sock;
5502     io.tval = DISCARD_PORT;
5503     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
5504     TH_ASSERT  (io.rc == 0);
5505
5506     /* Set socket non-blocking */
5507     io.sock = sock;
5508     io.tval = 1;
5509     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
5510     TH_ASSERT  (io.rc == 0);
5511
5512     /* Receive for 1 sec, timeout no data */
5513     npoll = 0;
5514     tout  = SYSTICK_MICROSEC(1000000);
5515     ticks = GET_SYSTICK();
5516     do {
5517       ARG_RECV   (sock, buffer, sizeof(buffer));
5518       TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT);
5519       npoll++;
5520       if (io.rc != ARM_SOCKET_EAGAIN) break;
5521     } while (GET_SYSTICK() - ticks < tout);
5522     /* Should return EAGAIN (operation timed out) */
5523     TH_ASSERT  (io.rc == ARM_SOCKET_EAGAIN);
5524     /* Check polling counter (max. 1000) */
5525     TH_ASSERT  (npoll >= 50);
5526
5527     /* Close socket, polling mode */
5528     io.sock = sock;
5529     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT*1000);
5530     ticks = GET_SYSTICK();
5531     do {
5532       TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5533       if (io.rc == 0) break;
5534     } while (GET_SYSTICK() - ticks < tout);
5535     TH_ASSERT  (io.rc == 0);
5536
5537     osDelay (10);
5538   }
5539
5540   /* Terminate worker thread */
5541   osThreadTerminate (worker);
5542 }
5543
5544 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
5545
5546 /* RecvFrom IO parameters */
5547 #ifndef __DOXYGEN__                     // Exclude form the documentation
5548 typedef struct {
5549   int32_t      sock;
5550   uint8_t     *buf;
5551   uint32_t     len;
5552   uint8_t     *ip;
5553   uint32_t    *ip_len;
5554   uint16_t    *port;
5555   int32_t      rc;
5556   /* Control */
5557   osThreadId_t owner;
5558   uint32_t     xid;
5559   uint32_t     tval;
5560 } IO_RECVFROM;
5561 #endif
5562
5563 /* Assign arguments */
5564 #define ARG_RECVFROM(_sock,_buf,_len,_ip,_ip_len,_port) do {                   \
5565                                                           io.sock   = _sock;   \
5566                                                           io.buf    = _buf;    \
5567                                                           io.len    = _len;    \
5568                                                           io.ip     = _ip;     \
5569                                                           io.ip_len = _ip_len; \
5570                                                           io.port   = _port;   \
5571                                                         } while (0)
5572
5573 /* RecvFrom worker thread */
5574 __NO_RETURN static void Th_RecvFrom (IO_RECVFROM *io) {
5575   uint32_t flags,xid;
5576
5577   for (;;) {
5578     /* Wait for the signal to select and execute the function */
5579     flags = osThreadFlagsWait (F_CREATE_UDP | F_CONNECT | F_SETOPT |
5580                                F_RECVFROM   | F_SEND    | F_CLOSE, osFlagsWaitAny, osWaitForever);
5581     xid   = io->xid;
5582     switch (flags) {
5583       case F_CREATE_UDP:
5584         /* Create datagram socket */
5585         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
5586         break;
5587
5588       case F_CONNECT:
5589         /* Connect on socket */
5590         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, CHARGEN_PORT);
5591         break;
5592
5593       case F_SETOPT: {
5594         /* Set socket options */
5595         int32_t opt_id = (io->tval > 1) ? ARM_SOCKET_SO_RCVTIMEO : ARM_SOCKET_IO_FIONBIO;
5596         io->rc = drv->SocketSetOpt (io->sock, opt_id, &io->tval, sizeof(io->tval));
5597       } break;
5598
5599       case F_RECVFROM:
5600         /* RecvFrom on socket */
5601         if (io->buf != NULL) {
5602           memset((void *)io->buf, 0xCC, io->len);
5603         }
5604         io->rc = drv->SocketRecvFrom (io->sock, io->buf, io->len, io->ip, io->ip_len, io->port);
5605         break;
5606
5607       case F_SEND:
5608         /* Send on socket */
5609         io->rc = drv->SocketSend (io->sock, "a", 1);
5610         break;
5611
5612       case F_CLOSE:
5613         /* Close socket */
5614         io->rc = drv->SocketClose (io->sock);
5615         break;
5616     }
5617     /* Done, send signal to owner thread */
5618     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
5619     osDelay(1);
5620     osThreadFlagsSet (io->owner, flags);
5621     osThreadFlagsClear (F_ALL);
5622   }
5623 }
5624
5625 /**
5626 \brief  Function: WIFI_SocketRecvFrom
5627 \ingroup wifi_sock_api
5628 \details
5629 The test function \b WIFI_SocketRecvFrom verifies the WiFi Driver \b SocketRecvFrom function:
5630 \code
5631 int32_t (*SocketRecvFrom) (int32_t socket, void *buf, uint32_t len, uint8_t *ip, uint32_t *ip_len, uint16_t *port);
5632 \endcode
5633
5634 Datagram socket test 1:
5635  - Create datagram socket
5636  - Connect to Chargen server
5637  - Check function parameters
5638  - Receive data in blocking mode
5639  - Set receive timeout to 1 sec
5640  - Receive again, timeout expires
5641  - Close socket
5642  - Receive again, closed socket
5643 */
5644 void WIFI_SocketRecvFrom (void) {
5645   uint8_t      ip[5];
5646   uint32_t     ip_len,ticks,tout;
5647   uint16_t     port;
5648   uint8_t      buf[4];
5649   osThreadId_t worker;
5650   int32_t      rval;
5651   IO_RECVFROM  io;
5652   int32_t      sock;
5653
5654   if (socket_funcs_exist == 0U) {
5655     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
5656     return;
5657   }
5658
5659   if (station_init (1) == 0) {
5660     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
5661     return;
5662   }
5663
5664   /* Create worker thread */
5665   worker = osThreadNew ((osThreadFunc_t)Th_RecvFrom, &io, NULL);
5666   if (worker == NULL) {
5667     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5668     return;
5669   }
5670
5671   ARG_INIT();
5672
5673   /* Create datagram socket */
5674   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
5675   if (io.rc < 0) {
5676     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
5677   } else {
5678     sock = io.rc;
5679
5680     /* Connect to datagram server */
5681     io.sock = sock;
5682     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
5683     TH_ASSERT  (io.rc == 0);
5684
5685     /* Check parameter (socket = -1) */
5686     ip_len = sizeof(ip);
5687     ARG_RECVFROM (-1, buf, sizeof(buf), ip, &ip_len, &port);
5688     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5689     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5690
5691     /* Check parameter (socket = INT32_MIN) */
5692     ARG_RECVFROM (INT32_MIN, buf, sizeof(buf), ip, &ip_len, &port);
5693     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5694     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5695
5696     /* Check parameter (socket = INT32_MAX) */
5697     ARG_RECVFROM (INT32_MAX, buf, sizeof(buf), ip, &ip_len, &port);
5698     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5699     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5700
5701     /* Check parameter (buf == NULL) */
5702     ARG_RECVFROM (sock, NULL, sizeof(buf), ip, &ip_len, &port);
5703     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5704     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
5705
5706     /* Send one byte of data to trigger a reply */
5707     io.sock = sock;
5708     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT_LONG);
5709     TH_ASSERT  (io.rc == 1);
5710
5711     /* Initialize buffers for return values */
5712     port   = 0;
5713     ip_len = sizeof(ip) + 1;
5714     memset ((void *)ip, 0, sizeof(ip));
5715     
5716     /* Receive no data (check that received data is available) */
5717     ARG_RECVFROM (sock, NULL, 0, ip, &ip_len, &port);
5718     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT_LONG);
5719     TH_ASSERT  (io.rc == 0);
5720
5721     /* Receive some data */
5722     ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
5723     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT_LONG);
5724     /* Should receive at least 2 bytes */
5725     TH_ASSERT  (io.rc >= 2);
5726     /* IP address should be the address of the server */
5727     TH_ASSERT  ((memcmp ((const void *)ip, (const void *)ip_socket_server, 4) == 0) && (ip_len == 4));
5728     /* Port number should be the port of the CHARGEN server */
5729     TH_ASSERT  (port == CHARGEN_PORT);
5730
5731     /* Set receive timeout to 1 sec */
5732     io.sock = sock;
5733     io.tval = 1000;
5734     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
5735     TH_ASSERT  (io.rc == 0);
5736
5737     /* Receive until timeout, no data */
5738     ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
5739     ticks = GET_SYSTICK();
5740     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5741     tout = GET_SYSTICK() - ticks;
5742     /* Should return EAGAIN (operation timed out) */
5743     TH_ASSERT  (io.rc == ARM_SOCKET_EAGAIN);
5744     /* Check receive timeout is in the range of 0.9 to 1.1 sec */
5745     TH_ASSERT  (tout > SYSTICK_MICROSEC(900000) && tout < SYSTICK_MICROSEC(1100000));
5746
5747     /* Close socket */
5748     io.sock = sock;
5749     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5750     TH_ASSERT  (io.rc == 0);
5751
5752     /* Receive again, closed socket */
5753     ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
5754     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5755     /* Should return error (socket not created) */
5756     /* Strict: ESOCK, valid non-strict: ERROR */
5757     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "recvfrom on closed socket", io.rc, ARM_SOCKET_ESOCK);
5758
5759     osDelay (10);
5760   }
5761
5762   if (rval == 0) {
5763     station_uninit ();
5764   }
5765
5766   /* Terminate worker thread */
5767   osThreadTerminate (worker);
5768 }
5769
5770 /**
5771 \brief  Test case: WIFI_SocketRecvFrom_nbio
5772 \ingroup wifi_sock_api
5773 \details
5774 The test case \b WIFI_SocketRecvFrom_nbio verifies the WiFi Driver \b SocketRecvFrom function
5775 running in non-blocking mode.
5776
5777 Datagram socket test 1:
5778  - Create datagram socket
5779  - Set non-blocking mode
5780  - Connect to Chargen server
5781  - Check function parameters
5782  - Receive data in non-blocking mode
5783  - Receive again, timeout expires
5784  - Close socket
5785  - Receive again, closed socket
5786 */
5787 void WIFI_SocketRecvFrom_nbio (void) {
5788   uint8_t      ip[4];
5789   uint32_t     ip_len,ticks,tout,npoll;
5790   uint16_t     port;
5791   uint8_t      buf[4];
5792   osThreadId_t worker;
5793   int32_t      rval;
5794   IO_RECVFROM  io;
5795   int32_t      sock;
5796
5797   /* Create worker thread */
5798   worker = osThreadNew ((osThreadFunc_t)Th_RecvFrom, &io, NULL);
5799   if (worker == NULL) {
5800     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
5801     return;
5802   }
5803
5804   ARG_INIT();
5805
5806   /* Create datagram socket */
5807   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
5808   if (io.rc < 0) {
5809     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
5810   } else {
5811     sock = io.rc;
5812
5813     /* Set socket non-blocking */
5814     io.sock = sock;
5815     io.tval = 1;
5816     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
5817     TH_ASSERT  (io.rc == 0);
5818
5819     /* Connect to datagram server */
5820     io.sock = sock;
5821     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
5822     TH_ASSERT  (io.rc == 0);
5823
5824     /* Check parameter (socket = -1) */
5825     ip_len = sizeof(ip);
5826     ARG_RECVFROM (-1, buf, sizeof(buf), ip, &ip_len, &port);
5827     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5828     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5829
5830     /* Check parameter (socket = INT32_MIN) */
5831     ARG_RECVFROM (INT32_MIN, buf, sizeof(buf), ip, &ip_len, &port);
5832     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5833     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5834
5835     /* Check parameter (socket = INT32_MAX) */
5836     ARG_RECVFROM (INT32_MAX, buf, sizeof(buf), ip, &ip_len, &port);
5837     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5838     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
5839
5840     /* Check parameter (buf == NULL) */
5841     ARG_RECVFROM (sock, NULL, sizeof(buf), ip, &ip_len, &port);
5842     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5843     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
5844
5845     /* Check if socket readable (len = 0) */
5846     ARG_RECVFROM (sock, buf, 0, ip, &ip_len, &port);
5847     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5848     /* No data available to read */
5849     TH_ASSERT  (io.rc == ARM_SOCKET_EAGAIN);
5850
5851     /* Send one byte of data to trigger a reply */
5852     io.sock = sock;
5853     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
5854     TH_ASSERT  (io.rc == 1);
5855
5856     /* Initialize buffers for return values */
5857     port   = 0;
5858     ip_len = sizeof(ip) + 1;
5859     memset (ip, 0, sizeof(ip));
5860     
5861     /* Receive some data */
5862     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT_LONG*1000);
5863     ticks = GET_SYSTICK();
5864     do {
5865       ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
5866       TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5867       if (io.rc != ARM_SOCKET_EAGAIN) break;
5868     } while (GET_SYSTICK() - ticks < tout);
5869     /* Should receive at least 2 bytes */
5870     TH_ASSERT  (io.rc >= 2);
5871     /* IP address should be the address of the server */
5872     TH_ASSERT  ((memcmp (ip, ip_socket_server, 4) == 0) && (ip_len == 4));
5873     /* Port number should be the port of the CHARGEN server */
5874     TH_ASSERT  (port == CHARGEN_PORT);
5875
5876      /* Receive for 1 sec, timeout no data */
5877     npoll = 0;
5878     tout  = SYSTICK_MICROSEC(1000000);
5879     ticks = GET_SYSTICK();
5880     do {
5881       ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
5882       TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5883       npoll++;
5884       if (io.rc != ARM_SOCKET_EAGAIN) break;
5885     } while (GET_SYSTICK() - ticks < tout);
5886     /* Should return EAGAIN (operation timed out) */
5887     TH_ASSERT  (io.rc == ARM_SOCKET_EAGAIN);
5888     /* Check polling counter (max. 1000) */
5889     TH_ASSERT  (npoll >= 50);
5890
5891     /* Close socket, polling mode */
5892     io.sock = sock;
5893     tout  = SYSTICK_MICROSEC(WIFI_SOCKET_TIMEOUT*1000);
5894     ticks = GET_SYSTICK();
5895     do {
5896       TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
5897       if (io.rc == 0) break;
5898     } while (GET_SYSTICK() - ticks < tout);
5899     TH_ASSERT  (io.rc == 0);
5900
5901     /* Receive again, closed socket */
5902     ARG_RECVFROM (sock, buffer, sizeof(buffer), ip, &ip_len, &port);
5903     TH_EXECUTE (F_RECVFROM, WIFI_SOCKET_TIMEOUT);
5904     /* Should return error (socket not created) */
5905     /* Strict: ESOCK, valid non-strict: ERROR */
5906     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "recvfrom on closed socket", io.rc, ARM_SOCKET_ESOCK);
5907
5908     osDelay (10);
5909   }
5910
5911   /* Terminate worker thread */
5912   osThreadTerminate (worker);
5913 }
5914
5915 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
5916
5917 /* Send IO parameters */
5918 #ifndef __DOXYGEN__                     // Exclude form the documentation
5919 typedef struct {
5920   int32_t        sock;
5921   const uint8_t *buf;
5922   uint32_t       len;
5923   int32_t        rc;
5924   /* Control */
5925   osThreadId_t owner;
5926   uint32_t     xid;
5927 } IO_SEND;
5928 #endif
5929
5930 /* Assign arguments */
5931 #define ARG_SEND(_sock,_buf,_len) do {               \
5932                                     io.sock = _sock; \
5933                                     io.buf  = _buf;  \
5934                                     io.len  = _len;  \
5935                                   } while (0)
5936
5937 /* Send worker thread */
5938 __NO_RETURN static void Th_Send (IO_SEND *io) {
5939   uint32_t flags,xid;
5940
5941   for (;;) {
5942     /* Wait for the signal to select and execute the function */
5943     flags = osThreadFlagsWait (F_CREATE_TCP | F_BIND | F_CONNECT |
5944                                F_LISTEN     | F_SEND | F_CLOSE, osFlagsWaitAny, osWaitForever);
5945     xid   = io->xid;
5946     switch (flags) {
5947       case F_CREATE_TCP:
5948         /* Create stream socket */
5949         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
5950         break;
5951
5952       case F_BIND:
5953         /* Bind socket */
5954         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
5955         break;
5956
5957       case F_CONNECT:
5958         /* Connect on socket */
5959         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
5960         break;
5961
5962        case F_LISTEN:
5963         /* Listen on socket */
5964         io->rc = drv->SocketListen (io->sock, 1);
5965         break;
5966
5967      case F_SEND:
5968         /* Send on socket */
5969         io->rc = drv->SocketSend (io->sock, io->buf, io->len);
5970         break;
5971
5972       case F_CLOSE:
5973         /* Close socket */
5974         io->rc = drv->SocketClose (io->sock);
5975         break;
5976     }
5977     /* Done, send signal to owner thread */
5978     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
5979     osDelay(1);
5980     osThreadFlagsSet (io->owner, flags);
5981     osThreadFlagsClear (F_ALL);
5982   }
5983 }
5984
5985 /**
5986 \brief  Function: WIFI_SocketSend
5987 \ingroup wifi_sock_api
5988 \details
5989 The test function \b WIFI_SocketSend verifies the WiFi Driver \b SocketSend function:
5990 \code
5991 int32_t (*SocketSend) (int32_t socket, const void *buf, uint32_t len);
5992 \endcode
5993
5994 Stream socket test 1:
5995  - Create stream socket
5996  - Connect to server, blocking mode
5997  - Check function parameters
5998  - Send data, blocking mode
5999  - Close socket
6000  - Send again, closed socket
6001
6002 Stream socket test 2:
6003  - Create stream socket
6004  - Connect to server, blocking mode
6005  - Send ESC data, server disconnects
6006  - Send again, disconnected socket
6007  - Close socket
6008
6009 Stream socket test 3:
6010  - Create stream socket
6011  - Send data, created socket
6012  - Bind socket
6013  - Send data, bound socket
6014  - Start listening
6015  - Send data, listening socket
6016  - Close socket
6017  - Send again, closed socket
6018 */
6019 void WIFI_SocketSend (void) {
6020   osThreadId_t worker;
6021   int32_t      rval;
6022   IO_SEND      io;
6023   int32_t      sock;
6024
6025   if (socket_funcs_exist == 0U) {
6026     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
6027     return;
6028   }
6029
6030   if (station_init (1) == 0) {
6031     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
6032     return;
6033   }
6034
6035   /* Create worker thread */
6036   worker = osThreadNew ((osThreadFunc_t)Th_Send, &io, NULL);
6037   if (worker == NULL) {
6038     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
6039     return;
6040   }
6041
6042   ARG_INIT();
6043
6044   /* Create stream socket */
6045   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6046   if (io.rc < 0) {
6047     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6048   } else {
6049     sock = io.rc;
6050
6051     /* Connect to stream server */
6052     io.sock = sock;
6053     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
6054     TH_ASSERT  (io.rc == 0);
6055
6056     /* Check parameter (socket = -1) */
6057     ARG_SEND   (-1, test_msg, sizeof(test_msg));
6058     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
6059     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6060
6061     /* Check parameter (socket = INT32_MIN) */
6062     ARG_SEND   (INT32_MIN, test_msg, sizeof(test_msg));
6063     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
6064     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6065
6066     /* Check parameter (socket = INT32_MAX) */
6067     ARG_SEND   (INT32_MAX, test_msg, sizeof(test_msg));
6068     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
6069     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6070
6071     /* Check parameter (buf = NULL) */
6072     ARG_SEND   (sock, NULL, sizeof(test_msg));
6073     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
6074     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6075
6076     /* Send no data (check that send is available) */
6077     ARG_SEND   (sock, test_msg, 0);
6078     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
6079     TH_ASSERT  (io.rc == 0);
6080
6081     /* Send some data */
6082     ARG_SEND   (sock, test_msg, sizeof(test_msg));
6083     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT_LONG);
6084     TH_ASSERT  (io.rc == sizeof(test_msg));
6085
6086     /* Close socket */
6087     io.sock = sock;
6088     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6089     TH_ASSERT  (io.rc == 0);
6090
6091     /* Send again, closed socket */
6092     ARG_SEND   (sock, test_msg, sizeof(test_msg));
6093     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
6094     /* Should return error (socket not created) */
6095     /* Strict: ESOCK, valid non-strict: ERROR */
6096     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "send on closed socket", io.rc, ARM_SOCKET_ESOCK);
6097
6098     osDelay (10);
6099   }
6100
6101   /* Create stream socket */
6102   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6103   if (io.rc < 0) {
6104     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6105   } else {
6106     sock = io.rc;
6107
6108     /* Connect to stream server */
6109     io.sock = sock;
6110     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
6111     TH_ASSERT  (io.rc == 0);
6112
6113     /* Send ESC command, server disconnects */
6114     ARG_SEND   (sock, (uint8_t *)"\x1B", 1);
6115     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT_LONG);
6116     TH_ASSERT  (io.rc == 1);
6117
6118     /* Wait for the server to disconnect */
6119     osDelay (200);
6120
6121     /* Send again, disconnected socket */
6122     ARG_SEND   (sock, test_msg, sizeof(test_msg));
6123     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
6124     /* Should return error (connection reset by the peer) */
6125     /* Strict: ECONNRESET, valid non-strict: ERROR */
6126     TH_ASSERT2 ((io.rc == ARM_SOCKET_ECONNRESET), (io.rc == ARM_SOCKET_ERROR), "send on disconnected socket", io.rc, ARM_SOCKET_ECONNRESET);
6127
6128     /* Close socket */
6129     io.sock = sock;
6130     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6131     TH_ASSERT  (io.rc == 0);
6132
6133     osDelay (10);
6134   }
6135
6136   /* Create stream socket */
6137   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6138   if (io.rc < 0) {
6139     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6140   } else {
6141     sock = io.rc;
6142
6143     /* Send data, created socket */
6144     ARG_SEND   (sock, test_msg, sizeof(test_msg));
6145     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
6146     /* Should return error (socket not connected) */
6147     /* Strict: ENOTCONN, valid non-strict: ERROR */
6148     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "send on created socket", io.rc, ARM_SOCKET_ENOTCONN);
6149
6150     /* Bind socket */
6151     io.sock = sock;
6152     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
6153     TH_ASSERT  (io.rc == 0);
6154
6155     /* Send data, bound socket */
6156     ARG_SEND (sock, test_msg, sizeof(test_msg));
6157     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
6158     /* Should return error (socket not connected) */
6159     /* Strict: ENOTCONN, valid non-strict: ERROR */
6160     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "send on bound socket", io.rc, ARM_SOCKET_ENOTCONN);
6161
6162     /* Start listening */
6163     io.sock = sock;
6164     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
6165     TH_ASSERT  (io.rc == 0);
6166
6167     /* Send data, listening socket */
6168     ARG_SEND (sock, test_msg, sizeof(test_msg));
6169     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
6170     /* Should return error (socket not connected) */
6171     /* Strict: ENOTCONN, valid non-strict: ERROR */
6172     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "send on listening socket", io.rc, ARM_SOCKET_ENOTCONN);
6173
6174     /* Close socket */
6175     io.sock = sock;
6176     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6177     TH_ASSERT  (io.rc == 0);
6178
6179     /* Send again, closed socket */
6180     ARG_SEND (sock, test_msg, sizeof(test_msg));
6181     TH_EXECUTE (F_SEND, WIFI_SOCKET_TIMEOUT);
6182     /* Should return error (socket not created) */
6183     /* Strict: ESOCK, valid non-strict: ERROR */
6184     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "send on closed socket", io.rc, ARM_SOCKET_ESOCK);
6185
6186     osDelay (10);
6187   }
6188
6189   if (rval == 0) {
6190     station_uninit ();
6191   }
6192
6193   /* Terminate worker thread */
6194   osThreadTerminate (worker);
6195 }
6196
6197 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
6198
6199 /* SendTo IO parameters */
6200 #ifndef __DOXYGEN__                     // Exclude form the documentation
6201 typedef struct {
6202   int32_t        sock;
6203   const uint8_t *buf;
6204   uint32_t       len;
6205   const uint8_t *ip;
6206   uint32_t       ip_len;
6207   uint16_t       port;
6208   uint16_t       reserved;
6209   int32_t        rc;
6210   /* Control */
6211   osThreadId_t owner;
6212   uint32_t     xid;
6213 } IO_SENDTO;
6214 #endif
6215
6216 /* Assign arguments */
6217 #define ARG_SENDTO(_sock,_buf,_len,_ip,_ip_len,_port) do {                   \
6218                                                         io.sock   = _sock;   \
6219                                                         io.buf    = _buf;    \
6220                                                         io.len    = _len;    \
6221                                                         io.ip     = _ip;     \
6222                                                         io.ip_len = _ip_len; \
6223                                                         io.port   = _port;   \
6224                                                       } while (0)
6225
6226 /* SendTo worker thread */
6227 __NO_RETURN static void Th_SendTo (IO_SENDTO *io) {
6228   uint32_t flags,xid;
6229
6230   for (;;) {
6231     /* Wait for the signal to select and execute the function */
6232     flags = osThreadFlagsWait (F_CREATE_UDP | F_SENDTO | F_RECV | F_CLOSE, osFlagsWaitAny, osWaitForever);
6233     xid   = io->xid;
6234     switch (flags) {
6235       case F_CREATE_UDP:
6236         /* Create datagram socket */
6237         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
6238         break;
6239
6240       case F_SENDTO:
6241         /* SendTo on socket */
6242         io->rc = drv->SocketSendTo (io->sock, io->buf, io->len, io->ip, io->ip_len, io->port);
6243         break;
6244
6245       case F_RECV:
6246         /* Recv on socket */
6247         memset((void *)buffer, 0xCC, sizeof(buffer));
6248         io->rc = drv->SocketRecv (io->sock, buffer, sizeof(buffer));
6249         break;
6250
6251       case F_CLOSE:
6252         /* Close socket */
6253         io->rc = drv->SocketClose (io->sock);
6254         break;
6255     }
6256     /* Done, send signal to owner thread */
6257     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
6258     osDelay(1);
6259     osThreadFlagsSet (io->owner, flags);
6260     osThreadFlagsClear (F_ALL);
6261   }
6262 }
6263
6264 /**
6265 \brief  Function: WIFI_SocketSendTo
6266 \ingroup wifi_sock_api
6267 \details
6268 The test function \b WIFI_SocketSend verifies the WiFi Driver \b SocketSendTo function:
6269 \code
6270 int32_t (*SocketSendTo) (int32_t socket, const void *buf, uint32_t len, const uint8_t *ip, uint32_t ip_len, uint16_t port);
6271 \endcode
6272
6273 Datagram socket test:
6274  - Create datagram socket
6275  - Check function parameters
6276  - Send data, blocking mode
6277  - Receive echo data, verify if the same
6278  - Close socket
6279  - Send again, closed socket
6280 */
6281 void WIFI_SocketSendTo (void) {
6282   osThreadId_t worker;
6283   int32_t      rval;
6284   IO_SENDTO    io;
6285   int32_t      sock;
6286
6287   if (socket_funcs_exist == 0U) {
6288     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
6289     return;
6290   }
6291
6292   if (station_init (1) == 0) {
6293     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
6294     return;
6295   }
6296
6297   /* Create worker thread */
6298   worker = osThreadNew ((osThreadFunc_t)Th_SendTo, &io, NULL);
6299   if (worker == NULL) {
6300     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
6301     return;
6302   }
6303
6304   ARG_INIT();
6305
6306   /* Create datagram socket */
6307   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
6308   if (io.rc < 0) {
6309     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
6310   } else {
6311     sock = io.rc;
6312
6313     /* Check parameter (socket = -1) */
6314     ARG_SENDTO (-1, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
6315     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
6316     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6317
6318     /* Check parameter (socket = INT32_MIN) */
6319     ARG_SENDTO (INT32_MIN, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
6320     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
6321     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6322
6323     /* Check parameter (socket = INT32_MAX) */
6324     ARG_SENDTO (INT32_MAX, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
6325     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
6326     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6327
6328     /* Check parameter (buf == NULL) */
6329     ARG_SENDTO (sock, NULL, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
6330     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
6331     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
6332
6333     /* Send no data (check that send is available) */
6334     ARG_SENDTO (sock, test_msg, 0, ip_socket_server, 4, ECHO_PORT);
6335     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
6336     TH_ASSERT  (io.rc == 0);
6337
6338     /* Send some data */
6339     ARG_SENDTO (sock, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
6340     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT_LONG);
6341     TH_ASSERT  (io.rc == sizeof(test_msg));
6342
6343     /* Receive the echoed data */
6344     io.sock = sock;
6345     TH_EXECUTE (F_RECV, WIFI_SOCKET_TIMEOUT_LONG);
6346     /* Should receive the same data (ECHO protocol) */
6347     TH_ASSERT  ((io.rc == sizeof(test_msg)) && (memcmp ((const void *)test_msg, (const void *)buffer, sizeof(test_msg)) == 0));
6348
6349     /* Close socket */
6350     io.sock = sock;
6351     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6352     TH_ASSERT  (io.rc == 0);
6353
6354     /* Send again, closed socket */
6355     ARG_SENDTO (sock, test_msg, sizeof(test_msg), ip_socket_server, 4, ECHO_PORT);
6356     TH_EXECUTE (F_SENDTO, WIFI_SOCKET_TIMEOUT);
6357     /* Should return error (socket not created) */
6358     /* Strict: ESOCK, valid non-strict: ERROR */
6359     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "sendto on closed socket", io.rc, ARM_SOCKET_ESOCK);
6360
6361     osDelay (10);
6362   }
6363
6364   if (rval == 0) {
6365     station_uninit ();
6366   }
6367
6368   /* Terminate worker thread */
6369   osThreadTerminate (worker);
6370 }
6371
6372 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
6373
6374 /* GetSockName IO parameters */
6375 #ifndef __DOXYGEN__                     // Exclude form the documentation
6376 typedef struct {
6377   int32_t      sock;
6378   uint8_t     *ip;
6379   uint32_t    *ip_len;
6380   uint16_t    *port;
6381   int32_t      rc;
6382   /* Control */
6383   osThreadId_t owner;
6384   uint32_t     xid;
6385 } IO_GETSOCKNAME;
6386 #endif
6387
6388 /* Assign arguments */
6389 #define ARG_GETSOCKNAME(_sock,_ip,_ip_len,_port) do {                   \
6390                                                    io.sock   = _sock;   \
6391                                                    io.ip     = _ip;     \
6392                                                    io.ip_len = _ip_len; \
6393                                                    io.port   = _port;   \
6394                                                  } while (0)
6395
6396 /* GetSockName worker thread */
6397 __NO_RETURN static void Th_GetSockName (IO_GETSOCKNAME *io) {
6398   uint32_t flags,xid;
6399
6400   for (;;) {
6401     /* Wait for the signal to select and execute the function */
6402     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP  | F_BIND |
6403                                F_CONNECT    | F_GETSOCKNAME | F_CLOSE, osFlagsWaitAny, osWaitForever);
6404     xid   = io->xid;
6405     switch (flags) {
6406       case F_CREATE_TCP:
6407         /* Create stream socket */
6408         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
6409         break;
6410
6411       case F_CREATE_UDP:
6412         /* Create datagram socket */
6413         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
6414         break;
6415
6416       case F_BIND:
6417         /* Bind socket */
6418         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
6419         break;
6420
6421       case F_CONNECT:
6422         /* Connect on socket */
6423         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
6424         break;
6425
6426       case F_GETSOCKNAME:
6427         /* Get socket name */
6428         io->rc = drv->SocketGetSockName (io->sock, io->ip, io->ip_len, io->port);
6429         break;
6430
6431       case F_CLOSE:
6432         /* Close socket */
6433         io->rc = drv->SocketClose (io->sock);
6434         break;
6435     }
6436     /* Done, send signal to owner thread */
6437     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
6438     osDelay(1);
6439     osThreadFlagsSet (io->owner, flags);
6440     osThreadFlagsClear (F_ALL);
6441   }
6442 }
6443
6444 /**
6445 \brief  Function: WIFI_SocketGetSockName
6446 \ingroup wifi_sock_api
6447 \details
6448 The test function \b WIFI_SocketGetSockName verifies the WiFi Driver \b SocketGetSockName function:
6449 \code
6450 int32_t (*SocketGetSockName) (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t *port);
6451 \endcode
6452
6453 Stream socket test 1:
6454  - Create stream socket
6455  - Connect to server, blocking mode
6456  - Check function parameters
6457  - Get socket name
6458  - Close socket
6459  - Get socket name again, closed socket
6460
6461 Stream socket test 1:
6462  - Create stream socket
6463  - Get socket name, not bound
6464  - Bind socket
6465  - Get socket name, bound
6466  - Close socket
6467
6468 Datagram socket test 1:
6469  - Create datagram socket
6470  - Connect to server, enable packet filtering
6471  - Check function parameters
6472  - Get socket name
6473  - Close socket
6474  - Get socket name again, closed socket
6475
6476 Datagram socket test 1:
6477  - Create datagram socket
6478  - Get socket name, not bound
6479  - Bind socket
6480  - Get socket name, bound
6481  - Close socket
6482 */
6483 void WIFI_SocketGetSockName (void) {
6484   uint8_t        local_ip[5];
6485   uint16_t       local_port;
6486   uint32_t       ip_len;
6487   osThreadId_t   worker;
6488   int32_t        rval;
6489   IO_GETSOCKNAME io;
6490   int32_t        sock;
6491
6492   if (socket_funcs_exist == 0U) {
6493     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
6494     return;
6495   }
6496
6497   if (station_init (1) == 0) {
6498     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
6499     return;
6500   }
6501
6502   /* Create worker thread */
6503   worker = osThreadNew ((osThreadFunc_t)Th_GetSockName, &io, NULL);
6504   if (worker == NULL) {
6505     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
6506     return;
6507   }
6508
6509   ARG_INIT();
6510
6511   /* Create stream socket */
6512   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6513   if (io.rc < 0) {
6514     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6515   } else {
6516     /* Test client mode */
6517     sock = io.rc;
6518
6519     /* Connect to stream server */
6520     io.sock = sock;
6521     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
6522     TH_ASSERT  (io.rc == 0);
6523
6524     /* Check parameter (socket = -1) */
6525     ip_len = sizeof(local_ip);
6526     ARG_GETSOCKNAME (-1, local_ip, &ip_len, &local_port);
6527     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6528     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6529
6530     /* Check parameter (socket = INT32_MIN) */
6531     ARG_GETSOCKNAME (INT32_MIN, local_ip, &ip_len, &local_port);
6532     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6533     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6534
6535     /* Check parameter (socket = INT32_MAX) */
6536     ARG_GETSOCKNAME (INT32_MAX, local_ip, &ip_len, &local_port);
6537     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6538     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6539
6540     /* Check parameter (port = NULL) */
6541     ip_len = sizeof(local_ip);
6542     ARG_GETSOCKNAME (sock, local_ip, &ip_len, NULL);
6543     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6544     /* Request IP address only should be accepted */
6545     TH_ASSERT  (io.rc == 0);
6546
6547     /* Check parameter (ip = NULL, ip_len = NULL) */
6548     ARG_GETSOCKNAME (sock, NULL, NULL, &local_port);
6549     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6550     /* Request port only should be accepted */
6551     TH_ASSERT  (io.rc == 0);
6552
6553     /* Initialize buffers for return values */
6554     local_port = 0;
6555     ip_len     = sizeof(local_ip) + 1;
6556     memcpy (local_ip, ip_bcast, sizeof(local_ip));
6557
6558     /* Retrieve socket name */
6559     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
6560     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6561     TH_ASSERT  (io.rc == 0);
6562     /* IP address should be different from broadcast */
6563     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_bcast, 4) != 0) && (ip_len == 4));
6564     /* Port number should be non-zero */
6565     TH_ASSERT  (local_port != 0);
6566
6567     /* Close socket */
6568     io.sock = sock;
6569     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6570     TH_ASSERT  (io.rc == 0);
6571
6572     /* Retrieve socket name again */
6573     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
6574     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6575     /* Should return error (socket not created) */
6576     /* Strict: ESOCK, valid non-strict: ERROR */
6577     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockname on closed socket", io.rc, ARM_SOCKET_ESOCK);
6578
6579     osDelay (10);
6580   }
6581
6582   /* Create stream socket */
6583   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6584   if (io.rc < 0) {
6585     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6586   } else {
6587     /* Test server mode */
6588     sock = io.rc;
6589
6590     /* Retrieve socket name, not bound */
6591     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
6592     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6593     /* Should return error (socket not bound) */
6594     /* Strict: EINVAL, valid non-strict: ERROR */
6595     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "getsockname on unbound socket", io.rc, ARM_SOCKET_EINVAL);
6596
6597     /* Initialize buffers for return values */
6598     local_port = 0;
6599     ip_len     = sizeof(local_ip) + 1;
6600     memcpy (local_ip, ip_bcast, sizeof(local_ip));
6601
6602     /* Bind socket */
6603     io.sock = sock;
6604     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
6605     TH_ASSERT  (io.rc == 0);
6606
6607     /* Retrieve socket name, bound */
6608     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
6609     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6610     TH_ASSERT  (io.rc == 0);
6611     /* IP address should be unspecified */
6612     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_unspec, 4) == 0) && (ip_len == 4));
6613     /* Port number should be listening port */
6614     TH_ASSERT  (local_port == DISCARD_PORT);
6615
6616     /* Close socket */
6617     io.sock = sock;
6618     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6619     TH_ASSERT  (io.rc == 0);
6620
6621     osDelay (10);
6622   }
6623
6624   /* Create datagram socket */
6625   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
6626   if (io.rc < 0) {
6627     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
6628   } else {
6629     /* Test client mode */
6630     sock = io.rc;
6631
6632     /* Connect to datagram server */
6633     io.sock = sock;
6634     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
6635     TH_ASSERT  (io.rc == 0);
6636
6637     /* Check parameter (socket = -1) */
6638     ARG_GETSOCKNAME (-1, local_ip, &ip_len, &local_port);
6639     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6640     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6641
6642     /* Check parameter (socket = INT32_MIN) */
6643     ARG_GETSOCKNAME (INT32_MIN, local_ip, &ip_len, &local_port);
6644     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6645     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6646
6647     /* Check parameter (socket = INT32_MAX) */
6648     ARG_GETSOCKNAME (INT32_MAX, local_ip, &ip_len, &local_port);
6649     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6650     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6651
6652     /* Check parameter (port = NULL) */
6653     ip_len = sizeof(local_ip);
6654     ARG_GETSOCKNAME (sock, local_ip, &ip_len, NULL);
6655     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6656     /* Request IP address only should be accepted */
6657     TH_ASSERT  (io.rc == 0);
6658
6659     /* Check parameter (ip = NULL, ip_len = NULL) */
6660     ARG_GETSOCKNAME (sock, NULL, NULL, &local_port);
6661     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6662     /* Request port only should be accepted */
6663     TH_ASSERT  (io.rc == 0);
6664
6665     /* Initialize buffers for return values */
6666     local_port = 0;
6667     ip_len     = sizeof(local_ip) + 1;
6668     memcpy (local_ip, ip_bcast, sizeof(local_ip));
6669
6670     /* Retrieve socket name */
6671     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
6672     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6673     TH_ASSERT  (io.rc == 0);
6674     /* IP address should be different from broadcast */
6675     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_bcast, 4) != 0) && (ip_len == 4));
6676     /* Port number should be non-zero */
6677     TH_ASSERT  (local_port != 0);
6678
6679     /* Close socket */
6680     io.sock = sock;
6681     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6682     TH_ASSERT  (io.rc == 0);
6683
6684     /* Retrieve socket name again */
6685     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
6686     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6687     /* Should return error (socket not created) */
6688     /* Strict: ESOCK, valid non-strict: ERROR */
6689     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockname on closed socket", io.rc, ARM_SOCKET_ESOCK);
6690
6691     osDelay (10);
6692   }
6693
6694   /* Create datagram socket */
6695   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
6696   if (io.rc < 0) {
6697     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
6698   } else {
6699     /* Test server mode */
6700     sock = io.rc;
6701
6702     /* Retrieve socket name, not bound */
6703     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
6704     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6705     /* Should return error (socket not bound) */
6706     /* Strict: EINVAL, valid non-strict: ERROR */
6707     TH_ASSERT2 ((io.rc == ARM_SOCKET_EINVAL), (io.rc == ARM_SOCKET_ERROR), "getsockname on unbound socket", io.rc, ARM_SOCKET_EINVAL);
6708
6709     /* Initialize buffers for return values */
6710     local_port = 0;
6711     ip_len     = sizeof(local_ip) + 1;
6712     memcpy (local_ip, ip_bcast, sizeof(local_ip));
6713
6714     /* Bind socket */
6715     io.sock = sock;
6716     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
6717     TH_ASSERT  (io.rc == 0);
6718
6719     /* Retrieve socket name, bound */
6720     ARG_GETSOCKNAME (sock, local_ip, &ip_len, &local_port);
6721     TH_EXECUTE (F_GETSOCKNAME, WIFI_SOCKET_TIMEOUT);
6722     TH_ASSERT  (io.rc == 0);
6723     /* IP address should be unspecified */
6724     TH_ASSERT  ((memcmp ((const void *)local_ip, (const void *)ip_unspec, 4) == 0) && (ip_len == 4));
6725     /* Port number should be listening port */
6726     TH_ASSERT  (local_port == DISCARD_PORT);
6727
6728     /* Close socket */
6729     io.sock = sock;
6730     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6731     TH_ASSERT  (io.rc == 0);
6732
6733     osDelay (10);
6734   }
6735
6736   if (rval == 0) {
6737     station_uninit ();
6738   }
6739
6740   /* Terminate worker thread */
6741   osThreadTerminate (worker);
6742 }
6743
6744 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
6745
6746 /* GetPeerName IO parameters */
6747 #ifndef __DOXYGEN__                     // Exclude form the documentation
6748 typedef struct {
6749   int32_t      sock;
6750   uint8_t     *ip;
6751   uint32_t    *ip_len;
6752   uint16_t    *port;
6753   int32_t      rc;
6754   /* Control */
6755   osThreadId_t owner;
6756   uint32_t     xid;
6757 } IO_GETPEERNAME;
6758 #endif
6759
6760 /* Assign arguments */
6761 #define ARG_GETPEERNAME(_sock,_ip,_ip_len,_port) do {                   \
6762                                                    io.sock   = _sock;   \
6763                                                    io.ip     = _ip;     \
6764                                                    io.ip_len = _ip_len; \
6765                                                    io.port   = _port;   \
6766                                                  } while (0)
6767
6768 /* GetPeerName worker thread */
6769 __NO_RETURN static void Th_GetPeerName (IO_GETPEERNAME *io) {
6770   uint32_t flags,xid;
6771
6772   for (;;) {
6773     /* Wait for the signal to select and execute the function */
6774     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP  | F_BIND | F_CONNECT |
6775                                F_LISTEN     | F_GETPEERNAME | F_CLOSE, osFlagsWaitAny, osWaitForever);
6776     xid   = io->xid;
6777     switch (flags) {
6778       case F_CREATE_TCP:
6779         /* Create stream socket */
6780         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
6781         break;
6782
6783       case F_CREATE_UDP:
6784         /* Create datagram socket */
6785         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
6786         break;
6787
6788       case F_BIND:
6789         /* Bind socket */
6790         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
6791         break;
6792
6793       case F_CONNECT:
6794         /* Connect on socket */
6795         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
6796         break;
6797
6798        case F_LISTEN:
6799         /* Listen on socket */
6800         io->rc = drv->SocketListen (io->sock, 1);
6801         break;
6802
6803       case F_GETPEERNAME:
6804         /* Get peer name  */
6805         io->rc = drv->SocketGetPeerName (io->sock, io->ip, io->ip_len, io->port);
6806         break;
6807
6808       case F_CLOSE:
6809         /* Close socket */
6810         io->rc = drv->SocketClose (io->sock);
6811         break;
6812     }
6813     /* Done, send signal to owner thread */
6814     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
6815     osDelay(1);
6816     osThreadFlagsSet (io->owner, flags);
6817     osThreadFlagsClear (F_ALL);
6818   }
6819 }
6820
6821 /**
6822 \brief  Function: WIFI_SocketGetPeerName
6823 \ingroup wifi_sock_api
6824 \details
6825 The test function \b WIFI_SocketGetPeerName verifies the WiFi Driver \b SocketGetPeerName function:
6826 \code
6827 int32_t (*SocketGetPeerName) (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t *port);
6828 \endcode
6829
6830 Stream socket test  1:
6831  - Create stream socket
6832  - Connect to server, blocking mode
6833  - Check function parameters
6834  - Get peer name
6835  - Close socket
6836  - Get peer name, closed socket
6837
6838 Stream socket test  2:
6839  - Create stream socket
6840  - Get peer name, created socket
6841  - Bind socket
6842  - Get peer name, bound socket
6843  - Start listening
6844  - Get peer name, listening socket
6845  - Close socket
6846
6847 Datagram socket test:
6848  - Create datagram socket
6849  - Connect to server, enable packet filtering
6850  - Check function parameters
6851  - Get peer name
6852  - Close socket
6853  - Get peer name, closed socket
6854 */
6855 void WIFI_SocketGetPeerName (void) {
6856   uint8_t        peer_ip[5];
6857   uint16_t       peer_port;
6858   uint32_t       ip_len;
6859   osThreadId_t   worker;
6860   int32_t        rval;
6861   IO_GETPEERNAME io;
6862   int32_t        sock;
6863
6864   if (socket_funcs_exist == 0U) {
6865     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
6866     return;
6867   }
6868
6869   if (station_init (1) == 0) {
6870     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
6871     return;
6872   }
6873
6874   /* Create worker thread */
6875   worker = osThreadNew ((osThreadFunc_t)Th_GetPeerName, &io, NULL);
6876   if (worker == NULL) {
6877     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
6878     return;
6879   }
6880
6881   ARG_INIT();
6882
6883   /* Create stream socket */
6884   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6885   if (io.rc < 0) {
6886     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6887   } else {
6888     sock = io.rc;
6889
6890     /* Connect to stream server */
6891     io.sock = sock;
6892     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
6893     TH_ASSERT  (io.rc == 0);
6894
6895     /* Check parameter (socket = -1) */
6896     ip_len = sizeof(peer_ip);
6897     ARG_GETPEERNAME (-1, peer_ip, &ip_len, &peer_port);
6898     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6899     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6900
6901     /* Check parameter (socket = INT32_MIN) */
6902     ARG_GETPEERNAME (INT32_MIN, peer_ip, &ip_len, &peer_port);
6903     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6904     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6905
6906     /* Check parameter (socket = INT32_MAX) */
6907     ARG_GETPEERNAME (INT32_MAX, peer_ip, &ip_len, &peer_port);
6908     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6909     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
6910
6911     /* Check parameter (port = NULL) */
6912     ip_len = sizeof(peer_ip);
6913     ARG_GETPEERNAME (sock, peer_ip, &ip_len, NULL);
6914     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6915     /* Request IP address only should be accepted */
6916     TH_ASSERT  (io.rc == 0);
6917
6918     /* Check parameter (ip = NULL, ip_len = NULL) */
6919     ARG_GETPEERNAME (sock, NULL, NULL, &peer_port);
6920     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6921     /* Request port only should be accepted */
6922     TH_ASSERT  (io.rc == 0);
6923
6924     /* Initialize buffers for return values */
6925     peer_port = 0;
6926     ip_len    = sizeof(peer_ip) + 1;
6927     memcpy (peer_ip, ip_bcast, sizeof(peer_ip));
6928
6929     /* Retrieve peer name */
6930     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6931     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6932     TH_ASSERT  (io.rc == 0);
6933     /* IP address should be the address of the server */
6934     TH_ASSERT  ((memcmp ((const void *)peer_ip, (const void *)ip_socket_server, 4) == 0) && (ip_len == 4));
6935     /* Port number should be the DISCARD port */
6936     TH_ASSERT  (peer_port == DISCARD_PORT);
6937
6938     /* Close stream socket */
6939     io.sock = sock;
6940     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6941     TH_ASSERT  (io.rc == 0);
6942
6943     /* Retrieve peer name again */
6944     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6945     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6946     /* Should return error (socket not created) */
6947     /* Strict: ESOCK, valid non-strict: ERROR */
6948     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getpeername on closed socket", io.rc, ARM_SOCKET_ESOCK);
6949
6950     osDelay (10);
6951   }
6952
6953   /* Create stream socket */
6954   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
6955   if (io.rc < 0) {
6956     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
6957   } else {
6958     sock = io.rc;
6959
6960     /* Get peer name, created socket */
6961     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6962     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6963     /* Should return error (socket not connected) */
6964     /* Strict: ENOTCONN, valid non-strict: ERROR */
6965     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "getpeername on created socket", io.rc, ARM_SOCKET_ENOTCONN);
6966
6967     /* Bind socket */
6968     io.sock = sock;
6969     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
6970     TH_ASSERT  (io.rc == 0);
6971
6972     /* Get peer name, bound socket */
6973     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6974     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6975     /* Should return error (socket not connected) */
6976     /* Strict: ENOTCONN, valid non-strict: ERROR */
6977     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "getpeername on bound socket", io.rc, ARM_SOCKET_ENOTCONN);
6978
6979     /* Start listening */
6980     io.sock = sock;
6981     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
6982     TH_ASSERT  (io.rc == 0);
6983
6984     /* Get peer name, listening socket */
6985     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
6986     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
6987     /* Should return error (socket not connected) */
6988     /* Strict: ENOTCONN, valid non-strict: ERROR */
6989     TH_ASSERT2 ((io.rc == ARM_SOCKET_ENOTCONN), (io.rc == ARM_SOCKET_ERROR), "getpeername on listening socket", io.rc, ARM_SOCKET_ENOTCONN);
6990
6991     /* Close socket */
6992     io.sock = sock;
6993     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
6994     TH_ASSERT  (io.rc == 0);
6995
6996     osDelay (10);
6997   }
6998
6999   /* Create datagram socket */
7000   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
7001   if (io.rc < 0) {
7002     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
7003   } else {
7004     sock = io.rc;
7005
7006     /* Connect to datagram server */
7007     io.sock = sock;
7008     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
7009     TH_ASSERT  (io.rc == 0);
7010
7011     /* Check parameter (socket = -1) */
7012     ip_len =  sizeof(peer_ip);
7013     ARG_GETPEERNAME (-1, peer_ip, &ip_len, &peer_port);
7014     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
7015     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7016
7017     /* Check parameter (socket = INT32_MIN) */
7018     ARG_GETPEERNAME (INT32_MIN, peer_ip, &ip_len, &peer_port);
7019     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
7020     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7021
7022     /* Check parameter (socket = INT32_MAX) */
7023     ARG_GETPEERNAME (INT32_MAX, peer_ip, &ip_len, &peer_port);
7024     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
7025     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7026
7027     /* Check parameter (port = NULL) */
7028     ip_len = sizeof(peer_ip);
7029     ARG_GETPEERNAME (sock, peer_ip, &ip_len, NULL);
7030     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
7031     /* Request IP address only should be accepted */
7032     TH_ASSERT  (io.rc == 0);
7033
7034     /* Check parameter (ip = NULL, ip_len = NULL) */
7035     ARG_GETPEERNAME (sock, NULL, NULL, &peer_port);
7036     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
7037     /* Request port only should be accepted */
7038     TH_ASSERT  (io.rc == 0);
7039
7040     /* Initialize buffers for return values */
7041     peer_port = 0;
7042     ip_len    = sizeof(peer_ip) + 1;
7043     memcpy (peer_ip, ip_bcast, sizeof(peer_ip));
7044
7045     /* Retrieve peer name */
7046     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
7047     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
7048     TH_ASSERT  (io.rc == 0);
7049     /* IP address should be the address of the server */
7050     TH_ASSERT  ((memcmp ((const void *)peer_ip, (const void *)ip_socket_server, 4) == 0) && (ip_len == 4));
7051     /* Port number should be the DISCARD port */
7052     TH_ASSERT  (peer_port == DISCARD_PORT);
7053
7054     /* Close socket */
7055     io.sock = sock;
7056     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7057     TH_ASSERT  (io.rc == 0);
7058
7059     /* Retrieve peer name again */
7060     ARG_GETPEERNAME (sock, peer_ip, &ip_len, &peer_port);
7061     TH_EXECUTE (F_GETPEERNAME, WIFI_SOCKET_TIMEOUT);
7062     /* Should return error (socket not created) */
7063     /* Strict: ESOCK, valid non-strict: ERROR */
7064     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getpeername on closed socket", io.rc, ARM_SOCKET_ESOCK);
7065
7066     osDelay (10);
7067   }
7068
7069   if (rval == 0) {
7070     station_uninit ();
7071   }
7072
7073   /* Terminate worker thread */
7074   osThreadTerminate (worker);
7075 }
7076
7077 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
7078
7079 /* GetOpt IO parameters */
7080 #ifndef __DOXYGEN__                     // Exclude form the documentation
7081 typedef struct {
7082   int32_t      sock;
7083   int32_t      opt_id;
7084   void        *opt_val;
7085   uint32_t    *opt_len;
7086   int32_t      rc;
7087   /* Control */
7088   osThreadId_t owner;
7089   uint32_t     xid;
7090 } IO_GETOPT;
7091 #endif
7092
7093 /* Assign arguments */
7094 #define ARG_GETOPT(_sock,_opt_id,_opt_val,_opt_len) do {                     \
7095                                                       io.sock    = _sock;    \
7096                                                       io.opt_id  = _opt_id;  \
7097                                                       io.opt_val = _opt_val; \
7098                                                       io.opt_len = _opt_len; \
7099                                                     } while (0)
7100
7101 /* GetOpt worker thread */
7102 __NO_RETURN static void Th_GetOpt (IO_GETOPT *io) {
7103   uint32_t flags,xid;
7104
7105   for (;;) {
7106     /* Wait for the signal to select and execute the function */
7107     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP |
7108                                F_GETOPT     | F_CLOSE, osFlagsWaitAny, osWaitForever);
7109     xid   = io->xid;
7110     switch (flags) {
7111       case F_CREATE_TCP:
7112         /* Create stream socket */
7113         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
7114         break;
7115
7116       case F_CREATE_UDP:
7117         /* Create datagram socket */
7118         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
7119         break;
7120
7121       case F_GETOPT:
7122         /* Get socket options */
7123         io->rc = drv->SocketGetOpt (io->sock, io->opt_id, io->opt_val, io->opt_len);
7124         break;
7125
7126       case F_CLOSE:
7127         /* Close socket */
7128         io->rc = drv->SocketClose (io->sock);
7129         break;
7130     }
7131     /* Done, send signal to owner thread */
7132     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
7133     osDelay(1);
7134     osThreadFlagsSet (io->owner, flags);
7135     osThreadFlagsClear (F_ALL);
7136   }
7137 }
7138
7139 /**
7140 \brief  Function: WIFI_SocketGetOpt
7141 \ingroup wifi_sock_api
7142 \details
7143 The test function \b WIFI_SocketGetOpt verifies the WiFi Driver \b SocketGetOpt function:
7144 \code
7145 int32_t (*SocketGetOpt) (int32_t socket, int32_t opt_id, void *opt_val, uint32_t *opt_len);
7146 \endcode
7147
7148 Stream socket test:
7149  - Create stream socket
7150  - Check function parameters
7151  - Get socket options
7152  - Close socket
7153  - Get socket options again, closed socket
7154
7155 Datagram socket test:
7156  - Create datagram socket
7157  - Get socket type
7158  - Close socket
7159  - Get socket type
7160 */
7161 void WIFI_SocketGetOpt (void) {
7162   uint32_t     opt_val;
7163   uint32_t     opt_len;
7164   osThreadId_t worker;
7165   int32_t      rval;
7166   IO_GETOPT    io;
7167   int32_t      sock;
7168
7169   if (socket_funcs_exist == 0U) {
7170     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
7171     return;
7172   }
7173
7174   if (station_init (1) == 0) {
7175     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7176     return;
7177   }
7178
7179   /* Create worker thread */
7180   worker = osThreadNew ((osThreadFunc_t)Th_GetOpt, &io, NULL);
7181   if (worker == NULL) {
7182     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7183     return;
7184   }
7185
7186   ARG_INIT();
7187
7188   /* Create stream socket */
7189   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7190   if (io.rc < 0) {
7191     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7192   } else {
7193     sock = io.rc;
7194  
7195     /* Check parameter (socket = -1) */
7196     opt_len = sizeof(opt_val);
7197     ARG_GETOPT (-1, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
7198     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7199     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7200
7201     /* Check parameter (socket = INT32_MIN) */
7202     ARG_GETOPT (INT32_MIN, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
7203     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7204     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7205
7206     /* Check parameter (socket = INT32_MAX) */
7207     ARG_GETOPT (INT32_MAX, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
7208     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7209     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7210
7211     /* Check parameter (opt_id = -1) */
7212     ARG_GETOPT (sock, -1, &opt_val, &opt_len);
7213     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7214     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7215
7216     /* Check parameter (opt_id = INT32_MIN) */
7217     ARG_GETOPT (sock, INT32_MIN, &opt_val, &opt_len);
7218     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7219     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7220
7221     /* Check parameter (opt_id = INT32_MAX) */
7222     ARG_GETOPT (sock, INT32_MAX, &opt_val, &opt_len);
7223     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7224     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7225
7226     /* Check parameter (opt_val = NULL) */
7227     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, NULL, &opt_len);
7228     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7229     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7230
7231     /* Check parameter (opt_len = NULL) */
7232     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, NULL);
7233     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7234     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7235
7236     /* Check parameter (*opt_len = 0) */
7237     opt_len = 0;
7238     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
7239     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7240     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7241
7242     /* Check parameter (*opt_len = 5) */
7243     opt_len = 5;
7244     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
7245     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7246     TH_ASSERT  ((io.rc == 0) && (opt_len == 4));
7247
7248     /* Get option FIONBIO (set only) */
7249     opt_len = sizeof(opt_val);
7250     ARG_GETOPT (sock, ARM_SOCKET_IO_FIONBIO, &opt_val, &opt_len);
7251     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7252     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7253
7254     /* Get option RCVTIMEO */
7255     opt_len = sizeof(opt_val) + 1;
7256     opt_val = 0xE2A5A241;
7257     ARG_GETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, &opt_len);
7258     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7259     TH_ASSERT  (io.rc == 0);
7260     /* Should be different from the initial value */
7261     TH_ASSERT  ((opt_val != 0xE2A5A241) && (opt_len == 4));
7262
7263     /* Get option SNDTIMEO */
7264     opt_len = sizeof(opt_val) + 1;
7265     opt_val = 0xE2A5A241;
7266     ARG_GETOPT (sock, ARM_SOCKET_SO_SNDTIMEO, &opt_val, &opt_len);
7267     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7268     TH_ASSERT  (io.rc == 0);
7269     /* Should be different from the initial value */
7270     TH_ASSERT  ((opt_val != 0xE2A5A241) && (opt_len == 4));
7271
7272     /* Get option KEEPALIVE */
7273     opt_len = sizeof(opt_val) + 1;
7274     opt_val = 0xE2A5A241;
7275     ARG_GETOPT (sock, ARM_SOCKET_SO_KEEPALIVE, &opt_val, &opt_len);
7276     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7277     TH_ASSERT  (io.rc == 0);
7278     /* Should be different from the initial value */
7279     TH_ASSERT  ((opt_val != 0xE2A5A241) && (opt_len == 4));
7280
7281     /* Get option socket TYPE */
7282     opt_len = sizeof(opt_val) + 1;
7283     opt_val = UINT32_MAX;
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);
7287     /* Should be SOCK_STREAM type */
7288     TH_ASSERT  ((opt_val == ARM_SOCKET_SOCK_STREAM) && (opt_len == 4));
7289
7290     /* Close stream socket */
7291     io.sock = sock;
7292     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7293     TH_ASSERT  (io.rc == 0);
7294
7295     /* Get option socket TYPE again */
7296     opt_len = sizeof(opt_val);
7297     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
7298     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7299     /* Should return error (socket not created) */
7300     /* Strict: ESOCK, valid non-strict: ERROR */
7301     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
7302
7303     osDelay (10);
7304   }
7305
7306   /* Create datagram socket */
7307   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
7308   if (io.rc < 0) {
7309     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
7310   } else {
7311     sock = io.rc;
7312
7313     /* Get option socket TYPE */
7314     opt_len = sizeof(opt_val) + 1;
7315     opt_val = UINT32_MAX;
7316     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
7317     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7318     TH_ASSERT  (io.rc == 0);
7319     /* Should be SOCK_DGRAM type */
7320     TH_ASSERT  ((opt_val == ARM_SOCKET_SOCK_DGRAM) && (opt_len == 4));
7321
7322     /* Close socket */
7323     io.sock = sock;
7324     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7325     TH_ASSERT  (io.rc == 0);
7326
7327     /* Get option socket TYPE again */
7328     opt_len = sizeof(opt_val);
7329     ARG_GETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, &opt_len);
7330     TH_EXECUTE (F_GETOPT, WIFI_SOCKET_TIMEOUT);
7331     /* Should return error (socket not created) */
7332     /* Strict: ESOCK, valid non-strict: ERROR */
7333     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "getsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
7334
7335     osDelay (10);
7336   }
7337
7338   if (rval == 0) {
7339     station_uninit ();
7340   }
7341
7342   /* Terminate worker thread */
7343   osThreadTerminate (worker);
7344 }
7345
7346 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
7347
7348 /* SetOpt IO parameters */
7349 #ifndef __DOXYGEN__                     // Exclude form the documentation
7350 typedef struct {
7351   int32_t      sock;
7352   int32_t      opt_id;
7353   const void  *opt_val;
7354   uint32_t     opt_len;
7355   int32_t      rc;
7356   /* Control */
7357   osThreadId_t owner;
7358   uint32_t     xid;
7359 } IO_SETOPT;
7360 #endif
7361
7362 /* Assign arguments */
7363 #define ARG_SETOPT(_sock,_opt_id,_opt_val,_opt_len) do {                     \
7364                                                       io.sock    = _sock;    \
7365                                                       io.opt_id  = _opt_id;  \
7366                                                       io.opt_val = _opt_val; \
7367                                                       io.opt_len = _opt_len; \
7368                                                     } while (0)
7369
7370 /* SetOpt worker thread */
7371 __NO_RETURN static void Th_SetOpt (IO_SETOPT *io) {
7372   uint32_t flags,xid;
7373
7374   for (;;) {
7375     /* Wait for the signal to select and execute the function */
7376     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_SETOPT | F_CLOSE, osFlagsWaitAny, osWaitForever);
7377     xid   = io->xid;
7378     switch (flags) {
7379       case F_CREATE_TCP:
7380         /* Create stream socket */
7381         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
7382         break;
7383
7384       case F_CREATE_UDP:
7385         /* Create datagram socket */
7386         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
7387         break;
7388
7389       case F_SETOPT:
7390         /* Set socket options */
7391         io->rc = drv->SocketSetOpt (io->sock, io->opt_id, io->opt_val, io->opt_len);
7392         break;
7393
7394       case F_CLOSE:
7395         /* Close socket */
7396         io->rc = drv->SocketClose (io->sock);
7397         break;
7398     }
7399     /* Done, send signal to owner thread */
7400     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
7401     osDelay(1);
7402     osThreadFlagsSet (io->owner, flags);
7403     osThreadFlagsClear (F_ALL);
7404   }
7405 }
7406
7407 /**
7408 \brief  Function: WIFI_SocketSetOpt
7409 \ingroup wifi_sock_api
7410 \details
7411 The test function \b WIFI_SocketSetOpt verifies the WiFi Driver \b SocketSetOpt function:
7412 \code
7413 int32_t (*SocketSetOpt) (int32_t socket, int32_t opt_id, const void *opt_val, uint32_t opt_len);
7414 \endcode
7415
7416 Stream socket test:
7417  - Create stream socket
7418  - Check function parameters
7419  - Set socket options
7420  - Close socket
7421  - Set socket option again, closed socket
7422
7423 Datagram socket test:
7424  - Create datagram socket
7425  - Set socket options
7426  - Close socket
7427  - Set socket option again, closed socket
7428 */
7429
7430 void WIFI_SocketSetOpt (void) {
7431   uint32_t     opt_val;
7432   osThreadId_t worker;
7433   int32_t      rval;
7434   IO_SETOPT    io;
7435   int32_t      sock;
7436
7437   if (socket_funcs_exist == 0U) {
7438     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
7439     return;
7440   }
7441
7442   if (station_init (1) == 0) {
7443     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7444     return;
7445   }
7446
7447   /* Create worker thread */
7448   worker = osThreadNew ((osThreadFunc_t)Th_SetOpt, &io, NULL);
7449   if (worker == NULL) {
7450     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7451     return;
7452   }
7453
7454   ARG_INIT();
7455
7456   /* Create stream socket */
7457   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7458   if (io.rc < 0) {
7459     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7460   } else {
7461     sock = io.rc;
7462  
7463     /* Check parameter (socket = -1) */
7464     opt_val = 5000;
7465     ARG_SETOPT (-1, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
7466     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7467     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7468
7469     /* Check parameter (socket = INT32_MIN) */
7470     ARG_SETOPT (-1, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
7471     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7472     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7473
7474     /* Check parameter (socket = INT32_MAX) */
7475     ARG_SETOPT (-1, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
7476     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7477     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7478
7479     /* Check parameter (opt_id = -1) */
7480     ARG_SETOPT (sock, -1, &opt_val, sizeof(opt_val));
7481     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7482     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7483
7484     /* Check parameter (opt_id = INT32_MIN) */
7485     ARG_SETOPT (sock, INT32_MIN, &opt_val, sizeof(opt_val));
7486     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7487     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7488
7489     /* Check parameter (opt_id = INT32_MAX) */
7490     ARG_SETOPT (sock, INT32_MAX, &opt_val, sizeof(opt_val));
7491     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7492     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7493
7494     /* Check parameter (opt_val = NULL) */
7495     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, NULL, sizeof(opt_val));
7496     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7497     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7498
7499     /* Check parameter (opt_len = 0) */
7500     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, 0);
7501     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7502     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7503
7504     /* Check parameter (opt_len = 3) */
7505     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, 3);
7506     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7507     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7508
7509     /* Set option FIONBIO (set only) */
7510     opt_val = 0;
7511     ARG_SETOPT (sock, ARM_SOCKET_IO_FIONBIO, &opt_val, sizeof(opt_val));
7512     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7513     TH_ASSERT  (io.rc == 0);
7514
7515     /* Set option RCVTIMEO */
7516     opt_val = 5000;
7517     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
7518     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7519     TH_ASSERT  (io.rc == 0);
7520
7521     /* Set option SNDTIMEO */
7522     opt_val = 2000;
7523     ARG_SETOPT (sock, ARM_SOCKET_SO_SNDTIMEO, &opt_val, sizeof(opt_val));
7524     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7525     TH_ASSERT  (io.rc == 0);
7526
7527     /* Set option KEEPALIVE */
7528     opt_val = 1;
7529     ARG_SETOPT (sock, ARM_SOCKET_SO_KEEPALIVE, &opt_val, sizeof(opt_val));
7530     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7531     TH_ASSERT  (io.rc == 0);
7532
7533     /* Set option socket TYPE (get only) */
7534     opt_val = ARM_SOCKET_SOCK_STREAM;
7535     ARG_SETOPT (sock, ARM_SOCKET_SO_TYPE, &opt_val, sizeof(opt_val));
7536     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7537     TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7538
7539     /* Close stream socket */
7540     io.sock = sock;
7541     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7542     TH_ASSERT  (io.rc == 0);
7543
7544     /* Set option RCVTIMEO again */
7545     opt_val = 5000;
7546     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
7547     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7548     /* Should return error (socket not created) */
7549     /* Strict: ESOCK, valid non-strict: ERROR */
7550     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "setsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
7551
7552     osDelay (10);
7553   }
7554
7555   /* Create datagram socket */
7556   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
7557   if (io.rc < 0) {
7558     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
7559   } else {
7560     sock = io.rc;
7561
7562     /* Set option RCVTIMEO */
7563     opt_val = 5000;
7564     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
7565     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7566     TH_ASSERT  (io.rc == 0);
7567
7568     /* Close socket */
7569     io.sock = sock;
7570     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7571     TH_ASSERT  (io.rc == 0);
7572
7573     /* Set option RCVTIMEO again */
7574     ARG_SETOPT (sock, ARM_SOCKET_SO_RCVTIMEO, &opt_val, sizeof(opt_val));
7575     TH_EXECUTE (F_SETOPT, WIFI_SOCKET_TIMEOUT);
7576     /* Should return error (socket not created) */
7577     /* Strict: ESOCK, valid non-strict: ERROR */
7578     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == ARM_SOCKET_ERROR), "setsockopt on closed socket", io.rc, ARM_SOCKET_ESOCK);
7579
7580     osDelay (10);
7581   }
7582
7583   if (rval == 0) {
7584     station_uninit ();
7585   }
7586
7587   /* Terminate worker thread */
7588   osThreadTerminate (worker);
7589 }
7590
7591 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
7592
7593 /* Close IO parameters */
7594 #ifndef __DOXYGEN__                     // Exclude form the documentation
7595 typedef struct {
7596   int32_t      sock;
7597   int32_t      rc;
7598   /* Control */
7599   osThreadId_t owner;
7600   uint32_t     xid;
7601 } IO_CLOSE;
7602 #endif
7603
7604 /* Assign arguments */
7605 #define ARG_CLOSE(_sock) do {               \
7606                            io.sock = _sock; \
7607                          } while (0)
7608
7609 /* Close worker thread */
7610 __NO_RETURN static void Th_Close (IO_CLOSE *io) {
7611   uint32_t flags,xid;
7612
7613   for (;;) {
7614     /* Wait for the signal to select and execute the function */
7615     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP | F_BIND |
7616                                F_CONNECT    | F_LISTEN     | F_CLOSE, osFlagsWaitAny, osWaitForever);
7617     xid   = io->xid;
7618     switch (flags) {
7619       case F_CREATE_TCP:
7620         /* Create stream socket */
7621         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
7622         break;
7623
7624       case F_CREATE_UDP:
7625         /* Create datagram socket */
7626         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
7627         break;
7628
7629       case F_BIND:
7630         /* Bind socket */
7631         io->rc = drv->SocketBind (io->sock, ip_unspec, 4, DISCARD_PORT);
7632         break;
7633
7634       case F_CONNECT:
7635         /* Connect on socket */
7636         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, DISCARD_PORT);
7637         break;
7638
7639       case F_LISTEN:
7640         /* Listen on socket */
7641         io->rc = drv->SocketListen (io->sock, 1);
7642         break;
7643
7644       case F_CLOSE:
7645         /* Close socket */
7646         io->rc = drv->SocketClose (io->sock);
7647         break;
7648     }
7649     /* Done, send signal to owner thread */
7650     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
7651     osDelay(1);
7652     osThreadFlagsSet (io->owner, flags);
7653     osThreadFlagsClear (F_ALL);
7654   }
7655 }
7656
7657 /**
7658 \brief  Function: WIFI_SocketClose
7659 \ingroup wifi_sock_api
7660 \details
7661 The test function \b WIFI_SocketClose verifies the WiFi Driver \b SocketClose function:
7662 \code
7663 int32_t (*SocketClose) (int32_t socket);
7664 \endcode
7665
7666 Stream socket test 1:
7667  - Create stream socket
7668  - Bind socket
7669  - Connect to server
7670  - Check function parameters
7671  - Close socket
7672  - Close socket again
7673
7674 Stream socket test 2:
7675  - Create stream socket
7676  - Bind socket
7677  - Start listening
7678  - Close socket
7679  - Close socket again
7680
7681 Datagram socket test:
7682  - Create datagram socket
7683  - Bind socket
7684  - Check function parameters
7685  - Close socket
7686  - Close socket again
7687 */
7688 void WIFI_SocketClose (void) {
7689   osThreadId_t worker;
7690   int32_t      rval;
7691   IO_CLOSE     io;
7692   int32_t      sock;
7693
7694   if (socket_funcs_exist == 0U) {
7695     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
7696     return;
7697   }
7698
7699   if (station_init (1) == 0) {
7700     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7701     return;
7702   }
7703
7704   /* Create worker thread */
7705   worker = osThreadNew ((osThreadFunc_t)Th_Close, &io, NULL);
7706   if (worker == NULL) {
7707     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7708     return;
7709   }
7710
7711   ARG_INIT();
7712
7713   /* Create stream socket */
7714   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7715   if (io.rc < 0) {
7716     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7717   } else {
7718     sock = io.rc;
7719
7720     /* Connect to stream server */
7721     io.sock = sock;
7722     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
7723     TH_ASSERT  (io.rc == 0);
7724
7725     /* Check parameter (socket = -1) */
7726     ARG_CLOSE  (-1);
7727     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7728     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7729
7730     /* Check parameter (socket = INT32_MIN) */
7731     ARG_CLOSE  (INT32_MIN);
7732     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7733     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7734
7735     /* Check parameter (socket = INT32_MAX) */
7736     ARG_CLOSE  (INT32_MAX);
7737     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7738     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7739
7740     /* Close socket */
7741     ARG_CLOSE  (sock);
7742     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7743     TH_ASSERT  (io.rc == 0);
7744
7745     /* Close again, closed socket */
7746     ARG_CLOSE  (sock);
7747     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7748     /* Should return error (socket not created) */
7749     /* Strict: ESOCK, valid non-strict: OK */
7750     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == 0), "close already closed socket", io.rc, ARM_SOCKET_ESOCK);
7751
7752     osDelay (10);
7753   }
7754
7755   /* Create stream socket */
7756   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
7757   if (io.rc < 0) {
7758     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
7759   } else {
7760     sock = io.rc;
7761
7762     /* Bind socket */
7763     io.sock = sock;
7764     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
7765     TH_ASSERT  (io.rc == 0);
7766
7767     /* Start listening */
7768     io.sock = sock;
7769     TH_EXECUTE (F_LISTEN, WIFI_SOCKET_TIMEOUT);
7770     TH_ASSERT  (io.rc == 0);
7771
7772     /* Close socket */
7773     ARG_CLOSE (sock);
7774     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7775     TH_ASSERT  (io.rc == 0);
7776
7777     /* Close again, closed socket */
7778     ARG_CLOSE (sock);
7779     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7780     /* Should return error (socket not created) */
7781     /* Strict: ESOCK, valid non-strict: OK */
7782     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == 0), "close already closed socket", io.rc, ARM_SOCKET_ESOCK);
7783
7784     osDelay (10);
7785   }
7786
7787   /* Create datagram socket */
7788   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
7789   if (io.rc < 0) {
7790     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
7791   } else {
7792     sock = io.rc;
7793
7794     /* Bind socket */
7795     io.sock = sock;
7796     TH_EXECUTE (F_BIND, WIFI_SOCKET_TIMEOUT);
7797     TH_ASSERT  (io.rc == 0);
7798
7799     /* Check parameter (socket = -1) */
7800     ARG_CLOSE  (-1);
7801     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7802     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7803
7804     /* Check parameter (socket = INT32_MIN) */
7805     ARG_CLOSE  (INT32_MIN);
7806     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7807     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7808
7809     /* Check parameter (socket = INT32_MAX) */
7810     ARG_CLOSE  (INT32_MAX);
7811     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7812     TH_ASSERT  (io.rc == ARM_SOCKET_ESOCK);
7813
7814     /* Close socket */
7815     ARG_CLOSE  (sock);
7816     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7817     TH_ASSERT  (io.rc == 0);
7818
7819     /* Close again, closed socket */
7820     ARG_CLOSE  (sock);
7821     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
7822     /* Should return error (socket not created) */
7823     /* Strict: ESOCK, valid non-strict: OK */
7824     TH_ASSERT2 ((io.rc == ARM_SOCKET_ESOCK), (io.rc == 0), "close already closed socket", io.rc, ARM_SOCKET_ESOCK);
7825
7826     osDelay (10);
7827   }
7828
7829   if (rval == 0) {
7830     station_uninit ();
7831   }
7832
7833   /* Terminate worker thread */
7834   osThreadTerminate (worker);
7835 }
7836
7837 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
7838
7839 /* GetHostByName IO parameters */
7840 #ifndef __DOXYGEN__                     // Exclude form the documentation
7841 typedef struct {
7842   const char  *name;
7843   int32_t      af;
7844   uint8_t     *ip;
7845   uint32_t    *ip_len;
7846   int32_t      rc;
7847   /* Control */
7848   osThreadId_t owner;
7849   uint32_t     xid;
7850 } IO_GETHOST;
7851 #endif
7852
7853 /* Assign arguments */
7854 #define ARG_GETHOST(_name,_af,_ip,_ip_len) do {                   \
7855                                              io.name   = _name;   \
7856                                              io.af     = _af;     \
7857                                              io.ip     = _ip;     \
7858                                              io.ip_len = _ip_len; \
7859                                            } while (0)
7860
7861 /* GetHostByName worker thread */
7862 __NO_RETURN static void Th_GetHostByName (IO_GETHOST *io) {
7863   uint32_t flags,xid;
7864
7865   for (;;) {
7866     /* Wait for the signal to select and execute the function */
7867     flags = osThreadFlagsWait (F_GETHOSTBYNAME, osFlagsWaitAny, osWaitForever);
7868     xid   = io->xid;
7869     switch (flags) {
7870       case F_GETHOSTBYNAME:
7871         /* Resolve host */
7872         io->rc = drv->SocketGetHostByName (io->name, io->af, io->ip, io->ip_len);
7873         break;
7874     }
7875     /* Done, send signal to owner thread */
7876     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
7877     osDelay(1);
7878     osThreadFlagsSet (io->owner, flags);
7879     osThreadFlagsClear (F_ALL);
7880   }
7881 }
7882
7883 /**
7884 \brief  Function: WIFI_SocketGetHostByName
7885 \ingroup wifi_sock_api
7886 \details
7887 The test function \b WIFI_SocketGetHostByName the WiFi Driver \b SocketGetHostByName function:
7888 \code
7889 int32_t (*SocketGetHostByName) (const char *name, int32_t af, uint8_t *ip, uint32_t *ip_len);
7890 \endcode
7891
7892 Function test:
7893  - Check function parameters
7894  - Resolve host
7895  - Resolve non-existent host
7896
7897 \note
7898 This test requires internet connectivity to DNS server.
7899 */
7900 void WIFI_SocketGetHostByName (void) {
7901   const char  *host_name = "www.arm.com";
7902   uint8_t      host_ip[5];
7903   uint32_t     ip_len;
7904   osThreadId_t worker;
7905   int32_t      rval;
7906   IO_GETHOST   io;
7907
7908   if (socket_funcs_exist == 0U) {
7909     TEST_ASSERT_MESSAGE(0,"[FAILED] Socket functions not available");
7910     return;
7911   }
7912
7913   if (station_init (1) == 0) {
7914     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
7915     return;
7916   }
7917
7918   /* Create worker thread */
7919   worker = osThreadNew ((osThreadFunc_t)Th_GetHostByName, &io, NULL);
7920   if (worker == NULL) {
7921     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
7922     return;
7923   }
7924
7925   ARG_INIT();
7926
7927   /* Check parameter (name = NULL) */
7928   ip_len = sizeof(host_ip);
7929   ARG_GETHOST(NULL, ARM_SOCKET_AF_INET, host_ip, &ip_len);
7930   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7931   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7932
7933   /* Check parameter (af = -1) */
7934   ARG_GETHOST(host_name, -1, host_ip, &ip_len);
7935   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7936   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7937
7938   /* Check parameter (af = INT32_MIN) */
7939   ARG_GETHOST(host_name, INT32_MIN, host_ip, &ip_len);
7940   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7941   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7942
7943   /* Check parameter (af = INT32_MAX) */
7944   ARG_GETHOST(host_name, INT32_MAX, host_ip, &ip_len);
7945   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7946   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7947
7948   /* Check parameter (ip = NULL) */
7949   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, NULL, &ip_len);
7950   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7951   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7952
7953   /* Check parameter (ip_len = NULL) */
7954   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, host_ip, NULL);
7955   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7956   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7957
7958   /* Check parameter (*ip_len = 0) */
7959   ip_len = 0;
7960   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, host_ip, &ip_len);
7961   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7962   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7963
7964   /* Check parameter (*ip_len = 3) */
7965   ip_len = 3;
7966   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, host_ip, &ip_len);
7967   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT);
7968   TH_ASSERT  (io.rc == ARM_SOCKET_EINVAL);
7969
7970   /* Resolve valid host */
7971   ip_len = sizeof(host_ip) + 1;
7972   memset((void *)host_ip, 0, sizeof(host_ip));
7973   ARG_GETHOST(host_name, ARM_SOCKET_AF_INET, host_ip, &ip_len);
7974   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT_LONG);
7975   /* IP address should be valid */
7976   TH_ASSERT  ((memcmp((const void *)host_ip, (const void *)ip_unspec, 4) != 0) && (ip_len == 4));
7977
7978   /* Resolve non-existent host */
7979   ip_len = sizeof(host_ip);
7980   ARG_GETHOST("non.existent.host", ARM_SOCKET_AF_INET, host_ip, &ip_len);
7981   TH_EXECUTE (F_GETHOSTBYNAME, WIFI_SOCKET_TIMEOUT_LONG);
7982   /* Should return error (host not found) */
7983   /* Strict: EHOSTNOTFOUND, valid non-strict: ERROR */
7984   TH_ASSERT2 ((io.rc == ARM_SOCKET_EHOSTNOTFOUND), (io.rc == ARM_SOCKET_ERROR), "gethostbyname for non-existing host", io.rc, ARM_SOCKET_EHOSTNOTFOUND);
7985
7986   if (rval == 0) {
7987     station_uninit ();
7988   }
7989
7990   /* Terminate worker thread */
7991   osThreadTerminate (worker);
7992 }
7993
7994 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
7995
7996 /* Ping IO parameters */
7997 #ifndef __DOXYGEN__                     // Exclude form the documentation
7998 typedef struct {
7999   const uint8_t *ip;
8000   uint32_t       ip_len;
8001   int32_t        rc;
8002   /* Control */
8003   osThreadId_t owner;
8004   uint32_t     xid;
8005 } IO_PING;
8006 #endif
8007
8008 /* Assign arguments */
8009 #define ARG_PING(_ip,_ip_len) do {                   \
8010                                 io.ip     = _ip;     \
8011                                 io.ip_len = _ip_len; \
8012                               } while (0)
8013
8014 /* Ping worker thread */
8015 __NO_RETURN static void Th_Ping (IO_PING *io) {
8016   uint32_t flags,xid;
8017
8018   for (;;) {
8019     /* Wait for the signal to select and execute the function */
8020     flags = osThreadFlagsWait (F_PING, osFlagsWaitAny, osWaitForever);
8021     xid   = io->xid;
8022     switch (flags) {
8023       case F_PING:
8024         /* Ping host */
8025         io->rc = drv->Ping (io->ip, io->ip_len);
8026         break;
8027     }
8028     /* Done, send signal to owner thread */
8029     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
8030     osDelay(1);
8031     osThreadFlagsSet (io->owner, flags);
8032     osThreadFlagsClear (F_ALL);
8033   }
8034 }
8035
8036 /**
8037 \brief  Function: WIFI_Ping
8038 \ingroup wifi_sock_api
8039 \details
8040 The test function \b WIFI_Ping verifies the WiFi Driver \b Ping function:
8041 \code
8042 int32_t (*Ping) (const uint8_t *ip, uint32_t ip_len);
8043 \endcode
8044
8045 Function test:
8046  - Check function parameters
8047  - Ping host
8048 */
8049 void WIFI_Ping (void) {
8050   osThreadId_t worker;
8051   int32_t      rval;
8052   IO_PING      io;
8053
8054   if (drv->Ping == NULL) {
8055     TEST_ASSERT_MESSAGE(0,"[FAILED] Ping function not available");
8056     return;
8057   }
8058
8059   if (station_init (1) == 0) {
8060     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8061     return;
8062   }
8063
8064   /* Create worker thread */
8065   worker = osThreadNew ((osThreadFunc_t)Th_Ping, &io, NULL);
8066   if (worker == NULL) {
8067     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8068     return;
8069   }
8070
8071   ARG_INIT();
8072
8073   /* Check parameter (ip = NULL) */
8074   ARG_PING   (NULL, 4);
8075   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
8076   TH_ASSERT  (io.rc == ARM_DRIVER_ERROR_PARAMETER);
8077
8078   /* Check parameter (ip_len = 0) */
8079   ARG_PING   (ip_socket_server, 0);
8080   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
8081   TH_ASSERT  (io.rc == ARM_DRIVER_ERROR_PARAMETER);
8082
8083   /* Check parameter (ip_len = 5) */
8084   ARG_PING   (ip_socket_server, 5);
8085   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
8086   TH_ASSERT  (io.rc == ARM_DRIVER_ERROR_PARAMETER);
8087
8088   /* Ping server */
8089   ARG_PING   (ip_socket_server, 4);
8090   TH_EXECUTE (F_PING, WIFI_SOCKET_TIMEOUT);
8091   TH_ASSERT  (io.rc == ARM_DRIVER_OK);
8092
8093   if (rval == 0) {
8094     station_uninit ();
8095   }
8096
8097   /* Terminate worker thread */
8098   osThreadTerminate (worker);
8099 }
8100
8101 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
8102
8103 /**
8104 \defgroup wifi_sock_op Socket Operation
8105 \ingroup wifi_tests
8106 \details 
8107 These tests verify operation of the WiFi socket functions.
8108 */
8109
8110 /* Worker thread is used for the following tests:
8111    - WIFI_Transfer_Fixed
8112    - WIFI_Transfer_Incremental
8113    - WIFI_Send_Fragmented
8114    - WIFI_Recv_Fragmented
8115    - WIFI_Test_Speed
8116    - WIFI_Concurrent_Socket
8117 */
8118
8119 /* Transfer IO parameters */
8120 #ifndef __DOXYGEN__                     // Exclude form the documentation
8121 typedef struct {
8122   int32_t      sock;
8123   uint32_t     len;
8124   uint32_t     size;
8125   int32_t      rc;
8126   /* Control */
8127   osThreadId_t owner;
8128   uint32_t     xid;
8129   int32_t      tcp;
8130 } IO_TRANSFER;
8131 #endif
8132
8133 /* Assign arguments */
8134 #define ARG_TRANSFER(_sock,_len,_size) do {               \
8135                                          io.sock = _sock; \
8136                                          io.len  = _len;  \
8137                                          io.size = _size; \
8138                                        } while (0)
8139
8140 /* Transfer worker thread */
8141 __NO_RETURN static void Th_Transfer (IO_TRANSFER *io) {
8142   uint32_t flags,xid,i,j;
8143   int32_t  rc = 0;
8144
8145   for (;;) {
8146     /* Wait for the signal to select and execute the function */
8147     flags = osThreadFlagsWait (F_CREATE_TCP | F_CREATE_UDP |
8148                                F_CONNECT    | F_CLOSE      |
8149                                F_XFER_FIXED | F_XFER_INCR  |
8150                                F_SEND_FRAG  | F_RECV_FRAG, osFlagsWaitAny, osWaitForever);
8151     xid   = io->xid;
8152     switch (flags) {
8153       case F_CREATE_TCP:
8154         /* Create stream socket */
8155         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
8156         break;
8157
8158       case F_CREATE_UDP:
8159         /* Create datagram socket */
8160         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_DGRAM, ARM_SOCKET_IPPROTO_UDP);
8161         break;
8162
8163       case F_CONNECT:
8164         /* Connect on socket */
8165         io->rc = drv->SocketConnect (io->sock, ip_socket_server, 4, ECHO_PORT);
8166         break;
8167
8168       case F_CLOSE:
8169         /* Close socket */
8170         io->rc = drv->SocketClose (io->sock);
8171         break;
8172
8173       case F_XFER_FIXED:
8174         /* Transfer Fixed size blocks */
8175         memset ((void *)buffer, 0xCC, io->len);
8176         /* Send and receive in small blocks */
8177         for (i = 0; i < io->len; i += io->size) {
8178           rc = drv->SocketSend (io->sock, &test_buf[i], io->size);
8179           if (rc <= 0) break;
8180           for (j = 0; j < io->size; j += (uint32_t)rc) {
8181             /* Returns any data available, up to requested amount */
8182             rc = drv->SocketRecv (io->sock, &buffer[i+j], io->size-j);
8183             if ((rc <= 0) || !io->tcp) break;
8184           }
8185           if (rc <= 0) break;
8186         }
8187         if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
8188           rc = (int32_t)i;
8189         }
8190         io->rc = rc;
8191         break;
8192
8193       case F_XFER_INCR:
8194         /* Transfer Increased size blocks */
8195         memset ((void *)buffer, 0xCC, io->len);
8196         /* Send and receive in enlarged block sizes */
8197         for (i = 0; i < io->len; i += io->size++) {
8198           rc = drv->SocketSend (io->sock, &test_buf[i], io->size);
8199           if (rc <= 0) break;
8200           rc = drv->SocketRecv (io->sock, &buffer[i], io->size);
8201           if (rc <= 0) break;
8202         }
8203         if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
8204           rc = (int32_t)i;
8205         }
8206         io->rc = rc;
8207         break;
8208
8209       case F_SEND_FRAG:
8210         /* Send Fragmented blocks */
8211         memset ((void *)buffer, 0xCC, io->len);
8212         /* Send in small blocks */
8213         for (i = 0; i < io->len; i += io->size) {
8214           rc = drv->SocketSend (io->sock, &test_buf[i], io->size);
8215           if (rc <= 0) break;
8216         }
8217         /* Receive in single block */
8218         if (rc > 0) {
8219           /* Small delay that blocks are received */
8220           osDelay (100);
8221           for (i = 0; i < io->len; i += (uint32_t)rc) {
8222             /* Returns any data available, up to requested amount */
8223             rc = drv->SocketRecv (io->sock, &buffer[i], io->len-i);
8224             if (rc <= 0) break;
8225           }
8226           if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
8227             rc = (int32_t)i;
8228           }
8229         }
8230         io->rc = rc;
8231         break;
8232
8233       case F_RECV_FRAG:
8234         /* Receive Fragmented blocks */
8235         memset ((void *)buffer, 0xCC, io->len);
8236         /* Send single block */
8237         rc = drv->SocketSend (io->sock, test_buf, io->len);
8238         if (rc > 0) {
8239           osDelay (100);
8240           /* Receive in small blocks */
8241           for (i = 0; i < io->len; i += io->size) {
8242             for (j = 0; j < io->size; j += (uint32_t)rc) {
8243               /* Returns any data available, up to requested amount */
8244               rc = drv->SocketRecv (io->sock, &buffer[i+j], io->size-j);
8245               if (rc <= 0) break;
8246             }
8247             if (rc <= 0) break;
8248           }
8249           if (memcmp ((const void *)buffer, (const void *)test_buf, io->len) == 0) {
8250             rc = (int32_t)i;
8251           }
8252         }
8253         io->rc = rc;
8254         break;
8255     }
8256     /* Done, send signal to owner thread */
8257     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
8258     osDelay(1);
8259     osThreadFlagsSet (io->owner, flags);
8260     osThreadFlagsClear (F_ALL);
8261   }
8262 }
8263
8264 /**
8265 \brief  Function: WIFI_Transfer_Fixed
8266 \ingroup wifi_sock_op
8267 \details
8268 The test function \b WIFI_Transfer_Fixed verifies data transfer in fixed size blocks.
8269  
8270 Stream socket test: 
8271  - Create stream socket
8272  - Transfer 128 blocks of   16 bytes
8273  - Transfer  32 blocks of   64 bytes
8274  - Transfer   8 blocks of  256 bytes
8275  - Transfer   2 blocks of 1024 bytes
8276  - Transfer   1 block  of 2048 bytes
8277  - Close socket
8278
8279 Datagram socket test:
8280  - Create datagram socket
8281  - Transfer 128 blocks of   16 bytes
8282  - Transfer  32 blocks of   64 bytes
8283  - Transfer   8 blocks of  256 bytes
8284  - Transfer   2 blocks of 1024 bytes
8285  - Transfer   1 block  of 1460 bytes
8286  - Close socket
8287 */
8288 void WIFI_Transfer_Fixed (void) {
8289   osThreadId_t worker;
8290   int32_t      rval;
8291   IO_TRANSFER  io;
8292   int32_t      sock;
8293
8294   if (station_init (1) == 0) {
8295     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8296     return;
8297   }
8298
8299   /* Create worker thread */
8300   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
8301   if (worker == NULL) {
8302     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8303     return;
8304   }
8305
8306   ARG_INIT();
8307
8308   /* Create stream socket */
8309   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8310   if (io.rc < 0) {
8311     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8312   } else {
8313     sock = io.rc;
8314
8315     /* Connect to stream server */
8316     io.tcp  = 1;
8317     io.sock = sock;
8318     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
8319     TH_ASSERT  (io.rc == 0);
8320
8321     /* Transfer 16-byte block(s) */
8322     ARG_TRANSFER (sock, 2048, 16);
8323     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8324     TH_ASSERT  (io.rc == 2048);
8325
8326     /* Transfer 64-byte block(s) */
8327     ARG_TRANSFER (sock, 2048, 64);
8328     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8329     TH_ASSERT  (io.rc == 2048);
8330
8331     /* Transfer 256-byte block(s) */
8332     ARG_TRANSFER (sock, 2048, 256);
8333     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8334     TH_ASSERT  (io.rc == 2048);
8335
8336     /* Transfer 1024-byte block(s) */
8337     ARG_TRANSFER (sock, 2048, 1024);
8338     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8339     TH_ASSERT  (io.rc == 2048);
8340
8341     /* Transfer 2048-byte block */
8342     ARG_TRANSFER (sock, 2048, 2048);
8343     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8344     TH_ASSERT  (io.rc == 2048);
8345
8346     /* Close stream socket */
8347     io.sock = sock;
8348     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8349     TH_ASSERT  (io.rc == 0);
8350
8351     osDelay (10);
8352   }
8353
8354   /* Create datagram socket */
8355   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
8356   if (io.rc < 0) {
8357     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
8358   } else {
8359     sock = io.rc;
8360
8361     /* Connect to datagram server */
8362     io.tcp  = 0;
8363     io.sock = sock;
8364     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
8365     TH_ASSERT  (io.rc == 0);
8366
8367     /* Transfer 16-byte block(s) */
8368     ARG_TRANSFER (sock, 2048, 16);
8369     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8370     TH_ASSERT  (io.rc == 2048);
8371
8372     /* Transfer 64-byte block(s) */
8373     ARG_TRANSFER (sock, 2048, 64);
8374     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8375     TH_ASSERT  (io.rc == 2048);
8376
8377     /* Transfer 256-byte block(s) */
8378     ARG_TRANSFER (sock, 2048, 256);
8379     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8380     TH_ASSERT  (io.rc == 2048);
8381
8382     /* Transfer 1024-byte block(s) */
8383     ARG_TRANSFER (sock, 2048, 1024);
8384     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8385     TH_ASSERT  (io.rc == 2048);
8386
8387     /* Transfer 1460-byte block */
8388     ARG_TRANSFER (sock, 1460, 1460);
8389     TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8390     TH_ASSERT  (io.rc == 1460);
8391
8392     /* Close datagram socket */
8393     io.sock = sock;
8394     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8395     TH_ASSERT  (io.rc == 0);
8396
8397     osDelay (10);
8398   }
8399
8400   if (rval == 0) {
8401     station_uninit ();
8402   }
8403
8404   /* Terminate worker thread */
8405   osThreadTerminate (worker);
8406 }
8407
8408 /**
8409 \brief  Function: WIFI_Transfer_Incremental
8410 \ingroup wifi_sock_op
8411 \details
8412 The test function \b WIFI_Transfer_Incremental verifies data transfer in ascending size blocks.
8413 Each subsequent block that the socket sends is one byte larger than the previous block.
8414
8415 Stream socket test:
8416  - Create stream socket
8417  - Transfer 51 blocks of   1 -  50 bytes
8418  - Transfer 30 blocks of  51 -  80 bytes
8419  - Transfer 20 blocks of  81 - 100 bytes
8420  - Transfer 13 blocks of 120 - 132 bytes
8421  - Transfer  8 blocks of 252 - 259 bytes
8422  - Transfer  4 blocks of 510 - 513 bytes
8423  - Close socket
8424
8425 Datagram socket test:
8426  - Create datagram socket
8427  - Transfer 51 blocks of   1 -  50 bytes
8428  - Transfer 30 blocks of  51 -  80 bytes
8429  - Transfer 20 blocks of  81 - 100 bytes
8430  - Transfer 13 blocks of 120 - 132 bytes
8431  - Transfer  8 blocks of 252 - 259 bytes
8432  - Transfer  4 blocks of 510 - 513 bytes
8433  - Close socket
8434 */
8435 void WIFI_Transfer_Incremental (void) {
8436   osThreadId_t worker;
8437   int32_t      rval;
8438   IO_TRANSFER  io;
8439   int32_t      sock;
8440
8441   if (station_init (1) == 0) {
8442     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8443     return;
8444   }
8445
8446   /* Create worker thread */
8447   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
8448   if (worker == NULL) {
8449     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8450     return;
8451   }
8452
8453   ARG_INIT();
8454
8455   /* Create stream socket */
8456   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8457   if (io.rc < 0) {
8458     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8459   } else {
8460     sock = io.rc;
8461
8462     /* Connect to stream server */
8463     io.sock = sock;
8464     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
8465     TH_ASSERT  (io.rc == 0);
8466
8467     /* Transfer 1 byte - 50 byte blocks */
8468     ARG_TRANSFER (sock, 1275, 1);
8469     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8470     TH_ASSERT  (io.rc == 1275);
8471
8472     /* Transfer 51 byte - 80-byte blocks */
8473     ARG_TRANSFER (sock, 1965, 51);
8474     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8475     TH_ASSERT  (io.rc == 1965);
8476
8477     /* Transfer 81 byte - 100 byte blocks */
8478     ARG_TRANSFER (sock, 1810, 81);
8479     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8480     TH_ASSERT  (io.rc == 1810);
8481
8482     /* Transfer 120 byte - 132 byte blocks */
8483     ARG_TRANSFER (sock, 1905, 120);
8484     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8485     TH_ASSERT  (io.rc == 1905);
8486
8487     /* Transfer 252 byte - 259 byte blocks */
8488     ARG_TRANSFER (sock, 2044, 252);
8489     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8490     TH_ASSERT  (io.rc == 2044);
8491
8492     /* Transfer 510 byte - 513 byte blocks */
8493     ARG_TRANSFER (sock, 2046, 510);
8494     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8495     TH_ASSERT  (io.rc == 2046);
8496
8497     /* Close stream socket */
8498     io.sock = sock;
8499     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8500     TH_ASSERT  (io.rc == 0);
8501
8502     osDelay (10);
8503   }
8504
8505   /* Create datagram socket */
8506   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
8507   if (io.rc < 0) {
8508     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
8509   } else {
8510     sock = io.rc;
8511
8512     /* Connect to datagram server */
8513     io.sock = sock;
8514     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
8515     TH_ASSERT  (io.rc == 0);
8516
8517     /* Transfer 1 byte - 50 byte blocks */
8518     ARG_TRANSFER (sock, 1275, 1);
8519     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8520     TH_ASSERT  (io.rc == 1275);
8521
8522     /* Transfer 51 byte - 80-byte blocks */
8523     ARG_TRANSFER (sock, 1965, 51);
8524     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8525     TH_ASSERT  (io.rc == 1965);
8526
8527     /* Transfer 81 byte - 100 byte blocks */
8528     ARG_TRANSFER (sock, 1810, 81);
8529     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8530     TH_ASSERT  (io.rc == 1810);
8531
8532     /* Transfer 120 byte - 132 byte blocks */
8533     ARG_TRANSFER (sock, 1905, 120);
8534     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8535     TH_ASSERT  (io.rc == 1905);
8536
8537     /* Transfer 252 byte - 259 byte blocks */
8538     ARG_TRANSFER (sock, 2044, 252);
8539     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8540     TH_ASSERT  (io.rc == 2044);
8541
8542     /* Transfer 510 byte - 513 byte blocks */
8543     ARG_TRANSFER (sock, 2046, 510);
8544     TH_EXECUTE (F_XFER_INCR, WIFI_SOCKET_TIMEOUT_LONG);
8545     TH_ASSERT  (io.rc == 2046);
8546
8547     /* Close datagram socket */
8548     io.sock = sock;
8549     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8550     TH_ASSERT  (io.rc == 0);
8551
8552     osDelay (10);
8553   }
8554
8555   if (rval == 0) {
8556     station_uninit ();
8557   }
8558
8559   /* Terminate worker thread */
8560   osThreadTerminate (worker);
8561 }
8562
8563 /**
8564 \brief  Function: WIFI_Send_Fragmented
8565 \ingroup wifi_sock_op
8566 \details
8567 The test function \b WIFI_Send_Fragmented verifies data transfer in chunks.
8568
8569 Stream socket test:
8570  - Create stream socket
8571  - Send 16 blocks of   16 bytes, receive 1 block of  256 bytes
8572  - Send 16 blocks of   64 bytes, receive 1 block of 1024 bytes
8573  - Send  5 blocks of  256 bytes, receive 1 block of 1280 bytes
8574  - Send  2 blocks of 1024 bytes, receive 1 block of 2048 bytes
8575  - Close socket
8576 */
8577 void WIFI_Send_Fragmented (void) {
8578   osThreadId_t worker;
8579   int32_t      rval;
8580   IO_TRANSFER  io;
8581   int32_t      sock;
8582
8583   if (station_init (1) == 0) {
8584     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8585     return;
8586   }
8587
8588   /* Create worker thread */
8589   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
8590   if (worker == NULL) {
8591     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8592     return;
8593   }
8594
8595   ARG_INIT();
8596
8597   /* Create stream socket */
8598   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8599   if (io.rc < 0) {
8600     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8601   } else {
8602     sock = io.rc;
8603
8604     /* Connect to stream server */
8605     io.sock = sock;
8606     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
8607     TH_ASSERT  (io.rc == 0);
8608
8609     /* Transfer 16-byte block(s) */
8610     ARG_TRANSFER (sock, 256, 16);
8611     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
8612     TH_ASSERT  (io.rc == 256);
8613
8614     /* Transfer 64-byte block(s) */
8615     ARG_TRANSFER (sock, 1024, 64);
8616     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
8617     TH_ASSERT  (io.rc == 1024);
8618
8619     /* Transfer 256-byte block(s) */
8620     ARG_TRANSFER (sock, 1280, 256);
8621     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
8622     TH_ASSERT  (io.rc == 1280);
8623
8624     /* Transfer 1024-byte block(s) */
8625     ARG_TRANSFER (sock, 2048, 1024);
8626     TH_EXECUTE (F_SEND_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
8627     TH_ASSERT  (io.rc == 2048);
8628
8629     /* Close stream socket */
8630     io.sock = sock;
8631     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8632     TH_ASSERT  (io.rc == 0);
8633
8634     osDelay (10);
8635   }
8636
8637   if (rval == 0) {
8638     station_uninit ();
8639   }
8640
8641   /* Terminate worker thread */
8642   osThreadTerminate (worker);
8643 }
8644
8645 /**
8646 \brief  Function: WIFI_Recv_Fragmented
8647 \ingroup wifi_sock_op
8648 \details
8649 The test function \b WIFI_Recv_Fragmented verifies data transfer in chunks.
8650
8651 Stream socket test:
8652  - Create stream socket
8653  - Send block of  256 bytes, receive 16 blocks of   16 bytes
8654  - Send block of 1024 bytes, receive 16 blocks of   64 bytes
8655  - Send block of 1280 bytes, receive  5 blocks of  256 bytes
8656  - Send block of 2048 bytes, receive  2 blocks of 1024 bytes
8657  - Close socket
8658 */
8659 void WIFI_Recv_Fragmented (void) {
8660   osThreadId_t worker;
8661   int32_t      rval;
8662   IO_TRANSFER  io;
8663   int32_t      sock;
8664
8665   if (station_init (1) == 0) {
8666     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8667     return;
8668   }
8669
8670   /* Create worker thread */
8671   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
8672   if (worker == NULL) {
8673     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8674     return;
8675   }
8676
8677   ARG_INIT();
8678
8679   /* Create stream socket */
8680   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8681   if (io.rc < 0) {
8682     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8683   } else {
8684     sock = io.rc;
8685
8686     /* Connect to stream server */
8687     io.sock = sock;
8688     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
8689     TH_ASSERT  (io.rc == 0);
8690
8691     /* Transfer 16-byte block(s) */
8692     ARG_TRANSFER (sock, 256, 16);
8693     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
8694     TH_ASSERT  (io.rc == 256);
8695
8696     /* Transfer 64-byte block(s) */
8697     ARG_TRANSFER (sock, 1024, 64);
8698     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
8699     TH_ASSERT  (io.rc == 1024);
8700
8701     /* Transfer 256-byte block(s) */
8702     ARG_TRANSFER (sock, 1280, 256);
8703     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
8704     TH_ASSERT  (io.rc == 1280);
8705
8706     /* Transfer 1024-byte block(s) */
8707     ARG_TRANSFER (sock, 2048, 1024);
8708     TH_EXECUTE (F_RECV_FRAG, WIFI_SOCKET_TIMEOUT_LONG);
8709     TH_ASSERT  (io.rc == 2048);
8710
8711     /* Close stream socket */
8712     io.sock = sock;
8713     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8714     TH_ASSERT (io.rc == 0);
8715
8716     osDelay (10);
8717   }
8718
8719   if (rval == 0) {
8720     station_uninit ();
8721   }
8722
8723   /* Terminate worker thread */
8724   osThreadTerminate (worker);
8725 }
8726
8727 /**
8728 \brief  Function: WIFI_Test_Speed
8729 \ingroup wifi_sock_op
8730 \details
8731 The test function \b WIFI_Test_Speed tests data transfer speed.
8732
8733 Stream socket test:
8734  - Create stream socket
8735  - Transfer for 4 seconds, send and receive
8736  - Calculate transfer rate
8737  - Close socket
8738
8739 Datagram socket test:
8740  - Create datagram socket
8741  - Transfer for 4 seconds, send and receive
8742  - Calculate transfer rate
8743  - Close socket
8744 */
8745 void WIFI_Test_Speed (void) {
8746   uint32_t     ticks,tout;
8747   osThreadId_t worker;
8748   int32_t      rval,n_bytes;
8749   IO_TRANSFER  io;
8750   int32_t      sock;
8751
8752   if (station_init (1) == 0) {
8753     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8754     return;
8755   }
8756
8757   /* Create worker thread */
8758   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
8759   if (worker == NULL) {
8760     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8761     return;
8762   }
8763
8764   ARG_INIT();
8765
8766   /* Create stream socket */
8767   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8768   if (io.rc < 0) {
8769     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8770   } else {
8771     sock = io.rc;
8772
8773     /* Connect to stream server */
8774     io.tcp  = 1;
8775     io.sock = sock;
8776     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
8777     TH_ASSERT  (io.rc == 0);
8778
8779     /* Transfer for 4 seconds */
8780     tout  = SYSTICK_MICROSEC(4000000);
8781     ticks = GET_SYSTICK();
8782     n_bytes = 0;
8783     do {
8784       ARG_TRANSFER (sock, 1420, 1420);
8785       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8786       if (io.rc > 0) n_bytes += io.rc;
8787       else           break;
8788     } while (GET_SYSTICK() - ticks < tout);
8789     /* Check transfer rate */
8790     if (n_bytes < 10000) {
8791       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
8792       TEST_MESSAGE(msg_buf);
8793     }
8794
8795     /* Close stream socket */
8796     io.sock = sock;
8797     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8798     TH_ASSERT  (io.rc == 0);
8799
8800     osDelay (10);
8801   }
8802
8803   /* Create datagram socket */
8804   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
8805   if (io.rc < 0) {
8806     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
8807   } else {
8808     sock = io.rc;
8809
8810     /* Connect to datagram server */
8811     io.tcp  = 0;
8812     io.sock = sock;
8813     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
8814     TH_ASSERT  (io.rc == 0);
8815
8816     /* Transfer for 4 seconds */
8817     tout  = SYSTICK_MICROSEC(4000000);
8818     ticks = GET_SYSTICK();
8819     n_bytes = 0;
8820     do {
8821       ARG_TRANSFER (sock, 1460, 1460);
8822       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8823       if (io.rc > 0) n_bytes += io.rc;
8824       else           break;
8825     } while (GET_SYSTICK() - ticks < tout);
8826     /* Check transfer rate */
8827     if (n_bytes < 10000) {
8828       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
8829       TEST_MESSAGE(msg_buf);
8830     }
8831
8832     /* Close datagram socket */
8833     io.sock = sock;
8834     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8835     TH_ASSERT  (io.rc == 0);
8836
8837     osDelay (10);
8838   }
8839
8840   if (rval == 0) {
8841     station_uninit ();
8842   }
8843
8844   /* Terminate worker thread */
8845   osThreadTerminate (worker);
8846 }
8847
8848 /* Sidekick IO parameters */
8849 #ifndef __DOXYGEN__                     // Exclude form the documentation
8850 typedef struct {
8851   int32_t  sock;
8852   uint32_t count;
8853 } IO_SIDEKICK;
8854 #endif
8855
8856 /* Concurrent coworker thread */
8857 __NO_RETURN static void Th_Sidekick (IO_SIDEKICK *io2) {
8858   uint8_t buff[48];
8859   int32_t rc;
8860
8861   for (;;) {
8862     if (osThreadFlagsWait (SK_TERMINATE, osFlagsWaitAny, 200) == SK_TERMINATE) {
8863       break;
8864     }
8865     memset ((void *)buff, 0xCC, sizeof(buff));
8866     rc = drv->SocketSend (io2->sock, test_msg, sizeof(test_msg));
8867     if (rc <= 0) break;
8868     rc = drv->SocketRecv (io2->sock, buff, sizeof(test_msg));
8869     if (rc <= 0) break;
8870     if (memcmp ((const void *)buff, (const void *)test_msg, sizeof(test_msg)) == 0) {
8871       io2->count += sizeof(test_msg);
8872     }
8873   }
8874   /* Owner deletes this thread */
8875   while (1) osDelay (osWaitForever);
8876 }
8877
8878 /**
8879 \brief  Function: WIFI_Concurrent_Socket
8880 \ingroup wifi_sock_op
8881 \details
8882 The test function \b WIFI_Concurrent_Socket verifies transfer of two concurrent sockets.
8883
8884 Stream socket test:
8885  - Create two stream sockets
8886  - Start transfer on 2nd socket with 200ms intervals
8887  - Transfer on main socket, full speed
8888  - Calculate transfer rate
8889  - Close sockets
8890
8891 Datagram socket test:
8892  - Create datagram and stream sockets
8893  - Start transfer on stream socket with 200ms intervals
8894  - Transfer on main socket, full speed
8895  - Calculate transfer rate
8896  - Close sockets
8897 \note
8898 The test runs with a coherent thread, that performs an additional stream socket io.
8899 */
8900 void WIFI_Concurrent_Socket (void) {
8901   uint32_t     ticks,tout;
8902   osThreadId_t worker,spawn;
8903   int32_t      rval,n_bytes;
8904   IO_TRANSFER  io;
8905   IO_SIDEKICK  io2;
8906   int32_t      sock;
8907
8908   if (station_init (1) == 0) {
8909     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
8910     return;
8911   }
8912
8913   /* Create worker thread */
8914   worker = osThreadNew ((osThreadFunc_t)Th_Transfer, &io, NULL);
8915   if (worker == NULL) {
8916     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
8917     return;
8918   }
8919
8920   ARG_INIT();
8921
8922   /* The test connects two stream sockets to the ECHO server and then    */
8923   /* performs simultaneous data transfer. The main socket transmits at   */
8924   /* full speed, and the other socket sends messages at 200ms intervals. */
8925   /* Both sockets record the number of bytes of data transferred, and    */
8926   /* the transfer rate is calculated.                                    */
8927
8928   /* Create stream socket */
8929   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8930   if (io.rc < 0) {
8931     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8932   } else {
8933     sock = io.rc;
8934
8935     /* Create 2nd stream socket */
8936     TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
8937     if (io.rc < 0) {
8938       TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
8939     }
8940     io2.sock  = io.rc;
8941     io2.count = 0;
8942
8943     /* Connect sockets */
8944     io.tcp  = 1;
8945     io.sock = sock;
8946     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
8947     TH_ASSERT  (io.rc == 0);
8948
8949     io.sock = io2.sock;
8950     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
8951     TH_ASSERT  (io.rc == 0);
8952
8953     /* Create spawned thread */
8954     spawn = osThreadNew ((osThreadFunc_t)Th_Sidekick, &io2, NULL);
8955     TEST_ASSERT(spawn != NULL);
8956
8957     /* Transfer for 4 seconds */
8958     tout  = SYSTICK_MICROSEC(4000000);
8959     ticks = GET_SYSTICK();
8960     n_bytes = 0;
8961     do {
8962       ARG_TRANSFER (sock, 1420, 1420);
8963       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
8964       if (io.rc > 0) n_bytes += io.rc;
8965       else           break;
8966     } while (GET_SYSTICK() - ticks < tout);
8967     /* Check main transfer rate */
8968     if (n_bytes < 10000) {
8969       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
8970       TEST_MESSAGE(msg_buf);
8971     }
8972     /* Check auxiliary transfer rate */
8973     if (io2.count == 0) {
8974       TEST_ASSERT_MESSAGE(0,"[FAILED] Auxiliary transfer failed");
8975     }
8976     else if (io2.count < 440) {
8977       TEST_MESSAGE("[WARNING] Auxiliary Transfer rate low");
8978     }
8979
8980     /* Terminate spawned thread */
8981     osThreadFlagsSet (spawn, SK_TERMINATE);
8982     osDelay(100);
8983     osThreadTerminate (spawn);
8984
8985     /* Close stream sockets */
8986     io.sock = io2.sock;
8987     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8988     TH_ASSERT  (io.rc == 0);
8989
8990     io.sock = sock;
8991     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
8992     TH_ASSERT  (io.rc == 0);
8993
8994     osDelay (10);
8995   }
8996
8997   /* The test connects datagram and stream sockets to the ECHO server     */
8998   /* and then performs simultaneous data transfer. The datagram socket    */
8999   /* transmits at full speed, and the stream socket sends messages at     */
9000   /* 200ms intervals. The number of bytes of transferred data is recorded */
9001   /* and the rate of transmission is calculated.                          */
9002
9003   /* Create datagram socket */
9004   TH_EXECUTE (F_CREATE_UDP, WIFI_SOCKET_TIMEOUT);
9005   if (io.rc < 0) {
9006     TEST_ASSERT_MESSAGE(0,"[FAILED] Datagram Socket not created");
9007   } else {
9008     sock = io.rc;
9009
9010     /* Connect datagram socket */
9011     io.tcp  = 0;
9012     io.sock = sock;
9013     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT);
9014     TH_ASSERT  (io.rc == 0);
9015
9016     /* Create stream socket */
9017     TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
9018     if (io.rc < 0) {
9019       TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
9020     }
9021     io2.sock  = io.rc;
9022     io2.count = 0;
9023
9024     /* Connect stream socket */
9025     io.sock = io2.sock;
9026     TH_EXECUTE (F_CONNECT, WIFI_SOCKET_TIMEOUT_LONG);
9027     TH_ASSERT  (io.rc == 0);
9028
9029     /* Create spawned thread */
9030     spawn = osThreadNew ((osThreadFunc_t)Th_Sidekick, &io2, NULL);
9031     TEST_ASSERT(spawn != NULL);
9032
9033     /* Transfer for 4 seconds */
9034     tout  = SYSTICK_MICROSEC(4000000);
9035     ticks = GET_SYSTICK();
9036     n_bytes = 0;
9037     do {
9038       ARG_TRANSFER (sock, 1460, 1460);
9039       TH_EXECUTE (F_XFER_FIXED, WIFI_SOCKET_TIMEOUT_LONG);
9040       if (io.rc > 0) n_bytes += io.rc;
9041       else           break;
9042     } while (GET_SYSTICK() - ticks < tout);
9043     /* Check main transfer rate */
9044     if (n_bytes < 10000) {
9045       snprintf(msg_buf, sizeof(msg_buf), "[WARNING] Slow Transfer rate (%d KB/s)", n_bytes / 2048);
9046       TEST_MESSAGE(msg_buf);
9047     }
9048     /* Check auxiliary transfer rate */
9049     if (io2.count == 0) {
9050       TEST_ASSERT_MESSAGE(0,"[FAILED] Auxiliary transfer failed");
9051     }
9052     else if (io2.count < 440) {
9053       TEST_MESSAGE("[WARNING] Auxiliary Transfer rate low");
9054     }
9055
9056     /* Terminate spawned thread */
9057     osThreadFlagsSet (spawn, SK_TERMINATE);
9058     osDelay(100);
9059     osThreadTerminate (spawn);
9060
9061     /* Close sockets */
9062     io.sock = io2.sock;
9063     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
9064     TH_ASSERT  (io.rc == 0);
9065
9066     io.sock = sock;
9067     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
9068     TH_ASSERT  (io.rc == 0);
9069
9070     osDelay (10);
9071   }
9072
9073   if (rval == 0) {
9074     station_uninit ();
9075   }
9076
9077   /* Terminate worker thread */
9078   osThreadTerminate (worker);
9079 }
9080
9081 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
9082
9083 /* TestAssistant commands */
9084 #define CMD_SEND_TCP        "SEND TCP,1420,4000"
9085 #define CMD_RECV_TCP        "RECV TCP,1420"
9086 #define TEST_BSIZE          1420
9087
9088 /* StreamRate IO parameters */
9089 #ifndef __DOXYGEN__                     // Exclude form the documentation
9090 typedef struct {
9091   int32_t      sock;
9092   int32_t      rc;
9093   /* Control */
9094   osThreadId_t owner;
9095   uint32_t     xid;
9096   int32_t      loss;
9097   const char  *cmd;
9098 } IO_STREAMRATE;
9099 #endif
9100
9101 /* StreamRate coworker thread */
9102 __NO_RETURN static void Th_StreamRate (IO_STREAMRATE *io) {
9103   uint32_t flags,xid,ticks,tout;
9104   int32_t  n,rc,i,val;
9105
9106   for (;;) {
9107     flags = osThreadFlagsWait (F_CREATE_TCP | F_DOWNLOAD | F_UPLOAD |
9108                                F_SEND_CTRL  | F_CLOSE, osFlagsWaitAny, osWaitForever);
9109     xid   = io->xid;
9110     switch (flags) {
9111       case F_CREATE_TCP:
9112         /* Create stream socket */
9113         io->rc = drv->SocketCreate (ARM_SOCKET_AF_INET, ARM_SOCKET_SOCK_STREAM, ARM_SOCKET_IPPROTO_TCP);
9114         break;
9115
9116       case F_DOWNLOAD:
9117         /* Downstream test, server is sender */
9118         for (n = 0; ; n += rc) {
9119           rc = drv->SocketRecv (io->sock, buffer, TEST_BSIZE);
9120           if (strncmp ((char *)buffer, "STAT", 4) == 0) {
9121             /* Server completed the test */
9122             sscanf ((char *)buffer+4, "%d", &val);
9123             if (val > n) io->loss = val - n;
9124             break;
9125           }
9126           if (rc <= 0) break;
9127         }
9128         io->rc = n;
9129         break;
9130
9131       case F_UPLOAD:
9132         /* Upstream test, server is receiver */
9133         memset ((void *)buffer, 'a', TEST_BSIZE);
9134         tout  = SYSTICK_MICROSEC(4000000);
9135         ticks = GET_SYSTICK();
9136         i = n = 0;
9137         do {
9138           snprintf ((char *)buffer, sizeof(buffer), "Block[%d]", ++i);
9139           rc = drv->SocketSend (io->sock, buffer, TEST_BSIZE);
9140           if (rc > 0) n += rc;
9141         } while (GET_SYSTICK() - ticks < tout);
9142         rc = snprintf ((char *)buffer, sizeof(buffer), "STOP %d bytes.", n);
9143         drv->SocketSend (io->sock, buffer, (uint32_t)rc);
9144         /* Receive report from server */
9145         drv->SocketRecv (io->sock, buffer, TEST_BSIZE);
9146         if (strncmp ((char *)buffer, "STAT", 4) == 0) {
9147           sscanf ((char *)buffer+4, "%d", &val);
9148           if (n > val) io->loss = n - val;
9149         }
9150         io->rc = n;
9151         break;
9152
9153       case F_CLOSE:
9154         /* Close socket */
9155         io->rc = drv->SocketClose (io->sock);
9156         break;
9157
9158       case F_SEND_CTRL:
9159         /* Send control command to TestAssistant */
9160         drv->SocketConnect (io->sock, ip_socket_server, 4, ASSISTANT_PORT);
9161         io->rc = drv->SocketSend (io->sock, io->cmd, strlen(io->cmd));
9162         break;
9163     }
9164     /* Done, send signal to owner thread */
9165     flags = (xid == io->xid) ? TH_OK : TH_TOUT;
9166     osDelay(1);
9167     osThreadFlagsSet (io->owner, flags);
9168     osThreadFlagsClear (F_ALL);
9169   }
9170 }
9171
9172 /**
9173 \brief  Function: WIFI_Downstream_Rate
9174 \ingroup wifi_sock_op
9175 \details
9176 The test function \b WIFI_Downstream_Rate tests the maximum rate at which the data
9177 can be received.
9178 */
9179 void WIFI_Downstream_Rate (void) {
9180   osThreadId_t  worker;
9181   int32_t       rval;
9182   IO_STREAMRATE io;
9183
9184   if (station_init (1) == 0) {
9185     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
9186     return;
9187   }
9188
9189   /* Create worker thread */
9190   worker = osThreadNew ((osThreadFunc_t)Th_StreamRate, &io, NULL);
9191   if (worker == NULL) {
9192     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
9193     return;
9194   }
9195
9196   ARG_INIT();
9197
9198   /* Create stream socket */
9199   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
9200   if (io.rc < 0) {
9201     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
9202   } else {
9203     io.sock = io.rc;
9204
9205     /* Send command to start the download */
9206     io.cmd = CMD_SEND_TCP;
9207     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
9208     TH_ASSERT  (io.rc > 0);
9209
9210     /* Wait for transfer to complete */
9211     io.loss = 0;
9212     TH_EXECUTE (F_DOWNLOAD, 5000 + WIFI_SOCKET_TIMEOUT);
9213     TH_ASSERT  (io.rc > 0);
9214
9215     /* Check data loss */
9216     if (io.loss) {
9217       snprintf(msg_buf, sizeof(msg_buf), "[FAILED] Data loss %d byte(s)", io.loss);
9218       TEST_ASSERT_MESSAGE(0,msg_buf);
9219     }
9220     else if (rval != 0) {
9221       snprintf(msg_buf, sizeof(msg_buf), "[INFO] Speed %d KB/s", io.rc/4096);
9222       TEST_MESSAGE(msg_buf);
9223     }
9224
9225     /* Close stream socket */
9226     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
9227     TH_ASSERT  (io.rc == 0);
9228
9229     osDelay (10);
9230   }
9231
9232   if (rval == 0) {
9233     station_uninit ();
9234   }
9235
9236   /* Terminate worker thread */
9237   osThreadTerminate (worker);
9238 }
9239
9240 /**
9241 \brief  Function: WIFI_Upstream_Rate
9242 \ingroup wifi_sock_op
9243 \details
9244 The test function \b WIFI_Upstream_Rate tests the maximum rate at which the data
9245 can be sent.
9246 */
9247 void WIFI_Upstream_Rate (void) {
9248   osThreadId_t  worker;
9249   int32_t       rval;
9250   IO_STREAMRATE io;
9251
9252   if (station_init (1) == 0) {
9253     TEST_ASSERT_MESSAGE(0,"[FAILED] Station initialization and connect failed");
9254     return;
9255   }
9256
9257   /* Create worker thread */
9258   worker = osThreadNew ((osThreadFunc_t)Th_StreamRate, &io, NULL);
9259   if (worker == NULL) {
9260     TEST_ASSERT_MESSAGE(0,"[FAILED] Worker Thread not created");
9261     return;
9262   }
9263
9264   ARG_INIT();
9265
9266   /* Create stream socket */
9267   TH_EXECUTE (F_CREATE_TCP, WIFI_SOCKET_TIMEOUT);
9268   if (io.rc < 0) {
9269     TEST_ASSERT_MESSAGE(0,"[FAILED] Stream Socket not created");
9270   } else {
9271     io.sock = io.rc;
9272
9273     /* Send command to start the upload */
9274     io.cmd = CMD_RECV_TCP;
9275     TH_EXECUTE (F_SEND_CTRL, WIFI_SOCKET_TIMEOUT_LONG);
9276     TH_ASSERT  (io.rc > 0);
9277
9278     /* Wait for transfer to complete */
9279     io.loss = 0;
9280     TH_EXECUTE (F_UPLOAD, 5000 + WIFI_SOCKET_TIMEOUT);
9281     TH_ASSERT  (io.rc > 0);
9282
9283     /* Check data loss */
9284     if (io.loss) {
9285       snprintf(msg_buf, sizeof(msg_buf), "[FAILED] Data loss %d byte(s)", io.loss);
9286       TEST_ASSERT_MESSAGE(0,msg_buf);
9287     }
9288     else if (rval != 0) {
9289       snprintf(msg_buf, sizeof(msg_buf), "[INFO] Speed %d KB/s", io.rc/4096);
9290       TEST_MESSAGE(msg_buf);
9291     }
9292
9293     /* Close stream socket */
9294     TH_EXECUTE (F_CLOSE, WIFI_SOCKET_TIMEOUT);
9295     TH_ASSERT  (io.rc == 0);
9296
9297     osDelay (10);
9298   }
9299
9300   if (rval == 0) {
9301     station_uninit ();
9302   }
9303
9304   /* Terminate worker thread */
9305   osThreadTerminate (worker);
9306 }