Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FXAS21002 FXOS8700Q
pal_socket_test.c
00001 /******************************************************************************* 00002 * Copyright 2016, 2017 ARM Ltd. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 *******************************************************************************/ 00016 00017 #include "pal.h" 00018 #include "pal_network.h" 00019 #include "unity.h" 00020 #include "unity_fixture.h" 00021 #include "test_runners.h" 00022 00023 #include <string.h> 00024 00025 // config file for keepalive server 00026 #include "pal_socket_test_address.h" 00027 00028 #ifdef __LINUX__ 00029 #include <netdb.h> 00030 #define test_getAddressInfo getAddressInfoIPv4 00031 #else 00032 #define test_getAddressInfo pal_getAddressInfo 00033 #endif 00034 00035 TEST_GROUP(pal_socket); 00036 00037 #define TRACE_GROUP "PAL" 00038 00039 //Sometimes you may want to get local data in a module, 00040 //for example if you need to pass a reference. 00041 //However, you should usually avoid this. 00042 //extern int Counter; 00043 00044 #define PAL_NET_SUPPORT_LWIP 1 00045 #define PAL_NET_TEST_SERVER_NAME "www.arm.com" 00046 #define PAL_NET_TEST_SERVER_NAME_UDP "8.8.8.8" 00047 00048 00049 #define PAL_NET_TEST_SERVER_HTTP_PORT 80 00050 00051 #define PAL_NET_TEST_SERVER_UDP_PORT 53 00052 #define PAL_NET_TEST_INCOMING_PORT 8002 00053 #define PAL_NET_TEST_INCOMING_PORT2 8989 00054 00055 #define PAL_NET_TEST_LOCAL_LOOPBACK_IF_INDEX 0 00056 extern void * g_palTestNetworkInterface; // this is set by the palTestMain function 00057 PAL_PRIVATE uint32_t g_interfaceCTXIndex = 0; 00058 PAL_PRIVATE uint32_t s_callbackcounter = 0; 00059 00060 #define PAL_NET_TEST_SOCKETS 4 00061 PAL_PRIVATE palSocket_t g_testSockets[PAL_NET_TEST_SOCKETS] = {0,0,0,0}; 00062 00063 #define PAL_NET_TEST_GOOGLE_CDN_HOST "ajax.googleapis.com" /*! CDN host server */ 00064 #define PAL_NET_TEST_GOOGLE_CDN_HOST_PORT 80 /*! CDN host port */ 00065 #define PAL_NET_TEST_GOOGLE_CDN_REQUEST "GET /ajax/libs/jquery/3.2.1/jquery.js HTTP/1.0\r\nHost:" PAL_NET_TEST_GOOGLE_CDN_HOST "\r\n\r\n" /*! HTTP get request */ 00066 #define PAL_NET_TEST_BUFFERED_TCP_BUF_SIZE_SMALL 4 00067 #define PAL_NET_TEST_BUFFERED_TCP_BUF_SIZE_LARGE 1024 00068 #define PAL_NET_TEST_BUFFERED_UDP_BUF_SIZE_SMALL 64 00069 #define PAL_NET_TEST_BUFFERED_UDP_BUF_SIZE_LARGE 512 00070 #define PAL_NET_TEST_BUFFERED_UDP_PORT 2606 00071 #define PAL_NET_TEST_BUFFERED_UDP_MESSAGE_SIZE (1024 * 256) 00072 PAL_PRIVATE uint8_t *g_testRecvBuffer = NULLPTR; 00073 PAL_PRIVATE uint8_t *g_testSendBuffer = NULLPTR; 00074 00075 #define PAL_NET_TEST_ECHO_TEST_SERVER_ADDRESS "echo.mbedcloudtesting.com" 00076 00077 // the tests expect to have guaranteed forward progress, even if they fail. So the semaphore 00078 // wait time is set to some arbitrary time, which is likely "long enough" to work even on system high load. 00079 // But if one tries to debug the code under test, the test code will timeout too soon. So if a 00080 // runtime debugger is used, just set this define to PAL_RTOS_WAIT_FOREVER 00081 #define TEST_SEMAPHORE_WAIT 10000 00082 00083 00084 #if defined(__SXOS__) 00085 // SX OS Does not support PAL_SO_RCVTIMEO or PAL_SO_SNDTIMEO 00086 #define PAL_SO_RCVTIMEO_EXPECTED_RESULT PAL_ERR_SOCKET_OPTION_NOT_SUPPORTED 00087 #define PAL_SO_SNDTIMEO_EXPECTED_RESULT PAL_ERR_SOCKET_OPTION_NOT_SUPPORTED 00088 #else 00089 #define PAL_SO_RCVTIMEO_EXPECTED_RESULT PAL_SUCCESS 00090 #define PAL_SO_SNDTIMEO_EXPECTED_RESULT PAL_SUCCESS 00091 #endif 00092 00093 00094 typedef struct pal_udp_test_data /*! structure used to hold state in UDP buffered tests */ 00095 { 00096 const size_t messageSize; 00097 const size_t bufferSize; 00098 const uint8_t startValue; 00099 palNetInterfaceInfo_t interfaceInfo; 00100 uint8_t currentValue; 00101 size_t totalSize; 00102 size_t chunkSize; 00103 } pal_udp_test_data_t; 00104 00105 TEST_SETUP(pal_socket) 00106 { 00107 uint32_t i = 0; 00108 palStatus_t status; 00109 //This is run before *each test* 00110 status = pal_init(); 00111 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00112 if ( NULL == g_palTestNetworkInterface ) 00113 { 00114 PAL_LOG_ERR("error: net interface not configured correctly"); 00115 } 00116 else 00117 { 00118 status = pal_registerNetworkInterface(g_palTestNetworkInterface, &g_interfaceCTXIndex); 00119 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00120 } 00121 00122 for (i = 0; i < PAL_NET_TEST_SOCKETS; i++) 00123 { 00124 g_testSockets[i] = 0; 00125 } 00126 } 00127 00128 TEST_TEAR_DOWN(pal_socket) 00129 { 00130 uint32_t i = 0; 00131 for (i = 0; i < PAL_NET_TEST_SOCKETS; i++) 00132 { 00133 if (g_testSockets[i] != 0) 00134 { 00135 pal_close(&(g_testSockets[i])); 00136 } 00137 } 00138 00139 if (g_testRecvBuffer != NULLPTR) 00140 { 00141 free(g_testRecvBuffer); 00142 g_testRecvBuffer = NULLPTR; 00143 } 00144 if (g_testSendBuffer != NULLPTR) 00145 { 00146 free(g_testSendBuffer); 00147 g_testSendBuffer = NULLPTR; 00148 } 00149 00150 pal_destroy(); 00151 } 00152 00153 #define PAL_TEST_BUFFER_SIZE 50 00154 PAL_PRIVATE void socketCallback1( void * arg) 00155 { 00156 s_callbackcounter++; 00157 } 00158 00159 /*! \brief Test socket creation, destruction and modification, as well as getting address infromation and checking the blocking status of sockets. 00160 * 00161 ** \test 00162 * | # | Step | Expected | 00163 * |---|----------------------------------------------------------------------------------- |-------------| 00164 * | 1 | Register a net interface using `pal_registerNetworkInterface`. | PAL_SUCCESS | 00165 * | 2 | Register a net interface using `pal_registerNetworkInterface`, | PAL_SUCCESS | 00166 * and check that the ID is the same as the previous step. 00167 * | 3 | Unregister a net interface using `pal_unregisterNetworkInterface`. | PAL_SUCCESS | 00168 * | 4 | Get the interface address using `pal_getNetInterfaceInfo`. | PAL_SUCCESS | 00169 * | 5 | Create a blocking UDP socket using `pal_socket`. | PAL_SUCCESS | 00170 * | 6 | Create a blocking UDP socket using `pal_socket`. | PAL_SUCCESS | 00171 * | 7 | Create a non-blocking UDP socket using `pal_socket`. | PAL_SUCCESS | 00172 * | 8 | Create a blocking asynchronous TCP socket with `socketCallback1` as callback. | PAL_SUCCESS | 00173 * | 9 | Check the number of net interfaces registered using `pal_getNetInterfaceInfo`. | PAL_SUCCESS | 00174 * | 10 | Set the socket receive timeout using `pal_setSocketOptions`. | PAL_SUCCESS | 00175 * | 11 | Check that the sockets return the correct blocking status using `pal_isNonBlocking`. | PAL_SUCCESS | 00176 * | 12 | Check the `pal_getAddressInfo` function with an invalid address. | PAL_ERR_SOCKET_DNS_ERROR | 00177 * | 13 | Close all sockets. | PAL_SUCCESS | 00178 */ 00179 TEST(pal_socket, socketUDPCreationOptionsTest) 00180 { 00181 #ifdef TARGET_LIKE_MBED 00182 // TODO: fix with https://jira.arm.com/browse/IOTCLT-3197 00183 TEST_IGNORE_MESSAGE("Ignored, IOTCLT-3197, Expected 2 Was 3"); 00184 #endif 00185 #if !defined(TARGET_LIKE_MBED) && !defined(DEBUG) 00186 // Non mbed and release mode 00187 // Linux socketUDPCreationOptionsTest fails on release mode 00188 // https://jira.arm.com/browse/IOTCLT-3241 00189 TEST_IGNORE_MESSAGE("Ignored, IOTCLT-3241, pal_socket_test.c:255: Expected 0 Was 1"); 00190 #endif 00191 palStatus_t result = PAL_SUCCESS; 00192 uint32_t numInterface = 0; 00193 palNetInterfaceInfo_t interfaceInfo; 00194 uint32_t interfaceIndex = 0; 00195 uint32_t interfaceIndex2 = 0; 00196 uint32_t sockOptVal = 5000; 00197 uint32_t sockOptLen = sizeof(sockOptVal); 00198 palSocketAddress_t address = { 0 }; 00199 palSocketLength_t addrlen = 0; 00200 bool isNonBlocking = false; 00201 00202 memset(&interfaceInfo,0,sizeof(interfaceInfo)); 00203 00204 /*#1*/ 00205 result = pal_registerNetworkInterface(g_palTestNetworkInterface, &interfaceIndex); 00206 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00207 00208 char iface[5]; 00209 for (int i = 1; i < PAL_MAX_SUPORTED_NET_INTERFACES; i++) { 00210 sprintf(iface, "%d", i); 00211 result = pal_registerNetworkInterface((void*)iface, &interfaceIndex); 00212 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00213 result = pal_getNumberOfNetInterfaces(&numInterface); 00214 TEST_ASSERT_EQUAL(numInterface, i + 1); 00215 } 00216 00217 // Array full 00218 result = pal_registerNetworkInterface((void*)"10", &interfaceIndex); 00219 TEST_ASSERT_EQUAL_HEX(PAL_ERR_SOCKET_MAX_NUMBER_OF_INTERFACES_REACHED , result); 00220 00221 // Check that re-adding the network interface returns the same index, 00222 // which in this case is the first item in the list 00223 /*#2*/ 00224 result = pal_registerNetworkInterface(g_palTestNetworkInterface, &interfaceIndex2); 00225 TEST_ASSERT_EQUAL_HEX(0, interfaceIndex2); 00226 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00227 00228 // Remove interfaces from the list, keep the first item since it required in other tests 00229 /*#3*/ 00230 for (int i = 1; i < PAL_MAX_SUPORTED_NET_INTERFACES; i++) { 00231 pal_unregisterNetworkInterface(i); 00232 pal_getNumberOfNetInterfaces(&numInterface); 00233 TEST_ASSERT_EQUAL(numInterface, PAL_MAX_SUPORTED_NET_INTERFACES - i); 00234 } 00235 00236 // Interface index out of range 00237 pal_unregisterNetworkInterface(11); 00238 00239 // Set index back to default one 00240 interfaceIndex = 0; 00241 00242 #if PAL_SUPPORT_IP_V4 00243 /*#4*/ 00244 result = pal_getNetInterfaceInfo(interfaceIndex, &interfaceInfo); 00245 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00246 PAL_PRINTF("Default interface address: %u %u %u %u \r\n", 00247 (unsigned char)interfaceInfo.address.addressData[2], 00248 (unsigned char)interfaceInfo.address.addressData[3], 00249 (unsigned char)interfaceInfo.address.addressData[4], 00250 (unsigned char)interfaceInfo.address.addressData[5]);; 00251 #endif 00252 00253 //Blocking 00254 /*#5*/ 00255 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM, false, interfaceIndex, &g_testSockets[0]); 00256 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00257 /*#6*/ 00258 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM, false, interfaceIndex, &g_testSockets[1]); 00259 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00260 //Non-blocking 00261 /*#7*/ 00262 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM, true, interfaceIndex, &g_testSockets[3]); 00263 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00264 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 00265 /*#8*/ 00266 result = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, false, interfaceIndex, socketCallback1, &g_testSockets[2]); 00267 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00268 #endif // PAL_NET_ASYNCHRONOUS_SOCKET_API 00269 00270 /*#9*/ 00271 result = pal_getNumberOfNetInterfaces(&numInterface); 00272 TEST_ASSERT_EQUAL(numInterface, 1); 00273 00274 /*#10*/ 00275 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO, &sockOptVal, sockOptLen); 00276 TEST_ASSERT_EQUAL_HEX(PAL_SO_RCVTIMEO_EXPECTED_RESULT, result); 00277 00278 /*#11*/ 00279 result = pal_isNonBlocking(g_testSockets[0],&isNonBlocking); 00280 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00281 TEST_ASSERT_EQUAL_HEX(isNonBlocking, false); 00282 00283 result = pal_isNonBlocking(g_testSockets[3], &isNonBlocking); 00284 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00285 TEST_ASSERT_EQUAL_HEX(isNonBlocking, true); 00286 00287 /*#12*/ 00288 result = pal_getAddressInfo("0.0.0.0", &address, &addrlen); 00289 TEST_ASSERT_EQUAL_HEX(PAL_ERR_SOCKET_DNS_ERROR , result); 00290 00291 /*#13*/ 00292 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 00293 result = pal_close(&g_testSockets[2]); 00294 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00295 00296 #endif // PAL_NET_ASYNCHRONOUS_SOCKET_API 00297 00298 result = pal_close(&g_testSockets[0]); 00299 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00300 result = pal_close(&g_testSockets[1]); 00301 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00302 result = pal_close(&g_testSockets[3]); 00303 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00304 result = pal_close(&g_testSockets[3]); //double close - should succeed 00305 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00306 } 00307 00308 00309 /*! \brief Test TCP socket creation, connection, send and receive with a test server. 00310 * 00311 ** \test 00312 * | # | Step | Expected | 00313 * |---|--------------------------------|-------------| 00314 * | 1 | Create a blocking TCP socket using `pal_socket`. | PAL_SUCCESS | 00315 * | 2 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 00316 * | 3 | Set the port to a test port in the address structure using `pal_setSockAddrPort` and set timeout. | PAL_SUCCESS | 00317 * | 4 | Connect the socket to the test server using `pal_connect`. | PAL_SUCCESS | 00318 * | 5 | Send a test message (short HTTP request) to the test server using `pal_send`. | PAL_SUCCESS | 00319 * | 6 | Receive (blocking) the server's response using `pal_recv` and check it is HTTP. | PAL_SUCCESS | 00320 * | 7 | Close the socket. | PAL_SUCCESS | 00321 */ 00322 TEST(pal_socket, basicTCPclientSendRecieve) 00323 { 00324 palStatus_t result = PAL_SUCCESS; 00325 palSocketAddress_t address = { 0 }; 00326 const char message[] = "GET / HTTP/1.0\r\n\r\n"; 00327 size_t sent = 0; 00328 char buffer[100] = { 0 }; 00329 size_t read = 0; 00330 palSocketLength_t addrlen = 0; 00331 int timeout = PAL_MILLI_PER_SECOND; 00332 00333 /*#1*/ 00334 00335 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, &g_testSockets[0]); 00336 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00337 00338 /*#2*/ 00339 result = pal_getAddressInfo(PAL_NET_TEST_SERVER_NAME, &address, &addrlen); 00340 if ((PAL_ERR_SOCKET_DNS_ERROR == result) || (PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY == result)) 00341 { 00342 PAL_LOG_ERR("error: address lookup returned an address not supported by current configuration cant continue test ( IPv6 add for IPv4 only configuration or IPv4 for IPv6 only configuration)"); 00343 goto end; 00344 } 00345 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00346 00347 /*#3*/ 00348 result = pal_setSockAddrPort(&address, PAL_NET_TEST_SERVER_HTTP_PORT); 00349 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00350 00351 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_SNDTIMEO, &timeout, sizeof(timeout)); 00352 TEST_ASSERT_EQUAL_HEX(PAL_SO_SNDTIMEO_EXPECTED_RESULT, result); 00353 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO, &timeout, sizeof(timeout)); 00354 TEST_ASSERT_EQUAL_HEX(PAL_SO_RCVTIMEO_EXPECTED_RESULT, result); 00355 00356 00357 /*#4*/ 00358 result = pal_connect(g_testSockets[0], &address, 16); 00359 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00360 00361 /*#5*/ 00362 result = pal_send(g_testSockets[0], message, sizeof(message) - 1, &sent); 00363 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00364 00365 /*#6*/ 00366 result = pal_recv(g_testSockets[0], buffer, 99, &read); 00367 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00368 00369 TEST_ASSERT(read >= 4); 00370 TEST_ASSERT(buffer[0] == 'H' && buffer[1] == 'T'&& buffer[2] == 'T' && buffer[3] == 'P'); 00371 00372 end: //unified cleanup 00373 /*#7*/ 00374 pal_close(&g_testSockets[0]); 00375 00376 } 00377 00378 /*! \brief Test UDP socket creation, connection, send and recieve with a test server. 00379 * 00380 ** \test 00381 * | # | Step | Expected | 00382 * |---|--------------------------------|-------------| 00383 * | 1 | Create a blocking UDP socket using `pal_socket`. | PAL_SUCCESS | 00384 * | 2 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 00385 * | 3 | Set the port to a test port in the address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 00386 * | 4 | Connect the socket to the test server using `pal_connect`. | PAL_SUCCESS | 00387 * | 5 | Send a test message (short DNS request) to the test server using `pal_send`. | PAL_SUCCESS | 00388 * | 6 | Receive (blocking) the server's response using `pal_recv`. | PAL_SUCCESS | 00389 * | 7 | Close the socket. | PAL_SUCCESS | 00390 */ 00391 TEST(pal_socket, basicUDPclientSendRecieve) 00392 { 00393 palStatus_t result = PAL_SUCCESS; 00394 palSocketAddress_t address = { 0 }; 00395 palSocketAddress_t address2 = { 0 }; 00396 uint8_t buffer[33] = { 0x8e, 0xde, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x61, 0x72, 0x73, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x69, 0x63, 0x61, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01 }; 00397 uint8_t buffer_in[10]; 00398 size_t sent = 0; 00399 size_t read = 0; 00400 size_t socket_timeout_ms = 5000; 00401 palSocketLength_t addrlen = 0; 00402 00403 /*#1*/ 00404 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM, false, 0, &g_testSockets[0]); 00405 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00406 00407 /*#2*/ 00408 result = pal_getAddressInfo(PAL_NET_TEST_SERVER_NAME_UDP, &address, &addrlen); 00409 if ((PAL_ERR_SOCKET_DNS_ERROR == result) || (PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY == result)) 00410 { 00411 PAL_LOG_ERR("error: address lookup returned an address not supported by current configuration can't continue test ( IPv6 add for IPv4 only configuration or IPv4 for IPv6 only configuration)"); 00412 goto end; 00413 } 00414 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00415 00416 /*#3*/ 00417 result = pal_setSockAddrPort(&address, PAL_NET_TEST_SERVER_UDP_PORT); 00418 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00419 00420 /*#4*/ 00421 //We set a timeout for receiving so we won't get stuck in the test 00422 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO, &socket_timeout_ms, sizeof(socket_timeout_ms)); 00423 TEST_ASSERT_EQUAL_HEX(PAL_SO_RCVTIMEO_EXPECTED_RESULT, result); 00424 00425 /*#5*/ 00426 result = pal_sendTo(g_testSockets[0], buffer, sizeof(buffer), &address, 16, &sent); 00427 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00428 TEST_ASSERT_EQUAL(sent, sizeof(buffer)); 00429 00430 /*#6*/ 00431 result = pal_receiveFrom(g_testSockets[0], buffer_in, 10, &address2, &addrlen, &read); 00432 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00433 TEST_ASSERT_EQUAL(read, 10); 00434 end: 00435 /*#7*/ 00436 pal_close(&g_testSockets[0]); 00437 } 00438 00439 00440 00441 00442 // This is an example showing how to check for a socket that has been closed remotely. 00443 #if 0 00444 PAL_PRIVATE void basicSocketScenario3Callback(void * arg) 00445 { 00446 char buffer[400]; 00447 size_t read = 0; 00448 palStatus_t result; 00449 00450 00451 s_callbackcounter++; 00452 result = pal_recv(g_testSockets[0], buffer, 999, &read); 00453 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00454 // If 0 bytes are read it means that the peer has performed an orderly shutdown so we must close the socket 00455 // to avoid ppoll from checking it. Checking a socket whose other end has been shut down causes ppoll to immediately return 00456 // with events == 0x1. 00457 if(read == 0) 00458 { 00459 pal_close(&g_testSockets[0]); 00460 } 00461 else 00462 { 00463 buffer[read] = '\0'; 00464 if(s_callbackcounter == 0) 00465 { 00466 TEST_ASSERT(read >= 4); 00467 TEST_ASSERT(buffer[0] == 'H' && buffer[1] == 'T'&& buffer[2] == 'T' && buffer[3] == 'P'); 00468 } 00469 } 00470 00471 } 00472 #endif 00473 static palSemaphoreID_t s_semaphoreID = NULLPTR; 00474 00475 PAL_PRIVATE void socketCallback2(void * arg) 00476 { 00477 palStatus_t result; 00478 if(s_callbackcounter == 0) 00479 { 00480 result = pal_osSemaphoreRelease(s_semaphoreID); 00481 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00482 } 00483 s_callbackcounter++; 00484 00485 } 00486 00487 static int s_secondCallbackCounter = 0; 00488 PAL_PRIVATE void socketCallbackErr(void * arg) 00489 { 00490 s_secondCallbackCounter++; 00491 } 00492 00493 /*! \brief Test asynchronous socket callbacks. 00494 * 00495 ** \test 00496 * | # | Step | Expected | 00497 * |---|--------------------------------|-------------| 00498 * | 1 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 00499 * | 2 | Create a blocking asynchronous TCP socket with `socketCallback2` as callback. | PAL_SUCCESS | 00500 * | 3 | Set port to a test port in the address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 00501 * | 4 | Connect the socket to the test server using `pal_connect`. | PAL_SUCCESS | 00502 * | 5 | Send a test message (short HTTP request) to the test server using `pal_send`. | PAL_SUCCESS | 00503 * | 6 | Wait for a callback to release the semaphore when the response arrives. | PAL_SUCCESS | 00504 * | 7 | Receive (blocking) the server's response using `pal_recv` and check that the response is HTTP.| PAL_SUCCESS | 00505 * | 8 | Close the socket. | PAL_SUCCESS | 00506 */ 00507 TEST(pal_socket, basicSocketScenario3) 00508 { 00509 palStatus_t result = PAL_SUCCESS; 00510 palSocketAddress_t address = { 0 }; 00511 const char* message = "GET / HTTP/1.0\r\nHost:10.45.48.68:8000\r\n\r\n"; 00512 size_t sent = 0; 00513 char buffer[100] = { 0 }; 00514 size_t read = 0; 00515 s_callbackcounter = 0; 00516 palSocketLength_t addrlen = 0; 00517 int32_t countersAvailable; 00518 00519 result = pal_osSemaphoreCreate(1, &s_semaphoreID); 00520 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00521 result = pal_osSemaphoreWait(s_semaphoreID, 40000, &countersAvailable); 00522 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00523 00524 /*#1*/ 00525 result = pal_getAddressInfo(PAL_NET_TEST_SERVER_NAME, &address, &addrlen); 00526 if ((PAL_ERR_SOCKET_DNS_ERROR == result) || (PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY == result)) 00527 { 00528 PAL_LOG_ERR("error: address lookup returned an address not supported by current configuration cant continue test ( IPv6 add for IPv4 only configuration or IPv4 for IPv6 only configuration)"); 00529 return; 00530 } 00531 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00532 00533 00534 00535 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 00536 /*#2*/ 00537 result = pal_asynchronousSocketWithArgument(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, socketCallback2, "socketCallback2Arg", &g_testSockets[0]); 00538 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00539 00540 s_secondCallbackCounter = 0; 00541 result = pal_asynchronousSocketWithArgument(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, socketCallbackErr, "socketCallback2Arg", &g_testSockets[1]); 00542 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00543 00544 TEST_ASSERT_EQUAL_HEX(0, s_secondCallbackCounter); 00545 /*#3*/ 00546 result = pal_setSockAddrPort(&address, PAL_NET_TEST_SERVER_HTTP_PORT); 00547 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00548 00549 /*#4*/ 00550 result = pal_connect(g_testSockets[0], &address, 16); 00551 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00552 00553 TEST_ASSERT_EQUAL_HEX(0, s_secondCallbackCounter); 00554 /*#5*/ 00555 result = pal_send(g_testSockets[0], message, strlen(message), &sent); 00556 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00557 00558 TEST_ASSERT_EQUAL_HEX(0, s_secondCallbackCounter); 00559 // Give a chance for the callback to be called. 00560 /*#6*/ 00561 result=pal_osSemaphoreWait(s_semaphoreID, 40000, &countersAvailable); 00562 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00563 00564 result=pal_osSemaphoreDelete(&s_semaphoreID); 00565 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00566 00567 /*#7*/ 00568 result = pal_recv(g_testSockets[0], buffer, 99, &read); 00569 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00570 TEST_ASSERT(read >= 4); 00571 TEST_ASSERT(buffer[0] == 'H' && buffer[1] == 'T'&& buffer[2] == 'T' && buffer[3] == 'P'); 00572 TEST_ASSERT(s_callbackcounter > 0); 00573 00574 00575 TEST_ASSERT_EQUAL_HEX(0, s_secondCallbackCounter); 00576 /*#8*/ 00577 pal_close(&g_testSockets[0]); 00578 #endif // PAL_NET_ASYNCHRONOUS_SOCKET_API 00579 } 00580 00581 00582 00583 00584 typedef struct palNetTestThreadData{ 00585 palSemaphoreID_t sem1; 00586 palSemaphoreID_t sem2; 00587 uint16_t port; 00588 } palNetTestThreadData_t; 00589 00590 char s_rcv_buffer[20] = {0}; 00591 char s_rcv_buffer2[50] = {0}; 00592 00593 void palNetClientFunc(void const *argument) 00594 { 00595 palStatus_t result = PAL_SUCCESS; 00596 int32_t tmp = 0; 00597 size_t sent = 0; 00598 size_t read = 0; 00599 00600 palNetTestThreadData_t* dualSem = (palNetTestThreadData_t*)argument; 00601 TEST_ASSERT_NOT_NULL(dualSem); 00602 00603 palSocketLength_t addrlen = 16; 00604 //palSocketAddress_t address = { 0 }; 00605 palNetInterfaceInfo_t interfaceInfo; 00606 const char* message = "GET / HTTP/1.0\r\n\r\n"; 00607 00608 /*#C1*/ 00609 result = pal_osSemaphoreWait(dualSem->sem1, TEST_SEMAPHORE_WAIT, &tmp); 00610 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00611 00612 /*#C2*/ 00613 result = pal_getNetInterfaceInfo(PAL_NET_TEST_LOCAL_LOOPBACK_IF_INDEX, &interfaceInfo); 00614 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00615 00616 /*#C3*/ 00617 uint16_t incoming_port = dualSem->port; 00618 PAL_PRINTF("client port = %u", incoming_port); 00619 result = pal_setSockAddrPort(&(interfaceInfo.address), incoming_port); 00620 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00621 00622 /*#C4*/ 00623 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, &g_testSockets[2]); 00624 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00625 00626 /*#C5*/ 00627 result = pal_connect(g_testSockets[2], &(interfaceInfo.address), addrlen); 00628 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00629 00630 /*#C6*/ 00631 result = pal_send(g_testSockets[2], message, 18, &sent); 00632 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00633 00634 /*#C7*/ 00635 result = pal_recv(g_testSockets[2], s_rcv_buffer, 15, &read); 00636 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00637 00638 /*#C8*/ 00639 pal_close(&g_testSockets[2]); 00640 00641 result = pal_osSemaphoreRelease(dualSem->sem2); 00642 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00643 } 00644 00645 /*! \brief /b ServerSocketScenario tests a TCP client-server scenario using device loopback. 00646 * 00647 * \note In mbed-os lwip loopback feature must be enabled to make test working. 00648 * This can be done by enabling LWIP_NETIF_LOOPBACK flag. 00649 * The sequence below is an approximation of the actual order of execution. 00650 * \note The test steps are divided into those in the server main thread (S1..S13) and those in the client thread (C1..C8). 00651 * The sequence below is an approximation of the actual order of execution. 00652 * 00653 ** \test 00654 * | # | Step | Expected | 00655 * |---|--------------------------------|-------------| 00656 * | S1 | Look up the IP address of loopback using `pal_getAddressInfo`. | PAL_SUCCESS | 00657 * | S2 | Create a blocking TCP server socket using `pal_socket`. | PAL_SUCCESS | 00658 * | S3 | Create a blocking TCP socket using `pal_socket`. | PAL_SUCCESS | 00659 * | S4 | Set the port to test port in address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 00660 * | S5 | Bind the server socket to the port and address using `pal_bind`. | PAL_SUCCESS | 00661 * | S6 | Create synchronization sepmaphores and set count to 0. | PAL_SUCCESS | 00662 * | S7 | Create a client thread with `BelowNormal` priority running `palNetClientFunc`. | PAL_SUCCESS | 00663 * | C1 | Client thread blocks on client sepmaphore s1. | PAL_SUCCESS | 00664 * | S8 | Listen to the server port using `pal_listen`. | PAL_SUCCESS | 00665 * | S9 | Release the client sepmahore s1. | PAL_SUCCESS | 00666 * | S10 | Call `accept` (blocking) to accept a new connection (retry in case of failure). | PAL_SUCCESS | 00667 * | C2 | Look up the IP address of the loopback using `pal_getAddressInfo`. | PAL_SUCCESS | 00668 * | C3 | Set the port to test port in the address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 00669 * | C4 | Create a blocking TCP socket using `pal_socket`. | PAL_SUCCESS | 00670 * | C5 | Connect to the server using `pal_connect`. | PAL_SUCCESS | 00671 * | C6 | Send data to server. | PAL_SUCCESS | 00672 * | S11 | Receive data from the client. | PAL_SUCCESS | 00673 * | S12 | Send data to the client. | PAL_SUCCESS | 00674 * | C7 | Receive data from the server. | PAL_SUCCESS | 00675 * | C8 | Client thread cleanup - close the socket and release the semaphore. | PAL_SUCCESS | 00676 * | S13 | Cleanup: close sockets and delete semaphores. | PAL_SUCCESS | 00677 */ 00678 TEST(pal_socket, ServerSocketScenario) 00679 { 00680 00681 palStatus_t result = PAL_SUCCESS; 00682 palSocketAddress_t address2 = { 0 }; 00683 const char* messageOut = "HTTP/1.0 200 OK"; 00684 size_t sent = 0; 00685 size_t read = 0; 00686 // Note: unlike the pal_connect(), the pal accept() still verifies the given address length. 00687 palSocketLength_t addrlen = sizeof(palSocketAddress_t); 00688 00689 palSemaphoreID_t semaphoreID = NULLPTR; 00690 palSemaphoreID_t semaphoreID2 = NULLPTR; 00691 palNetTestThreadData_t dualSem = {0}; 00692 palThreadID_t threadID1 = NULLPTR; 00693 int32_t tmp = 0; 00694 palNetInterfaceInfo_t interfaceInfo; 00695 memset(&interfaceInfo,0,sizeof(interfaceInfo)); 00696 00697 00698 /*#S1*/ 00699 result = pal_getNetInterfaceInfo(PAL_NET_TEST_LOCAL_LOOPBACK_IF_INDEX, &interfaceInfo); 00700 if ((PAL_ERR_SOCKET_DNS_ERROR == result) || (PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY == result)) 00701 { 00702 PAL_LOG_ERR("error: address lookup returned an address not supported by current configuration cant continue test ( IPv6 add for IPv4 only configuration or IPv4 for IPv6 only configuration)"); 00703 return; 00704 } 00705 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00706 00707 /*#S2*/ 00708 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM_SERVER, false, 0, &g_testSockets[0]); 00709 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00710 00711 /*#S3*/ 00712 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, &g_testSockets[1]); 00713 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00714 00715 /*#S4*/ 00716 uint32_t rand_number = 0; 00717 uint16_t incoming_port; 00718 00719 for (int i=0; i<5; i++) { 00720 pal_osRandomBuffer((uint8_t*)&rand_number, sizeof(rand_number)); 00721 incoming_port = (uint16_t)(35400 + (rand_number % (40000 - 35400))); 00722 PAL_PRINTF("server port = %u", incoming_port); 00723 00724 result = pal_setSockAddrPort(&(interfaceInfo.address), incoming_port); 00725 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00726 00727 /*#S5*/ 00728 result = pal_bind(g_testSockets[0], &(interfaceInfo.address), interfaceInfo.addressSize); 00729 00730 if (PAL_SUCCESS == result) { 00731 PAL_PRINTF("bind succeeded on port %u", incoming_port); 00732 break; 00733 } else { 00734 PAL_PRINTF("bind failed on port %u", incoming_port); 00735 } 00736 } 00737 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00738 00739 /*#S6*/ 00740 00741 // start client thread to connect to the server. 00742 result = pal_osSemaphoreCreate(0 ,&semaphoreID); 00743 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00744 00745 result = pal_osSemaphoreCreate(0 ,&semaphoreID2); 00746 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00747 00748 dualSem.sem1 = semaphoreID; 00749 dualSem.sem2 = semaphoreID2; 00750 dualSem.port = incoming_port; 00751 00752 /*#S7*/ 00753 result = pal_osThreadCreateWithAlloc(palNetClientFunc, &dualSem , PAL_osPriorityBelowNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &threadID1); 00754 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00755 00756 /*#S8*/ 00757 result = pal_listen(g_testSockets[0], 10); 00758 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00759 00760 /*#S9*/ 00761 result = pal_osSemaphoreRelease(dualSem.sem1); 00762 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00763 00764 00765 PAL_PRINTF("waiting for connection:\r\n"); 00766 /*#S10*/ 00767 result = pal_accept(g_testSockets[0], &address2, &addrlen, &g_testSockets[1]); 00768 PAL_PRINTF("after accept: %" PRIu32 "\r\n", result); 00769 if (PAL_SUCCESS != result ) 00770 { 00771 result = pal_accept(g_testSockets[0], &address2, &addrlen, &g_testSockets[1]); 00772 PAL_PRINTF("after accept: %" PRIu32 "\r\n",result); 00773 } 00774 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00775 00776 /*#S11*/ 00777 result = pal_recv(g_testSockets[1], s_rcv_buffer2, 49, &read); 00778 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00779 00780 /*#S12*/ 00781 result = pal_send(g_testSockets[1], messageOut, 15, &sent); 00782 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00783 00784 00785 //cleanup 00786 00787 /*#S13*/ 00788 00789 pal_close(&g_testSockets[1]); 00790 pal_close(&g_testSockets[0]); 00791 00792 result = pal_osSemaphoreWait(semaphoreID2, TEST_SEMAPHORE_WAIT, &tmp); 00793 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00794 pal_osDelay(2000); 00795 pal_osThreadTerminate(&threadID1); 00796 result = pal_osSemaphoreDelete(&semaphoreID); 00797 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00798 TEST_ASSERT_EQUAL_HEX(NULLPTR, semaphoreID); 00799 00800 result = pal_osSemaphoreDelete(&semaphoreID2); 00801 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00802 TEST_ASSERT_EQUAL_HEX(NULLPTR, semaphoreID2); 00803 } 00804 00805 00806 00807 PAL_PRIVATE volatile uint32_t s_callbackCounterNonBlock = 0; 00808 00809 PAL_PRIVATE void nonBlockCallback(void * arg) 00810 { 00811 s_callbackCounterNonBlock++; 00812 } 00813 00814 #define PAL_NET_TEST_HTTP_HEADER_LEN 5 00815 00816 /*! \brief /b nonBlockingAsyncTest checks the asynchronous- nonblocking socket scenario. 00817 ** \test 00818 * | # | Step | Expected | 00819 * |---|--------------------------------|-------------| 00820 * | 1 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 00821 * | 2 | Create an asynchronous non-blocking TCP socket with `nonBlockCallback` as callback. | PAL_SUCCESS | 00822 * | 3 | Set the port to test port in the address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 00823 * | 4 | Connect the socket. | PAL_SUCCESS or PAL_ERR_SOCKET_IN_PROGRES | 00824 * | 5 | Send a test message to the test server using `pal_send` (repeat until success). | PAL_SUCCESS or PAL_ERR_SOCKET_IN_PROGRES | 00825 * | 6 | Wait for the callback and receive server response using `pal_recv` (repeat until success). | PAL_SUCCESS or PAL_ERR_SOCKET_WOULD_BLOCK| 00826 * | 7 | Close the socket. | PAL_SUCCESS | 00827 */ 00828 TEST(pal_socket, nonBlockingAsyncTest) 00829 { 00830 palStatus_t result = PAL_SUCCESS; 00831 palSocketAddress_t address = { 0 }; 00832 const char* message = "GET / HTTP/1.0\r\nHost:10.45.48.68:8000\r\n\r\n"; 00833 size_t sent = 0; 00834 char buffer[100] = { 0 }; 00835 size_t read = 0; 00836 s_callbackcounter = 0; 00837 palSocketLength_t addrlen = 0; 00838 int32_t waitIterations = 0; 00839 00840 /*#1*/ 00841 result = pal_getAddressInfo(PAL_NET_TEST_SERVER_NAME, &address, &addrlen); 00842 if ((PAL_ERR_SOCKET_DNS_ERROR == result) || (PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY == result)) 00843 { 00844 PAL_LOG_ERR("error: address lookup returned an address not supported by current configuration cant continue test ( IPv6 add for IPv4 only configuration or IPv4 for IPv6 only configuration)"); 00845 return; 00846 } 00847 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00848 00849 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 00850 /*#2*/ 00851 result = pal_asynchronousSocketWithArgument(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, nonBlockCallback, "non-blockSocketCallbackArg", &g_testSockets[0]); 00852 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00853 00854 /*#3*/ 00855 result = pal_setSockAddrPort(&address, PAL_NET_TEST_SERVER_HTTP_PORT); 00856 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00857 00858 /*#4*/ 00859 result = pal_connect(g_testSockets[0], &address, 16); 00860 if (PAL_ERR_SOCKET_IN_PROGRES == result) 00861 { 00862 result = pal_connect(g_testSockets[0], &address, 16); 00863 if ((result != PAL_SUCCESS) && (result != PAL_ERR_SOCKET_ALREADY_CONNECTED ) && (result != PAL_ERR_SOCKET_IN_PROGRES ) && (result != PAL_ERR_SOCKET_WOULD_BLOCK )) // check expected result codes.(connection should either be in progress or connected already) 00864 { 00865 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00866 } 00867 pal_osDelay(400); 00868 } 00869 else 00870 { 00871 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00872 } 00873 s_callbackCounterNonBlock = 0; 00874 00875 /*#5*/ 00876 result = pal_send(g_testSockets[0], message, strlen(message), &sent); 00877 00878 while (PAL_ERR_SOCKET_IN_PROGRES == result) 00879 { 00880 pal_osDelay(100); 00881 result = pal_send(g_testSockets[0], message, strlen(message), &sent); 00882 } 00883 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00884 00885 /*#6*/ 00886 result = pal_recv(g_testSockets[0], buffer, PAL_NET_TEST_HTTP_HEADER_LEN, &read); // may block 00887 while ((PAL_ERR_SOCKET_WOULD_BLOCK == result) && (10 > waitIterations )) 00888 { 00889 s_callbackCounterNonBlock = 0; 00890 while (s_callbackCounterNonBlock == 0) 00891 { 00892 waitIterations++; 00893 pal_osDelay(100); 00894 } 00895 result = pal_recv(g_testSockets[0], buffer, PAL_NET_TEST_HTTP_HEADER_LEN, &read); // shouldnt block 00896 } 00897 00898 /*#7*/ 00899 pal_close(&g_testSockets[0]); 00900 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00901 TEST_ASSERT(read >= 4); 00902 TEST_ASSERT(buffer[0] == 'H' && buffer[1] == 'T'&& buffer[2] == 'T' && buffer[3] == 'P'); 00903 TEST_ASSERT(s_callbackCounterNonBlock > 0); 00904 00905 #endif // PAL_NET_ASYNCHRONOUS_SOCKET_API 00906 } 00907 00908 /*! \brief /b tProvUDPTest tests UDP socket send/receive and checks that we get the correct error for receive timeout. 00909 ** \test 00910 * | # | Step | Expected | 00911 * |---|--------------------------------|-------------| 00912 * | 1 | Create a blocking UDP socket using `pal_socket`. | PAL_SUCCESS | 00913 * | 2 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 00914 * | 3 | Set the port to test port in the address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 00915 * | 4 | Set socket timeouts using `pal_setSocketOptions`. | PAL_SUCCESS | 00916 * | 5 | Send a test message (short HTTP request) to test the server using `pal_send`. | PAL_SUCCESS | 00917 * | 6 | Receive the (blocking) server response using `pal_recv`. | PAL_SUCCESS | 00918 * | 7 | Receive the (blocking) server response again using `pal_recv` and fail. | PAL_ERR_SOCKET_WOULD_BLOCK | 00919 * | 8 | Close the socket. | PAL_SUCCESS | 00920 */ 00921 TEST(pal_socket, tProvUDPTest) 00922 { 00923 #if defined(__SXOS__) 00924 TEST_IGNORE_MESSAGE("Ignored, SX OS does not support PAL_SO_RCVTIMEO"); 00925 #else 00926 palStatus_t result = PAL_SUCCESS; 00927 palSocketAddress_t address = { 0,{0} }; 00928 uint8_t buffer[100] = { 0 }; 00929 uint8_t buffer_dns[33] = { 0x8e, 0xde, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x61, 0x72, 0x73, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x69, 0x63, 0x61, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01 }; 00930 size_t sent = 0; 00931 size_t read = 0; 00932 palSocketLength_t addrlen = 16; 00933 int timeout = PAL_MILLI_PER_SECOND; 00934 00935 /*#1*/ 00936 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM, false, 0, &g_testSockets[0]); 00937 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00938 00939 /*#2*/ 00940 result = pal_getAddressInfo(PAL_NET_TEST_SERVER_NAME_UDP, &address, &addrlen); 00941 if ((PAL_ERR_SOCKET_DNS_ERROR == result) || (PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY == result)) 00942 { 00943 PAL_LOG_ERR("error: address lookup returned an address not supported by current configuration cant continue test ( IPv6 add for IPv4 only configuration or IPv4 for IPv6 only configuration)"); 00944 goto end; 00945 } 00946 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00947 00948 /*#3*/ 00949 result = pal_setSockAddrPort(&address, PAL_NET_TEST_SERVER_UDP_PORT); 00950 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00951 00952 /*#4*/ 00953 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_SNDTIMEO, &timeout, sizeof(timeout)); 00954 TEST_ASSERT_EQUAL_HEX(PAL_SO_SNDTIMEO_EXPECTED_RESULT, result); 00955 00956 timeout = 1000; 00957 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO, &timeout, sizeof(timeout)); 00958 TEST_ASSERT_EQUAL_HEX(PAL_SO_RCVTIMEO_EXPECTED_RESULT, result); 00959 00960 /*#5*/ 00961 result = pal_sendTo(g_testSockets[0], buffer_dns, sizeof(buffer_dns), &address, addrlen, &sent); 00962 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00963 TEST_ASSERT_EQUAL_HEX(sent, sizeof(buffer_dns)); 00964 00965 /*#6*/ 00966 result = pal_receiveFrom(g_testSockets[0], buffer, 16, NULL, NULL, &read); 00967 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00968 TEST_ASSERT_EQUAL(read, 16); 00969 00970 /*#7*/ 00971 result = pal_receiveFrom(g_testSockets[0], buffer, 100, NULL, NULL, &read); // should get timeout 00972 TEST_ASSERT_EQUAL_HEX(result, PAL_ERR_SOCKET_WOULD_BLOCK ); 00973 00974 end: 00975 /*#8*/ 00976 pal_close(&g_testSockets[0]); 00977 #endif 00978 } 00979 00980 00981 PAL_PRIVATE void fillUDPTestBuffer(pal_udp_test_data_t *data, uint8_t* buffer) 00982 { 00983 TEST_ASSERT_NOT_NULL(data); 00984 TEST_ASSERT_NOT_NULL(buffer); 00985 00986 memset(buffer, 0, data->bufferSize); 00987 data->chunkSize = (data->messageSize - data->totalSize > data->bufferSize) ? data->bufferSize : (data->messageSize - data->totalSize); 00988 memset(buffer, ++(data->currentValue), data->chunkSize); 00989 data->totalSize += data->chunkSize; 00990 } 00991 00992 // UDP test sender thread function. 00993 PAL_PRIVATE void socketUDPBufferedTestSender(const void *arg) 00994 { 00995 palStatus_t result = PAL_SUCCESS; 00996 pal_udp_test_data_t *data = (pal_udp_test_data_t*)arg; // cast from const to non-const 00997 size_t sent = 0, totalSent = 0; 00998 00999 TEST_ASSERT_NOT_NULL(data); 01000 TEST_ASSERT_NOT_EQUAL(0, data->bufferSize); 01001 TEST_ASSERT_NOT_EQUAL(0, data->chunkSize); 01002 01003 g_testSendBuffer = (uint8_t*)malloc(sizeof(uint8_t) * data->bufferSize); 01004 TEST_ASSERT_NOT_NULL(g_testSendBuffer); 01005 01006 data->totalSize = 0; 01007 data->chunkSize = 0; 01008 data->currentValue = data->startValue; 01009 while (totalSent != data->messageSize) 01010 { 01011 fillUDPTestBuffer(data, g_testSendBuffer); 01012 result = pal_sendTo(g_testSockets[0], g_testSendBuffer, data->chunkSize, &(data->interfaceInfo.address), data->interfaceInfo.addressSize, &sent); 01013 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01014 totalSent += sent; 01015 pal_osDelay(5); // allow some time for the RX bits to be set 01016 }; 01017 01018 free(g_testSendBuffer); 01019 g_testSendBuffer = NULLPTR; 01020 } 01021 01022 /*! \brief Test UDP socket read in chunks 01023 * 01024 * \note The test generates data and calculates its hash, then this data is re-generated from a dedicated thread and 01025 * received on the current thread which calculates the received data hash and compares it to the original hash 01026 * 01027 * @param[in] bufSize - the read buffer size 01028 * 01029 ** \test 01030 * | # | Step | Expected | 01031 * |---|--------------------------------|-------------| 01032 * | 1 | Initialize the MD context. | PAL_SUCCESS | 01033 * | 2 | Allocate buffer. | PAL_SUCCESS | 01034 * | 3 | Generate data incrementally and update the MD context. | PAL_SUCCESS | 01035 * | 4 | Get the hash output size and validate it. | PAL_SUCCESS | 01036 * | 5 | Get the calculated hash. | PAL_SUCCESS | 01037 * | 6 | Free the MD context resources. | PAL_SUCCESS | 01038 * | 7 | Get the interface address. | PAL_SUCCESS | 01039 * | 8 | Create a (blocking) UDP socket. | PAL_SUCCESS | 01040 * | 9 | Set the socket port and set send/receive timeouts. | PAL_SUCCESS | 01041 * | 10 | Bind the socket. | PAL_SUCCESS | 01042 * | 11 | Initialize the MD context. | PAL_SUCCESS | 01043 * | 12 | Launch the data sender thread. | PAL_SUCCESS | 01044 * | 13 | Read data from the socket until there's no more data or all data has been received. | PAL_SUCCESS | 01045 * | 14 | Update the MD context. | PAL_SUCCESS | 01046 * | 15 | Terminate the sending thread. | PAL_SUCCESS | 01047 * | 16 | Close the socket. | PAL_SUCCESS | 01048 * | 17 | Get the hash output size and validate it. | PAL_SUCCESS | 01049 * | 18 | Get the calculated hash and compare it. | PAL_SUCCESS | 01050 * | 19 | Free the MD context resources. | PAL_SUCCESS | 01051 * | 20 | Free allocated buffer. | PAL_SUCCESS | 01052 */ 01053 PAL_PRIVATE void socketUDPBuffered(size_t bufSize) 01054 { 01055 palStatus_t result = PAL_SUCCESS; 01056 pal_udp_test_data_t data = { PAL_NET_TEST_BUFFERED_UDP_MESSAGE_SIZE, bufSize, 0 }; 01057 uint8_t expectedHash[PAL_SHA256_SIZE] = { 0 }, actualHash[PAL_SHA256_SIZE] = { 0 }; 01058 size_t read = 0, totalRead = 0, hashlen = 0; 01059 int timeout = PAL_MILLI_PER_SECOND; 01060 palMDHandle_t handle = NULLPTR; 01061 palThreadID_t thread = NULLPTR; 01062 01063 /*#1*/ 01064 result = pal_mdInit(&handle, PAL_SHA256); 01065 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01066 TEST_ASSERT_NOT_EQUAL(NULLPTR, handle); 01067 01068 /*#2*/ 01069 g_testRecvBuffer = (uint8_t*)malloc(sizeof(uint8_t) * bufSize); 01070 TEST_ASSERT_NOT_EQUAL(NULLPTR, g_testRecvBuffer); 01071 01072 /*#3*/ 01073 data.totalSize = data.chunkSize = 0; 01074 data.currentValue = data.startValue; 01075 while (data.totalSize != data.messageSize) 01076 { 01077 fillUDPTestBuffer(&data, g_testRecvBuffer); 01078 result = pal_mdUpdate(handle, g_testRecvBuffer, data.chunkSize); 01079 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01080 }; 01081 01082 /*#4*/ 01083 result = pal_mdGetOutputSize(handle, &hashlen); 01084 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01085 TEST_ASSERT_EQUAL_HEX(PAL_SHA256_SIZE, hashlen); 01086 01087 /*#5*/ 01088 result = pal_mdFinal(handle, expectedHash); 01089 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01090 01091 /*#6*/ 01092 result = pal_mdFree(&handle); 01093 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01094 01095 /*#7*/ 01096 memset(&(data.interfaceInfo), 0, sizeof(data.interfaceInfo)); 01097 result = pal_getNetInterfaceInfo(0, &(data.interfaceInfo)); 01098 if ((PAL_ERR_SOCKET_DNS_ERROR == result) || (PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY == result)) 01099 { 01100 PAL_LOG_ERR("error: address lookup returned an address not supported by current configuration cant continue test ( IPv6 add for IPv4 only configuration or IPv4 for IPv6 only configuration)"); 01101 goto end; 01102 } 01103 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01104 01105 /*#8*/ 01106 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM, false, 0, &g_testSockets[0]); 01107 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01108 01109 /*#9*/ 01110 result = pal_setSockAddrPort(&(data.interfaceInfo.address), PAL_NET_TEST_BUFFERED_UDP_PORT); 01111 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01112 01113 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO, &timeout, sizeof(timeout)); 01114 TEST_ASSERT_EQUAL_HEX(PAL_SO_RCVTIMEO_EXPECTED_RESULT, result); 01115 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_SNDTIMEO, &timeout, sizeof(timeout)); 01116 TEST_ASSERT_EQUAL_HEX(PAL_SO_SNDTIMEO_EXPECTED_RESULT, result); 01117 01118 /*#10*/ 01119 result = pal_bind(g_testSockets[0], &(data.interfaceInfo.address), data.interfaceInfo.addressSize); 01120 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01121 01122 /*#11*/ 01123 handle = NULLPTR; 01124 result = pal_mdInit(&handle, PAL_SHA256); 01125 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01126 TEST_ASSERT_NOT_EQUAL(NULLPTR, handle); 01127 01128 /*#12*/ 01129 result = pal_osThreadCreateWithAlloc(socketUDPBufferedTestSender, &data, PAL_osPriorityNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &thread); 01130 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01131 TEST_ASSERT_NOT_EQUAL(NULLPTR, thread); 01132 01133 /*#13*/ 01134 do 01135 { 01136 read = 0; 01137 memset(g_testRecvBuffer, 0, data.bufferSize); 01138 result = pal_receiveFrom(g_testSockets[0], g_testRecvBuffer, data.bufferSize, &(data.interfaceInfo.address), &(data.interfaceInfo.addressSize), &read); 01139 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01140 /*#14*/ 01141 result = pal_mdUpdate(handle, g_testRecvBuffer, read); 01142 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01143 totalRead += read; 01144 } while (read > 0 && totalRead < data.messageSize); 01145 01146 /*#15*/ 01147 result = pal_osThreadTerminate(&thread); 01148 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01149 01150 /*#16*/ 01151 result = pal_close(&g_testSockets[0]); 01152 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01153 01154 /*#17*/ 01155 hashlen = 0; 01156 result = pal_mdGetOutputSize(handle, &hashlen); 01157 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01158 TEST_ASSERT_EQUAL_HEX(PAL_SHA256_SIZE, hashlen); 01159 01160 /*#18*/ 01161 result = pal_mdFinal(handle, actualHash); 01162 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01163 TEST_ASSERT_EQUAL_MEMORY(expectedHash, actualHash, PAL_SHA256_SIZE); 01164 01165 /*#19*/ 01166 result = pal_mdFree(&handle); 01167 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01168 01169 /*#20*/ 01170 end: 01171 free(g_testRecvBuffer); 01172 g_testRecvBuffer = NULLPTR; 01173 } 01174 01175 /*! \brief Test function UDP socket read in small chunks 01176 * 01177 ** \test 01178 */ 01179 TEST(pal_socket, socketUDPBufferedSmall) 01180 { 01181 #ifdef TARGET_LIKE_MBED 01182 // TODO: fix with https://jira.arm.com/browse/IOTCLT-3197 01183 TEST_IGNORE_MESSAGE("Ignored, IOTCLT-3197, Expected 0x00000000 Was 0xFFFF5..."); 01184 #endif 01185 socketUDPBuffered(PAL_NET_TEST_BUFFERED_UDP_BUF_SIZE_SMALL); 01186 } 01187 01188 /*! \brief Test function UDP socket read in large chunks 01189 * 01190 ** \test 01191 */ 01192 TEST(pal_socket, socketUDPBufferedLarge) 01193 { 01194 #ifdef TARGET_LIKE_MBED 01195 // TODO: fix with https://jira.arm.com/browse/IOTCLT-3197 01196 TEST_IGNORE_MESSAGE("Ignored, IOTCLT-3197, Expected 0x00000000 Was 0xFFFF5..."); 01197 #endif 01198 socketUDPBuffered(PAL_NET_TEST_BUFFERED_UDP_BUF_SIZE_LARGE); 01199 } 01200 01201 #ifdef __LINUX__ // Linux CI tests for socketTCPBufferedSmall & socketTCPBufferedLarge must use an ipv4 address in order to connect to the external host 01202 #if PAL_SUPPORT_IP_V4 01203 PAL_PRIVATE palStatus_t getAddressInfoIPv4(char const *url, palSocketAddress_t *address, palSocketLength_t* addressLength) 01204 { 01205 struct addrinfo *info = NULLPTR; 01206 struct addrinfo hints = { 0 }; 01207 struct sockaddr_in *sockAddress = NULLPTR; 01208 palIpV4Addr_t ipV4Address = { 0 }; 01209 int ret; 01210 palStatus_t result; 01211 01212 hints.ai_family = AF_INET; 01213 ret = getaddrinfo(url, NULL, &hints, &info); 01214 TEST_ASSERT_EQUAL(0, ret); 01215 TEST_ASSERT_NOT_EQUAL(NULLPTR, info); 01216 TEST_ASSERT_EQUAL(AF_INET, info->ai_family); 01217 01218 sockAddress = (struct sockaddr_in*)info->ai_addr; 01219 memcpy(ipV4Address, &(sockAddress->sin_addr), PAL_IPV4_ADDRESS_SIZE); 01220 freeaddrinfo(info); 01221 01222 result = pal_setSockAddrIPV4Addr(address, ipV4Address); 01223 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01224 *addressLength = sizeof(struct sockaddr_in); 01225 return result; 01226 } 01227 #endif 01228 #endif 01229 01230 /*! \brief Test TCP socket read in chunks 01231 * 01232 * \note The test attempts to perform an HTTP get request to a google (jquery) CDN, read the file in chunks (ignoring HTTP headers) and compare its hash to a pre-known hash using SHA256. 01233 * 01234 * @param[in] bufSize - the read buffer size 01235 * 01236 ** \test 01237 * | # | Step | Expected | 01238 * |---|--------------------------------|-------------| 01239 * | 1 | Create a (blocking) TCP socket. | PAL_SUCCESS | 01240 * | 2 | Look up the IP address of the CDN server. | PAL_SUCCESS | 01241 * | 3 | Set the port to the CDN server's HTTP port and set send/receive timeouts. | PAL_SUCCESS | 01242 * | 4 | Connect the socket to the CDN server. | PAL_SUCCESS | 01243 * | 5 | Send an HTTP get request to the CDN server. | PAL_SUCCESS | 01244 * | 6 | Initialize the MD context. | PAL_SUCCESS | 01245 * | 7 | Allocate HTTP response buffer. | PAL_SUCCESS | 01246 * | 8 | Read the server's response until there's no more data to read. | PAL_SUCCESS | 01247 * | 9 | If we're done dealing with the HTTP headers then update the MD context. | PAL_SUCCESS | 01248 * | 10 | Locate the end of the HTTP headers in the server's response (HTTP headers end with a double CRLF). | PAL_SUCCESS | 01249 * | 11 | Update the MD context. | PAL_SUCCESS | 01250 * | 12 | Close the socket. | PAL_SUCCESS | 01251 * | 13 | Get the hash output size and validate it. | PAL_SUCCESS | 01252 * | 14 | Get the calculated hash and compare it to the pre-known hash. | PAL_SUCCESS | 01253 * | 15 | Free the MD context resources. | PAL_SUCCESS | 01254 * | 16 | Free HTTP response buffer. | PAL_SUCCESS | 01255 */ 01256 PAL_PRIVATE void socketTCPBuffered(size_t bufSize) 01257 { 01258 palStatus_t result = PAL_SUCCESS; 01259 palSocketAddress_t address = { 0 }; 01260 palSocketLength_t addrlen = 0; 01261 int timeout = 5000; 01262 uint8_t next = '\r', state = 0; 01263 size_t read = 0, sent = 0, hashlen = 0; 01264 bool body = false; 01265 palMDHandle_t handle = NULLPTR; 01266 uint8_t actualHash[PAL_SHA256_SIZE] = { 0 }; 01267 const uint8_t expectedHash[] = // pre-calculated jquery.js 3.2.1 SHA256 01268 { 01269 0x0d, 0x90, 0x27, 0x28, 0x9f, 0xfa, 0x5d, 0x9f, 0x6c, 0x8b, 0x4e, 0x07, 0x82, 0xbb, 0x31, 0xbb, 01270 0xff, 0x2c, 0xef, 0x5e, 0xe3, 0x70, 0x8c, 0xcb, 0xcb, 0x7a, 0x22, 0xdf, 0x91, 0x28, 0xbb, 0x21 01271 }; 01272 01273 01274 01275 /*#2*/ 01276 result = test_getAddressInfo(PAL_NET_TEST_GOOGLE_CDN_HOST, &address, &addrlen); 01277 if ((PAL_ERR_SOCKET_DNS_ERROR == result) || (PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY == result)) 01278 { 01279 PAL_LOG_ERR("error: address lookup returned an address not supported by current configuration cant continue test ( IPv6 add for IPv4 only configuration or IPv4 for IPv6 only configuration)"); 01280 return; 01281 } 01282 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01283 01284 /*#1*/ 01285 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, &g_testSockets[0]); 01286 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01287 01288 /*#3*/ 01289 result = pal_setSockAddrPort(&address, PAL_NET_TEST_GOOGLE_CDN_HOST_PORT); 01290 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01291 01292 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_SNDTIMEO, &timeout, sizeof(timeout)); 01293 TEST_ASSERT_EQUAL_HEX(PAL_SO_SNDTIMEO_EXPECTED_RESULT, result); 01294 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO, &timeout, sizeof(timeout)); 01295 TEST_ASSERT_EQUAL_HEX(PAL_SO_RCVTIMEO_EXPECTED_RESULT, result); 01296 01297 /*#4*/ 01298 result = pal_connect(g_testSockets[0], &address, addrlen); 01299 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01300 01301 /*#5*/ 01302 result = pal_send(g_testSockets[0], PAL_NET_TEST_GOOGLE_CDN_REQUEST, sizeof(PAL_NET_TEST_GOOGLE_CDN_REQUEST) - 1, &sent); 01303 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01304 01305 /*#6*/ 01306 result = pal_mdInit(&handle, PAL_SHA256); 01307 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01308 TEST_ASSERT_NOT_EQUAL(NULLPTR, handle); 01309 01310 /*#7*/ 01311 g_testRecvBuffer = (uint8_t*)malloc(sizeof(uint8_t) * bufSize + 1); 01312 TEST_ASSERT_NOT_EQUAL(NULLPTR, g_testRecvBuffer); 01313 01314 /*#8*/ 01315 do 01316 { 01317 read = 0; 01318 memset(g_testRecvBuffer, 0, bufSize + 1); 01319 result = pal_recv(g_testSockets[0], g_testRecvBuffer, bufSize, &read); 01320 TEST_ASSERT_TRUE((PAL_SUCCESS == result && read > 0) || (PAL_ERR_SOCKET_CONNECTION_CLOSED == result && read == 0)); 01321 01322 /*#9*/ 01323 if (body) 01324 { 01325 result = pal_mdUpdate(handle, g_testRecvBuffer, read); 01326 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01327 continue; 01328 } 01329 01330 /*#10*/ 01331 for (size_t i = 0; i < bufSize; i++) // dealing with the HTTP headers - headers end on a double CRLF 01332 { 01333 if (g_testRecvBuffer[i] == next) 01334 { 01335 next = (next == '\r') ? '\n' : '\r'; 01336 state = state | (state + 1); 01337 if (state == 0xf) 01338 { 01339 /*#11*/ 01340 body = true; 01341 result = pal_mdUpdate(handle, (g_testRecvBuffer + i + 1), strlen(((char*)g_testRecvBuffer) + i + 1)); 01342 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01343 break; 01344 } 01345 } 01346 else if (state != 0) 01347 { 01348 next = '\r'; 01349 state = 0; 01350 } 01351 } 01352 } while (read > 0); 01353 01354 /*#12*/ 01355 result = pal_close(&g_testSockets[0]); 01356 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01357 01358 /*#13*/ 01359 result = pal_mdGetOutputSize(handle, &hashlen); 01360 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01361 TEST_ASSERT_EQUAL_HEX(PAL_SHA256_SIZE, hashlen); 01362 01363 /*#14*/ 01364 result = pal_mdFinal(handle, actualHash); 01365 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01366 TEST_ASSERT_EQUAL_MEMORY(expectedHash, actualHash, PAL_SHA256_SIZE); 01367 01368 /*#15*/ 01369 result = pal_mdFree(&handle); 01370 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01371 01372 /*#16*/ 01373 free(g_testRecvBuffer); 01374 g_testRecvBuffer = NULLPTR; 01375 01376 } 01377 01378 /*! \brief Test function TCP socket read in small chunks 01379 * 01380 ** \test 01381 */ 01382 TEST(pal_socket, socketTCPBufferedSmall) 01383 { 01384 socketTCPBuffered(PAL_NET_TEST_BUFFERED_TCP_BUF_SIZE_SMALL); 01385 } 01386 01387 /*! \brief Test function TCP socket read in large chunks 01388 * 01389 ** \test 01390 */ 01391 TEST(pal_socket, socketTCPBufferedLarge) 01392 { 01393 socketTCPBuffered(PAL_NET_TEST_BUFFERED_TCP_BUF_SIZE_LARGE); 01394 } 01395 01396 #if (PAL_DNS_API_VERSION == 1) 01397 01398 // flag marking if the pal_getAddressInfoAsync callback has been invoked 01399 PAL_PRIVATE bool g_getAddressInfoAsyncCallbackInvoked = false; 01400 01401 // callback invoked from the call to pal_getAddressInfoAsync 01402 PAL_PRIVATE void getAddressInfoAsyncCallback(const char* url, palSocketAddress_t* address, palSocketLength_t* addressLength, palStatus_t status, void* arg) 01403 { 01404 palStatus_t* statusArg = (palStatus_t*)arg; 01405 *statusArg = status; 01406 g_getAddressInfoAsyncCallbackInvoked = true; 01407 } 01408 #endif 01409 01410 /*! \brief Test get address info asynchronously 01411 ** \test 01412 * | # | Step | Expected | 01413 * |---|-------------------------------------------------------------------------------------------------------|-------------| 01414 * | 1 | Invoke a synchronous get address info so we'll have something to compare to the asynchronous results. | PAL_SUCCESS | 01415 * | 2 | Invoke an asynchronous get address info. | PAL_SUCCESS | 01416 * | 3 | Wait until the asynchronous get address info callback is called or max wait time has ended. | PAL_SUCCESS | 01417 * | 4 | Compare the synchronous results to the asynchronous results. | PAL_SUCCESS | 01418 */ 01419 TEST(pal_socket, getAddressInfoAsync) 01420 { 01421 #if (PAL_DNS_API_VERSION == 1) 01422 int counter = 0; 01423 palSocketAddress_t addressSync = { 0 }, addressAsync = { 0 }; 01424 palSocketLength_t addrlenSync = 0, addrlenAsync = 0; 01425 palStatus_t status, statusCallback; 01426 01427 /*#1*/ 01428 status = pal_getAddressInfo(PAL_NET_TEST_SERVER_NAME, &addressSync, &addrlenSync); 01429 if ((PAL_ERR_SOCKET_DNS_ERROR == status) || (PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY == status)) 01430 { 01431 PAL_LOG_ERR("error: address lookup returned an address not supported by current configuration cant continue test ( IPv6 add for IPv4 only configuration or IPv4 for IPv6 only configuration)"); 01432 return; 01433 } 01434 TEST_ASSERT_TRUE_MESSAGE((PAL_SUCCESS == status), "synchronous call to pal_getAddressInfo failed"); 01435 01436 /*#2*/ 01437 statusCallback = PAL_ERR_SOCKET_ERROR_BASE ; 01438 01439 status = pal_getAddressInfoAsync(PAL_NET_TEST_SERVER_NAME, &addressAsync, &addrlenAsync, getAddressInfoAsyncCallback, &statusCallback); 01440 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01441 01442 /*#3*/ 01443 while ((!g_getAddressInfoAsyncCallbackInvoked) && counter < 20) // wait until callback is invoked or max time of ~5 seconds 01444 { 01445 counter++; 01446 pal_osDelay(250); 01447 } 01448 TEST_ASSERT_TRUE_MESSAGE(g_getAddressInfoAsyncCallbackInvoked, "getAddressInfoAsyncCallback was not invoked"); 01449 g_getAddressInfoAsyncCallbackInvoked = false; 01450 01451 /*#4*/ 01452 TEST_ASSERT_EQUAL_HEX(status, statusCallback); 01453 TEST_ASSERT_EQUAL_HEX(addrlenSync, addrlenAsync); 01454 TEST_ASSERT_EQUAL_HEX(addressSync.addressType, addressAsync.addressType); 01455 TEST_ASSERT_EQUAL_MEMORY(addressSync.addressData, addressAsync.addressData, PAL_NET_MAX_ADDR_SIZE); 01456 #else 01457 TEST_IGNORE_MESSAGE("Ignored, PAL_DNS_API_VERSION not 1"); 01458 #endif // (PAL_DNS_API_VERSION == 1) 01459 } 01460 01461 01462 /*! \brief Test pal socket APIs input parameter validations 01463 ** \test 01464 */ 01465 TEST(pal_socket, socketApiInputParamValidation) 01466 { 01467 #ifdef TARGET_LIKE_MBED 01468 // TODO: fix with https://jira.arm.com/browse/IOTCLT-3197 01469 TEST_IGNORE_MESSAGE("Ignored, IOTCLT-3197, Expected 86 Was 4294964381"); 01470 #endif 01471 #ifdef DEBUG 01472 palStatus_t status; 01473 palSocketAddress_t addr; 01474 addr.addressType = PAL_AF_UNSPEC; 01475 uint16_t port = 0; 01476 01477 status = pal_registerNetworkInterface(NULL, NULL); 01478 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01479 status = pal_setSockAddrPort(NULL, 0); 01480 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01481 status = pal_setSockAddrPort(&addr, 0); 01482 TEST_ASSERT_EQUAL_HEX(PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY , status); 01483 #if PAL_SUPPORT_IP_V4 01484 status = pal_setSockAddrIPV4Addr(NULL, NULL); 01485 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01486 status = pal_getSockAddrIPV4Addr(NULL, NULL); 01487 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01488 status = pal_getSockAddrIPV4Addr(&addr, NULL); 01489 TEST_ASSERT_EQUAL_HEX(PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY , status); 01490 #endif 01491 #if PAL_SUPPORT_IP_V6 01492 status = pal_setSockAddrIPV6Addr(NULL, NULL); 01493 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01494 status = pal_getSockAddrIPV6Addr(NULL, NULL); 01495 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01496 status = pal_getSockAddrIPV6Addr(&addr, NULL); 01497 TEST_ASSERT_EQUAL_HEX(PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY , status); 01498 #endif 01499 status = pal_getSockAddrPort(NULL, NULL); 01500 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01501 status = pal_getSockAddrPort(&addr, &port); 01502 TEST_ASSERT_EQUAL_HEX(PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY , status); 01503 status = pal_setSocketOptions(NULL, 0, NULL, 0); 01504 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01505 status = pal_isNonBlocking(NULL, NULL); 01506 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01507 status = pal_bind(NULL, NULL, 0); 01508 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01509 status = pal_receiveFrom(NULL, NULL, 0, NULL, NULL, NULL); 01510 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01511 status = pal_sendTo(NULL, NULL, 0, NULL, 0, NULL); 01512 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01513 status = pal_close(NULL); 01514 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01515 status = pal_getNumberOfNetInterfaces(NULL); 01516 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01517 status = pal_getNetInterfaceInfo(0, NULL); 01518 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01519 #if PAL_NET_TCP_AND_TLS_SUPPORT 01520 status = pal_accept(NULL, NULL, NULL, NULL); 01521 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01522 status = pal_connect(NULL, NULL, 0); 01523 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01524 status = pal_recv(NULL, NULL, 0, NULL); 01525 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01526 status = pal_send(NULL, NULL, 0, NULL); 01527 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01528 #endif // PAL_NET_TCP_AND_TLS_SUPPORT 01529 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 01530 status = pal_asynchronousSocketWithArgument(PAL_AF_UNSPEC, PAL_SOCK_DGRAM, false, 0, NULL, NULL, NULL); 01531 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01532 #endif // PAL_NET_ASYNCHRONOUS_SOCKET_API 01533 #if PAL_NET_DNS_SUPPORT 01534 status = pal_getAddressInfo(NULL, NULL, NULL); 01535 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01536 #if (PAL_DNS_API_VERSION == 1) 01537 status = pal_getAddressInfoAsync(NULL, NULL, NULL, NULL, NULL); 01538 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01539 #endif 01540 #endif // PAL_NET_DNS_SUPPORT 01541 #else 01542 TEST_IGNORE_MESSAGE("Ignored, DEBUG not defined"); 01543 #endif //DEBUG 01544 } 01545 01546 #ifdef PAL_TEST_KEEPALIVE 01547 PAL_PRIVATE void keepAliveFunc(bool keepalive) 01548 { 01549 palStatus_t result = PAL_SUCCESS; 01550 palSocketAddress_t address = { 0 }; 01551 char buffer[100] = { 0 }; 01552 size_t read = 0; 01553 palSocketLength_t addrlen = 0; 01554 int timeout = PAL_MILLI_PER_SECOND; 01555 int KeepAliveOn = 0, KeepAliveIntvl = 0, KeepAliveIdle = 0; 01556 int keepaliveNumber=0; 01557 01558 if (keepalive) 01559 { 01560 KeepAliveOn=1; 01561 KeepAliveIntvl=1; 01562 KeepAliveIdle =1; 01563 } 01564 /*#1*/ 01565 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, &g_testSockets[0]); 01566 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 01567 01568 /*#2*/ 01569 result = pal_getAddressInfo(PAL_TEST_KEEPALIVE_SERVER_ADDRESS, &address, &addrlen); 01570 if ((PAL_ERR_SOCKET_DNS_ERROR == result) || (PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY == result)) 01571 { 01572 PAL_LOG_ERR("error: address lookup returned an address not supported by current configuration cant continue test ( IPv6 add for IPv4 only configuration or IPv4 for IPv6 only configuration)"); 01573 goto end; 01574 } 01575 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 01576 01577 /*#3*/ 01578 result = pal_setSockAddrPort(&address, PAL_TEST_SERVER_KEEPALIVE_PORT); 01579 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 01580 01581 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_SNDTIMEO, &timeout, sizeof(timeout)); 01582 TEST_ASSERT_EQUAL_HEX(PAL_SO_SNDTIMEO_EXPECTED_RESULT, result); 01583 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO, &timeout, sizeof(timeout)); 01584 TEST_ASSERT_EQUAL_HEX(PAL_SO_RCVTIMEO_EXPECTED_RESULT, result); 01585 01586 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_KEEPALIVE, &KeepAliveOn, sizeof(KeepAliveOn)); 01587 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01588 if (keepalive) { 01589 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_KEEPIDLE, &KeepAliveIdle, sizeof(KeepAliveIdle)); 01590 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01591 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_KEEPINTVL, &KeepAliveIntvl, sizeof(KeepAliveIntvl)); 01592 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01593 } 01594 01595 /*#4*/ 01596 result = pal_connect(g_testSockets[0], &address, sizeof(palSocketAddress_t)); 01597 01598 if (result != PAL_SUCCESS) 01599 { 01600 PAL_LOG_ERR("Unable to connect to %s", PAL_TEST_KEEPALIVE_SERVER_ADDRESS); 01601 } 01602 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 01603 01604 /*#6*/ 01605 while (result != PAL_ERR_SOCKET_CONNECTION_CLOSED ) 01606 { 01607 result = pal_recv(g_testSockets[0], buffer, sizeof(buffer)-1 , &read); 01608 if (result != PAL_ERR_SOCKET_CONNECTION_CLOSED ) 01609 { 01610 if((read != 0) && (buffer[0]!=0)) 01611 { 01612 keepaliveNumber=atoi(buffer); 01613 if (keepalive){ 01614 TEST_ASSERT_TRUE(keepaliveNumber > PAL_TEST_KEEPALIVE_NUM_OF_ACK); 01615 } 01616 else{ 01617 TEST_ASSERT_TRUE(keepaliveNumber < PAL_TEST_KEEPALIVE_NUM_OF_ACK); 01618 } 01619 break; 01620 } 01621 } 01622 01623 } 01624 end: 01625 result = pal_close(&g_testSockets[0]); 01626 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 01627 } 01628 #endif // #ifdef PAL_TEST_KEEPALIVE 01629 /*! \brief Test keepAlive On/Off 01630 ** \test 01631 * | # | Step | Expected | 01632 * |---|--------------------------------|-------------| 01633 * | 1 | Create a blocking TCP socket using `pal_socket`. | PAL_SUCCESS | 01634 * | 2 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 01635 * | 3 | Set the port to a test port in the address structure using `pal_setSockAddrPort` and set timeout. | PAL_SUCCESS | 01636 * | 4 | Set keepalive socket options : if keepalive is on set keepalibe idel and intvl . | PAL_SUCCESS | 01637 * | 5 | Connect the socket to the test server using `pal_connect`. | PAL_SUCCESS | 01638 * | 6 | Receive (blocking) the server's response using `pal_recv` and check it keepalive packates sent. | PAL_SUCCESS | 01639 * | 7 | Close the socket. | PAL_SUCCESS | 01640 */ 01641 01642 TEST(pal_socket, keepaliveOn) 01643 { 01644 #ifdef PAL_TEST_KEEPALIVE 01645 keepAliveFunc(true); 01646 #else 01647 TEST_IGNORE_MESSAGE("Ignored, PAL_TEST_KEEPALIVE not defined"); 01648 #endif 01649 } 01650 01651 TEST(pal_socket, keepaliveOff) 01652 { 01653 #ifdef PAL_TEST_KEEPALIVE 01654 keepAliveFunc(false); 01655 #else 01656 TEST_IGNORE_MESSAGE("Ignored, PAL_TEST_KEEPALIVE not defined"); 01657 #endif 01658 } 01659 01660 /*! \brief /b tcp_echo checks the asynchronous- nonblocking socket scenario using tcp. 01661 ** \test 01662 * | # | Step | Expected | 01663 * |---|--------------------------------|-------------| 01664 * | 1 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 01665 * | 2 | Create an asynchronous non-blocking TCP socket with `nonBlockCallback` as callback. | PAL_SUCCESS | 01666 * | 3 | Set the port to test port in the address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 01667 * | 4 | Connect the socket. | PAL_SUCCESS or PAL_ERR_SOCKET_IN_PROGRES | 01668 * | 5 | Send a test message to the test server using `pal_send` (repeat until success). | PAL_SUCCESS or PAL_ERR_SOCKET_IN_PROGRES | 01669 * | 6 | Wait for the callback and receive server response using `pal_recv` (repeat until success). | PAL_SUCCESS or PAL_ERR_SOCKET_WOULD_BLOCK| 01670 * | 7 | Close the socket. | PAL_SUCCESS | 01671 */ 01672 PAL_PRIVATE void echo_test(bool tcp) 01673 { 01674 palStatus_t result = PAL_SUCCESS; 01675 palSocketAddress_t address = { 0 }; 01676 const char* message = "Test string to be sent to echo server, and expected to be returned by the echo server."; 01677 size_t sent = 0; 01678 char buffer[100] = { 0 }; 01679 size_t read = 0; 01680 size_t tot_read = 0; 01681 s_callbackcounter = 0; 01682 palSocketLength_t addrlen = 0; 01683 int32_t waitIterations = 0; 01684 palSocketType_t sockType; 01685 01686 TEST_ASSERT_MESSAGE(sizeof(buffer) / sizeof(char) > strlen(message), "buffer too small to contain test message"); 01687 01688 if (tcp) 01689 { 01690 sockType = PAL_SOCK_STREAM; 01691 } 01692 else 01693 { 01694 sockType = PAL_SOCK_DGRAM; 01695 } 01696 01697 /*#1*/ 01698 result = pal_getAddressInfo(PAL_NET_TEST_ECHO_TEST_SERVER_ADDRESS, &address, &addrlen); 01699 if ((PAL_ERR_SOCKET_DNS_ERROR == result) || (PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY == result)) 01700 { 01701 PAL_LOG_ERR("error: address lookup returned an address not supported by current configuration cant continue test ( IPv6 add for IPv4 only configuration or IPv4 for IPv6 only configuration)"); 01702 return; 01703 } 01704 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01705 01706 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 01707 /*#2*/ 01708 result = pal_asynchronousSocketWithArgument(PAL_AF_INET, sockType, true, 0, nonBlockCallback, "non-blockSocketCallbackArg", &g_testSockets[0]); 01709 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01710 01711 /*#3*/ 01712 result = pal_setSockAddrPort(&address, 7); 01713 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01714 01715 /*#4*/ 01716 result = pal_connect(g_testSockets[0], &address, 16); 01717 if (PAL_ERR_SOCKET_IN_PROGRES == result) 01718 { 01719 result = pal_connect(g_testSockets[0], &address, 16); 01720 if ((result != PAL_SUCCESS) && (result != PAL_ERR_SOCKET_ALREADY_CONNECTED ) && (result != PAL_ERR_SOCKET_IN_PROGRES ) && (result != PAL_ERR_SOCKET_WOULD_BLOCK )) // check expected result codes.(connection should either be in progress or connected already) 01721 { 01722 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01723 } 01724 pal_osDelay(400); 01725 } 01726 else 01727 { 01728 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01729 } 01730 s_callbackCounterNonBlock = 0; 01731 01732 /*#5*/ 01733 result = pal_send(g_testSockets[0], message, strlen(message), &sent); 01734 while (PAL_ERR_SOCKET_IN_PROGRES == result) 01735 { 01736 pal_osDelay(100); 01737 result = pal_send(g_testSockets[0], message, strlen(message), &sent); 01738 } 01739 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01740 01741 /*#6*/ 01742 result = pal_recv(g_testSockets[0], buffer + tot_read, sizeof(buffer) / sizeof(char) - tot_read, &read); // may block 01743 while ((PAL_ERR_SOCKET_WOULD_BLOCK == result) && (10 > waitIterations )) 01744 { 01745 tot_read += read; 01746 s_callbackCounterNonBlock = 0; 01747 while (s_callbackCounterNonBlock == 0) 01748 { 01749 waitIterations++; 01750 pal_osDelay(100); 01751 } 01752 result = pal_recv(g_testSockets[0], buffer + tot_read, sizeof(buffer) / sizeof(char) - tot_read, &read); // shouldnt block 01753 } 01754 tot_read += read; 01755 01756 /*#7*/ 01757 pal_close(&g_testSockets[0]); 01758 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01759 TEST_ASSERT_EQUAL(strlen(message), tot_read); 01760 TEST_ASSERT_EQUAL_STRING(message, buffer); 01761 TEST_ASSERT(s_callbackCounterNonBlock > 0); 01762 01763 #endif // PAL_NET_ASYNCHRONOUS_SOCKET_API 01764 } 01765 01766 TEST(pal_socket, tcp_echo) 01767 { 01768 #ifdef TARGET_LIKE_MBED 01769 // TODO: fix with https://jira.arm.com/browse/IOTCLT-3197 01770 TEST_IGNORE_MESSAGE("Ignored, IOTCLT-3197, Expected 86 Was 4294964381"); 01771 #endif 01772 echo_test(true); 01773 } 01774 01775 TEST(pal_socket, udp_echo) 01776 { 01777 #ifdef TARGET_LIKE_MBED 01778 // TODO: fix with https://jira.arm.com/browse/IOTCLT-3197 01779 TEST_IGNORE_MESSAGE("Ignored, IOTCLT-3197, Expected 86 Was 4294964381"); 01780 #endif 01781 echo_test(false); 01782 }
Generated on Tue Jul 12 2022 20:21:02 by
