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