Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
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 "PlatIncludes.h" 00022 #include "pal_BSP.h" 00023 #include "string.h" 00024 00025 #ifdef __LINUX__ 00026 #include <netdb.h> 00027 #define test_getAddressInfo getAddressInfoIPv4 00028 #else 00029 #define test_getAddressInfo pal_getAddressInfo 00030 #endif 00031 00032 TEST_GROUP(pal_socket); 00033 00034 //Sometimes you may want to get local data in a module, 00035 //for example if you need to pass a reference. 00036 //However, you should usually avoid this. 00037 //extern int Counter; 00038 00039 #define PAL_NET_SUPPORT_LWIP 1 00040 #define PAL_NET_TEST_SERVER_NAME "www.arm.com" 00041 #define PAL_NET_TEST_SERVER_NAME_UDP "8.8.8.8" 00042 #define PAL_TEST_KEEPALIVE_SERVER_ADDRESS "62.44.193.186" 00043 #define PAL_TEST_KEEPALIVE_NUM_OF_ACK 4 00044 00045 #define PAL_NET_TEST_SERVER_HTTP_PORT 80 00046 #define PAL_TEST_SERVER_KEEPALIVE_PORT 5533 00047 00048 #define PAL_NET_TEST_SERVER_UDP_PORT 53 00049 #define PAL_NET_TEST_INCOMING_PORT 8002 00050 #define PAL_NET_TEST_INCOMING_PORT2 8989 00051 00052 #define PAL_NET_TEST_LOCAL_LOOPBACK_IF_INDEX 0 00053 extern void * g_palTestNetworkInterface; // this is set by the palTestMain funciton 00054 PAL_PRIVATE uint32_t g_interfaceCTXIndex = 0; 00055 PAL_PRIVATE uint32_t s_callbackcounter = 0; 00056 00057 #define PAL_NET_TEST_SOCKETS 4 00058 PAL_PRIVATE palSocket_t g_testSockets[PAL_NET_TEST_SOCKETS] = {0,0,0,0}; 00059 00060 #define PAL_NET_TEST_GOOGLE_CDN_HOST "ajax.googleapis.com" /*! CDN host server */ 00061 #define PAL_NET_TEST_GOOGLE_CDN_HOST_PORT 80 /*! CDN host port */ 00062 #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 */ 00063 #define PAL_NET_TEST_BUFFERED_TCP_BUF_SIZE_SMALL 4 00064 #define PAL_NET_TEST_BUFFERED_TCP_BUF_SIZE_LARGE 1024 00065 #define PAL_NET_TEST_BUFFERED_UDP_BUF_SIZE_SMALL 64 00066 #define PAL_NET_TEST_BUFFERED_UDP_BUF_SIZE_LARGE 512 00067 #define PAL_NET_TEST_BUFFERED_UDP_PORT 2606 00068 #define PAL_NET_TEST_BUFFERED_UDP_MESSAGE_SIZE (1024 * 256) 00069 PAL_PRIVATE uint8_t *g_testRecvBuffer = NULLPTR; 00070 PAL_PRIVATE uint8_t *g_testSendBuffer = NULLPTR; 00071 00072 typedef struct pal_udp_test_data /*! structure used to hold state in UDP buffered tests */ 00073 { 00074 const size_t messageSize; 00075 const size_t bufferSize; 00076 const uint8_t startValue; 00077 palNetInterfaceInfo_t interfaceInfo; 00078 uint8_t currentValue; 00079 size_t totalSize; 00080 size_t chunkSize; 00081 } pal_udp_test_data_t; 00082 00083 TEST_SETUP(pal_socket) 00084 { 00085 uint32_t i = 0; 00086 palStatus_t status = PAL_SUCCESS; 00087 //This is run before *each test* 00088 pal_init(); 00089 if ( NULL == g_palTestNetworkInterface ) 00090 { 00091 PAL_LOG(ERR, "error: net interface not configutred correctly"); 00092 } 00093 else 00094 { 00095 status = pal_registerNetworkInterface(g_palTestNetworkInterface, &g_interfaceCTXIndex); 00096 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00097 } 00098 00099 for (i = 0; i < PAL_NET_TEST_SOCKETS; i++) 00100 { 00101 g_testSockets[i] = 0; 00102 } 00103 } 00104 00105 TEST_TEAR_DOWN(pal_socket) 00106 { 00107 uint32_t i = 0; 00108 for (i = 0; i < PAL_NET_TEST_SOCKETS; i++) 00109 { 00110 if (g_testSockets[i] != 0) 00111 { 00112 pal_close(&(g_testSockets[i])); 00113 } 00114 } 00115 00116 if (g_testRecvBuffer != NULLPTR) 00117 { 00118 free(g_testRecvBuffer); 00119 g_testRecvBuffer = NULLPTR; 00120 } 00121 if (g_testSendBuffer != NULLPTR) 00122 { 00123 free(g_testSendBuffer); 00124 g_testSendBuffer = NULLPTR; 00125 } 00126 00127 pal_destroy(); 00128 } 00129 00130 #define PAL_TEST_BUFFER_SIZE 50 00131 PAL_PRIVATE void socketCallback1( void * arg) 00132 { 00133 s_callbackcounter++; 00134 } 00135 00136 /*! \brief Test socket creation, destruction and modification, as well as getting address infromation and checking the blocking status of sockets. 00137 * 00138 ** \test 00139 * | # | Step | Expected | 00140 * |---|--------------------------------|-------------| 00141 * | 1 | Register a net interface using `pal_registerNetworkInterface`. | PAL_SUCCESS | 00142 * | 2 | Register a net interface using `pal_registerNetworkInterface`, and check that the ID is the same as the previous step. | PAL_SUCCESS | 00143 * | 3 | Get the interface address using `pal_getNetInterfaceInfo`. | PAL_SUCCESS | 00144 * | 4 | Create a blocking UDP socket using `pal_socket`. | PAL_SUCCESS | 00145 * | 5 | Create a blocking UDP socket using `pal_socket`. | PAL_SUCCESS | 00146 * | 6 | Create a non-blocking UDP socket using `pal_socket`. | PAL_SUCCESS | 00147 * | 7 | Create a blocking asynchronous TCP socket with `socketCallback1` as callback. | PAL_SUCCESS | 00148 * | 8 | Check the number of net interfaces registered using `pal_getNetInterfaceInfo`. | PAL_SUCCESS | 00149 * | 9 | Set the socket receive timeout using `pal_setSocketOptions`. | PAL_SUCCESS | 00150 * | 10 | Check that the sockets return the correct blocking status using `pal_isNonBlocking`. | PAL_SUCCESS | 00151 * | 11 | Check the `pal_getAddressInfo` function with an invalid address. | PAL_ERR_SOCKET_DNS_ERROR | 00152 * | 12 | Close all sockets. | PAL_SUCCESS | 00153 */ 00154 TEST(pal_socket, socketUDPCreationOptionsTest) 00155 { 00156 palStatus_t result = PAL_SUCCESS; 00157 uint32_t numInterface = 0; 00158 palNetInterfaceInfo_t interfaceInfo; 00159 uint32_t interfaceIndex = 0; 00160 uint32_t interfaceIndex2 = 0; 00161 uint32_t sockOptVal = 5000; 00162 uint32_t sockOptLen = sizeof(sockOptVal); 00163 palSocketAddress_t address = { 0 }; 00164 palSocketLength_t addrlen = 0; 00165 bool isNonBlocking = false; 00166 00167 memset(&interfaceInfo,0,sizeof(interfaceInfo)); 00168 // Check that re-adding the network interface returns the same index 00169 /*#1*/ 00170 result = pal_registerNetworkInterface(g_palTestNetworkInterface, &interfaceIndex); 00171 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00172 00173 /*#2*/ 00174 result = pal_registerNetworkInterface(g_palTestNetworkInterface, &interfaceIndex2); 00175 TEST_ASSERT_EQUAL_HEX(interfaceIndex, interfaceIndex2); 00176 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00177 00178 /*#3*/ 00179 result = pal_getNetInterfaceInfo(interfaceIndex, &interfaceInfo); 00180 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00181 PAL_PRINTF("Default interface address: %u %u %u %u \r\n", 00182 (unsigned char)interfaceInfo.address.addressData[2], 00183 (unsigned char)interfaceInfo.address.addressData[3], 00184 (unsigned char)interfaceInfo.address.addressData[4], 00185 (unsigned char)interfaceInfo.address.addressData[5]);; 00186 00187 00188 //Blocking 00189 /*#4*/ 00190 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM , false, interfaceIndex, &g_testSockets[0]); 00191 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00192 /*#5*/ 00193 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM , false, interfaceIndex, &g_testSockets[1]); 00194 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00195 //Non-blocking 00196 /*#6*/ 00197 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM , true, interfaceIndex, &g_testSockets[3]); 00198 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00199 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 00200 /*#7*/ 00201 result = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, false, interfaceIndex, socketCallback1, &g_testSockets[2]); 00202 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00203 #endif // PAL_NET_ASYNCHRONOUS_SOCKET_API 00204 00205 /*#8*/ 00206 result = pal_getNumberOfNetInterfaces(&numInterface); 00207 TEST_ASSERT_NOT_EQUAL(numInterface, 0); 00208 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00209 00210 /*#9*/ 00211 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO , &sockOptVal, sockOptLen); 00212 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00213 00214 /*#10*/ 00215 result = pal_isNonBlocking(g_testSockets[0],&isNonBlocking); 00216 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00217 TEST_ASSERT_EQUAL_HEX(isNonBlocking, false); 00218 00219 result = pal_isNonBlocking(g_testSockets[3], &isNonBlocking); 00220 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00221 TEST_ASSERT_EQUAL_HEX(isNonBlocking, true); 00222 00223 /*#11*/ 00224 result = pal_getAddressInfo("0.0.0.0", &address, &addrlen); 00225 TEST_ASSERT_EQUAL_HEX(PAL_ERR_SOCKET_DNS_ERROR , result); 00226 00227 /*#12*/ 00228 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 00229 result = pal_close(&g_testSockets[2]); 00230 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00231 00232 #endif // PAL_NET_ASYNCHRONOUS_SOCKET_API 00233 00234 result = pal_close(&g_testSockets[0]); 00235 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00236 result = pal_close(&g_testSockets[1]); 00237 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00238 result = pal_close(&g_testSockets[3]); 00239 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00240 result = pal_close(&g_testSockets[3]); //double close - should succeed 00241 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00242 } 00243 00244 00245 /*! \brief Test TCP socket creation, connection, send and receive with a test server. 00246 * 00247 ** \test 00248 * | # | Step | Expected | 00249 * |---|--------------------------------|-------------| 00250 * | 1 | Create a blocking TCP socket using `pal_socket`. | PAL_SUCCESS | 00251 * | 2 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 00252 * | 3 | Set the port to a test port in the address structure using `pal_setSockAddrPort` and set timeout. | PAL_SUCCESS | 00253 * | 4 | Connect the socket to the test server using `pal_connect`. | PAL_SUCCESS | 00254 * | 5 | Send a test message (short HTTP request) to the test server using `pal_send`. | PAL_SUCCESS | 00255 * | 6 | Receive (blocking) the server's response using `pal_recv` and check it is HTTP. | PAL_SUCCESS | 00256 * | 7 | Close the socket. | PAL_SUCCESS | 00257 */ 00258 TEST(pal_socket, basicTCPclientSendRecieve) 00259 { 00260 palStatus_t result = PAL_SUCCESS; 00261 palSocketAddress_t address = { 0 }; 00262 const char message[] = "GET / HTTP/1.0\r\n\r\n"; 00263 size_t sent = 0; 00264 char buffer[100] = { 0 }; 00265 size_t read = 0; 00266 palSocketLength_t addrlen = 0; 00267 int timeout = PAL_MILLI_PER_SECOND; 00268 00269 /*#1*/ 00270 00271 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, &g_testSockets[0]); 00272 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00273 00274 /*#2*/ 00275 result = pal_getAddressInfo(PAL_NET_TEST_SERVER_NAME, &address, &addrlen); 00276 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00277 00278 /*#3*/ 00279 result = pal_setSockAddrPort(&address, PAL_NET_TEST_SERVER_HTTP_PORT); 00280 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00281 00282 00283 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_SNDTIMEO , &timeout, sizeof(timeout)); 00284 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00285 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO , &timeout, sizeof(timeout)); 00286 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00287 00288 00289 /*#4*/ 00290 result = pal_connect(g_testSockets[0], &address, 16); 00291 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00292 00293 /*#5*/ 00294 result = pal_send(g_testSockets[0], message, sizeof(message) - 1, &sent); 00295 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00296 00297 /*#6*/ 00298 result = pal_recv(g_testSockets[0], buffer, 99, &read); 00299 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00300 00301 TEST_ASSERT(read >= 4); 00302 TEST_ASSERT(buffer[0] == 'H' && buffer[1] == 'T'&& buffer[2] == 'T' && buffer[3] == 'P'); 00303 00304 /*#7*/ 00305 pal_close(&g_testSockets[0]); 00306 00307 } 00308 00309 /*! \brief Test UDP socket creation, connection, send and recieve with a test server. 00310 * 00311 ** \test 00312 * | # | Step | Expected | 00313 * |---|--------------------------------|-------------| 00314 * | 1 | Create a blocking UDP 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`. | PAL_SUCCESS | 00317 * | 4 | Connect the socket to the test server using `pal_connect`. | PAL_SUCCESS | 00318 * | 5 | Send a test message (short DNS request) to the test server using `pal_send`. | PAL_SUCCESS | 00319 * | 6 | Receive (blocking) the server's response using `pal_recv`. | PAL_SUCCESS | 00320 * | 7 | Close the socket. | PAL_SUCCESS | 00321 */ 00322 TEST(pal_socket, basicUDPclientSendRecieve) 00323 { 00324 palStatus_t result = PAL_SUCCESS; 00325 palSocketAddress_t address = { 0 }; 00326 palSocketAddress_t address2 = { 0 }; 00327 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 }; 00328 uint8_t buffer_in[10]; 00329 size_t sent = 0; 00330 size_t read = 0; 00331 size_t socket_timeout_ms = 5000; 00332 palSocketLength_t addrlen = 0; 00333 00334 /*#1*/ 00335 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM , 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_UDP, &address, &addrlen); 00340 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00341 00342 /*#3*/ 00343 result = pal_setSockAddrPort(&address, PAL_NET_TEST_SERVER_UDP_PORT); 00344 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00345 00346 /*#4*/ 00347 //We set a timeout for receiving so we won't get stuck in the test 00348 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO , &socket_timeout_ms, sizeof(socket_timeout_ms)); 00349 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00350 00351 /*#5*/ 00352 result = pal_sendTo(g_testSockets[0], buffer, sizeof(buffer), &address, 16, &sent); 00353 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00354 TEST_ASSERT_EQUAL(sent, sizeof(buffer)); 00355 00356 /*#6*/ 00357 result = pal_receiveFrom(g_testSockets[0], buffer_in, 10, &address2, &addrlen, &read); 00358 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00359 TEST_ASSERT_EQUAL(read, 10); 00360 00361 /*#7*/ 00362 pal_close(&g_testSockets[0]); 00363 } 00364 00365 00366 00367 00368 // This is an example showing how to check for a socket that has been closed remotely. 00369 #if 0 00370 PAL_PRIVATE void basicSocketScenario3Callback(void * arg) 00371 { 00372 char buffer[400]; 00373 size_t read = 0; 00374 palStatus_t result; 00375 00376 00377 s_callbackcounter++; 00378 result = pal_recv(g_testSockets[0], buffer, 999, &read); 00379 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00380 // If 0 bytes are read it means that the peer has performed an orderly shutdown so we must close the socket 00381 // to avoid ppoll from checking it. Checking a socket whose other end has been shut down causes ppoll to immediately return 00382 // with events == 0x1. 00383 if(read == 0) 00384 { 00385 pal_close(&g_testSockets[0]); 00386 } 00387 else 00388 { 00389 buffer[read] = '\0'; 00390 if(s_callbackcounter == 0) 00391 { 00392 TEST_ASSERT(read >= 4); 00393 TEST_ASSERT(buffer[0] == 'H' && buffer[1] == 'T'&& buffer[2] == 'T' && buffer[3] == 'P'); 00394 } 00395 } 00396 00397 } 00398 #endif 00399 palSemaphoreID_t s_semaphoreID = NULLPTR; 00400 00401 PAL_PRIVATE void socketCallback2(void * arg) 00402 { 00403 palStatus_t result; 00404 if(s_callbackcounter == 0) 00405 { 00406 result = pal_osSemaphoreRelease(s_semaphoreID); 00407 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00408 } 00409 s_callbackcounter++; 00410 00411 } 00412 00413 static int s_secondCallbackCounter = 0; 00414 PAL_PRIVATE void socketCallbackErr(void * arg) 00415 { 00416 s_secondCallbackCounter++; 00417 } 00418 00419 /*! \brief Test asynchronous socket callbacks. 00420 * 00421 ** \test 00422 * | # | Step | Expected | 00423 * |---|--------------------------------|-------------| 00424 * | 1 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 00425 * | 2 | Create a blocking asynchronous TCP socket with `socketCallback2` as callback. | PAL_SUCCESS | 00426 * | 3 | Set port to a test port in the address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 00427 * | 4 | Connect the socket to the test server using `pal_connect`. | PAL_SUCCESS | 00428 * | 5 | Send a test message (short HTTP request) to the test server using `pal_send`. | PAL_SUCCESS | 00429 * | 6 | Wait for a callback to release the semaphore when the response arrives. | PAL_SUCCESS | 00430 * | 7 | Receive (blocking) the server's response using `pal_recv` and check that the response is HTTP.| PAL_SUCCESS | 00431 * | 8 | Close the socket. | PAL_SUCCESS | 00432 */ 00433 TEST(pal_socket, basicSocketScenario3) 00434 { 00435 palStatus_t result = PAL_SUCCESS; 00436 palSocketAddress_t address = { 0 }; 00437 const char* message = "GET / HTTP/1.0\r\nHost:10.45.48.68:8000\r\n\r\n"; 00438 size_t sent = 0; 00439 char buffer[100] = { 0 }; 00440 size_t read = 0; 00441 s_callbackcounter = 0; 00442 palSocketLength_t addrlen = 0; 00443 int32_t countersAvailable; 00444 00445 result = pal_osSemaphoreCreate(1, &s_semaphoreID); 00446 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00447 result = pal_osSemaphoreWait(s_semaphoreID, 40000, &countersAvailable); 00448 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00449 00450 /*#1*/ 00451 result = pal_getAddressInfo(PAL_NET_TEST_SERVER_NAME, &address, &addrlen); 00452 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00453 00454 00455 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 00456 /*#2*/ 00457 result = pal_asynchronousSocketWithArgument(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, socketCallback2, "socketCallback2Arg", &g_testSockets[0]); 00458 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00459 00460 s_secondCallbackCounter = 0; 00461 result = pal_asynchronousSocketWithArgument(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, socketCallbackErr, "socketCallback2Arg", &g_testSockets[1]); 00462 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00463 00464 TEST_ASSERT_EQUAL_HEX(0, s_secondCallbackCounter); 00465 /*#3*/ 00466 result = pal_setSockAddrPort(&address, PAL_NET_TEST_SERVER_HTTP_PORT); 00467 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00468 00469 /*#4*/ 00470 result = pal_connect(g_testSockets[0], &address, 16); 00471 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00472 00473 TEST_ASSERT_EQUAL_HEX(0, s_secondCallbackCounter); 00474 /*#5*/ 00475 result = pal_send(g_testSockets[0], message, strlen(message), &sent); 00476 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00477 00478 TEST_ASSERT_EQUAL_HEX(0, s_secondCallbackCounter); 00479 // Give a chance for the callback to be called. 00480 /*#6*/ 00481 result=pal_osSemaphoreWait(s_semaphoreID, 40000, &countersAvailable); 00482 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00483 00484 result=pal_osSemaphoreDelete(&s_semaphoreID); 00485 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00486 00487 /*#7*/ 00488 result = pal_recv(g_testSockets[0], buffer, 99, &read); 00489 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00490 TEST_ASSERT(read >= 4); 00491 TEST_ASSERT(buffer[0] == 'H' && buffer[1] == 'T'&& buffer[2] == 'T' && buffer[3] == 'P'); 00492 TEST_ASSERT(s_callbackcounter > 0); 00493 00494 00495 TEST_ASSERT_EQUAL_HEX(0, s_secondCallbackCounter); 00496 /*#8*/ 00497 pal_close(&g_testSockets[0]); 00498 #endif // PAL_NET_ASYNCHRONOUS_SOCKET_API 00499 } 00500 00501 typedef struct palNetTestThreadData{ 00502 palSemaphoreID_t sem1; 00503 palSemaphoreID_t sem2; 00504 uint16_t port; 00505 } palNetTestThreadData_t; 00506 00507 char s_rcv_buffer[20] = {0}; 00508 char s_rcv_buffer2[50] = {0}; 00509 00510 void palNetClientFunc(void const *argument) 00511 { 00512 palStatus_t result = PAL_SUCCESS; 00513 int32_t tmp = 0; 00514 size_t sent = 0; 00515 size_t read = 0; 00516 palNetTestThreadData_t* dualSem = (palNetTestThreadData_t*)argument; 00517 palSocketLength_t addrlen = 16; 00518 //palSocketAddress_t address = { 0 }; 00519 palNetInterfaceInfo_t interfaceInfo; 00520 const char* message = "GET / HTTP/1.0\r\n\r\n"; 00521 00522 /*#C1*/ 00523 result = pal_osSemaphoreWait(dualSem->sem1, 500, &tmp); 00524 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00525 00526 /*#C2*/ 00527 result = pal_getNetInterfaceInfo(PAL_NET_TEST_LOCAL_LOOPBACK_IF_INDEX, &interfaceInfo); 00528 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00529 00530 /*#C3*/ 00531 uint16_t incoming_port = dualSem->port; 00532 PAL_PRINTF("client port = %u", incoming_port); 00533 result = pal_setSockAddrPort(&(interfaceInfo.address), incoming_port); 00534 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00535 00536 /*#C4*/ 00537 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, &g_testSockets[2]); 00538 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00539 00540 /*#C5*/ 00541 result = pal_connect(g_testSockets[2], &(interfaceInfo.address), addrlen); 00542 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00543 00544 /*#C6*/ 00545 result = pal_send(g_testSockets[2], message, 18, &sent); 00546 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00547 00548 /*#C7*/ 00549 result = pal_recv(g_testSockets[2], s_rcv_buffer, 15, &read); 00550 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00551 00552 /*#C8*/ 00553 pal_close(&g_testSockets[2]); 00554 00555 result = pal_osSemaphoreRelease(dualSem->sem2); 00556 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00557 } 00558 00559 /*! \brief /b ServerSocketScenario tests a TCP client-server scenario using device loopback. 00560 * 00561 * \note The test steps are divided into those in the server main thread (S1..S13) and those in the client thread (C1..C8). 00562 * The sequence below is an approximation of the actual order of execution. 00563 * 00564 ** \test 00565 * | # | Step | Expected | 00566 * |---|--------------------------------|-------------| 00567 * | S1 | Create a blocking TCP server socket using `pal_socket`. | PAL_SUCCESS | 00568 * | S2 | Create a blocking TCP socket using `pal_socket`. | PAL_SUCCESS | 00569 * | S3 | Look up the IP address of loopback using `pal_getAddressInfo`. | PAL_SUCCESS | 00570 * | S4 | Set the port to test port in address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 00571 * | S5 | Bind the server socket to the port and address using `pal_bind`. | PAL_SUCCESS | 00572 * | S6 | Create synchronization sepmaphores and set count to 0. | PAL_SUCCESS | 00573 * | S7 | Create a client thread with `BelowNormal` priority running `palNetClientFunc`. | PAL_SUCCESS | 00574 * | C1 | Client thread blocks on client sepmaphore s1. | PAL_SUCCESS | 00575 * | S8 | Listen to the server port using `pal_listen`. | PAL_SUCCESS | 00576 * | S9 | Release the client sepmahore s1. | PAL_SUCCESS | 00577 * | S10 | Call `accept` (blocking) to accept a new connection (retry in case of failure). | PAL_SUCCESS | 00578 * | C2 | Look up the IP address of the loopback using `pal_getAddressInfo`. | PAL_SUCCESS | 00579 * | C3 | Set the port to test port in the address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 00580 * | C4 | Create a blocking TCP socket using `pal_socket`. | PAL_SUCCESS | 00581 * | C5 | Connect to the server using `pal_connect`. | PAL_SUCCESS | 00582 * | C6 | Send data to server. | PAL_SUCCESS | 00583 * | S11 | Receive data from the client. | PAL_SUCCESS | 00584 * | S12 | Send data to the client. | PAL_SUCCESS | 00585 * | C7 | Receive data from the server. | PAL_SUCCESS | 00586 * | C8 | Client thread cleanup - close the socket and release the semaphore. | PAL_SUCCESS | 00587 * | S13 | Cleanup: close sockets and delete semaphores. | PAL_SUCCESS | 00588 */ 00589 00590 TEST(pal_socket, ServerSocketScenario) 00591 { 00592 palStatus_t result = PAL_SUCCESS; 00593 palSocketAddress_t address2 = { 0 }; 00594 const char* messageOut = "HTTP/1.0 200 OK"; 00595 size_t sent = 0; 00596 size_t read = 0; 00597 palSocketLength_t addrlen = 16; 00598 00599 palSemaphoreID_t semaphoreID = NULLPTR; 00600 palSemaphoreID_t semaphoreID2 = NULLPTR; 00601 palNetTestThreadData_t dualSem = {0}; 00602 palThreadID_t threadID1 = NULLPTR; 00603 int32_t tmp = 0; 00604 palNetInterfaceInfo_t interfaceInfo; 00605 memset(&interfaceInfo,0,sizeof(interfaceInfo)); 00606 00607 00608 /*#S1*/ 00609 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM_SERVER , false, 0, &g_testSockets[0]); 00610 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00611 00612 /*#S2*/ 00613 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, &g_testSockets[1]); 00614 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00615 00616 /*#S3*/ 00617 result = pal_getNetInterfaceInfo(PAL_NET_TEST_LOCAL_LOOPBACK_IF_INDEX, &interfaceInfo); 00618 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00619 00620 PAL_PRINTF("interface addr: %u %u %u %u \r\n", 00621 (unsigned char)interfaceInfo.address.addressData[2], 00622 (unsigned char)interfaceInfo.address.addressData[3], 00623 (unsigned char)interfaceInfo.address.addressData[4], 00624 (unsigned char)interfaceInfo.address.addressData[5]);; 00625 /*#S4*/ 00626 uint32_t rand_number = 0; 00627 uint16_t incoming_port; 00628 00629 for (int i=0; i<5; i++) { 00630 pal_osRandomBuffer((uint8_t*)&rand_number, sizeof(rand_number)); 00631 incoming_port = (uint16_t)(35400 + (rand_number % (40000 - 35400))); 00632 PAL_PRINTF("server port = %u", incoming_port); 00633 00634 result = pal_setSockAddrPort(&(interfaceInfo.address), incoming_port); 00635 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00636 00637 /*#S5*/ 00638 result = pal_bind(g_testSockets[0], &(interfaceInfo.address), interfaceInfo.addressSize); 00639 00640 if (PAL_SUCCESS == result) { 00641 PAL_PRINTF("bind succeeded on port %u", incoming_port); 00642 break; 00643 } else { 00644 PAL_PRINTF("bind failed on port %u", incoming_port); 00645 } 00646 } 00647 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00648 00649 /*#S6*/ 00650 00651 // start client thread to connect to the server. 00652 result = pal_osSemaphoreCreate(1 ,&semaphoreID); 00653 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00654 result = pal_osSemaphoreWait(semaphoreID, 1000, &tmp); 00655 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00656 00657 00658 result = pal_osSemaphoreCreate(1 ,&semaphoreID2); 00659 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00660 result = pal_osSemaphoreWait(semaphoreID2, 1000, &tmp); 00661 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00662 00663 dualSem.sem1 = semaphoreID; 00664 dualSem.sem2 = semaphoreID2; 00665 dualSem.port = incoming_port; 00666 00667 /*#S7*/ 00668 result = pal_osThreadCreateWithAlloc(palNetClientFunc, &dualSem , PAL_osPriorityBelowNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &threadID1); 00669 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00670 00671 /*#S8*/ 00672 result = pal_listen(g_testSockets[0], 10); 00673 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00674 00675 /*#S9*/ 00676 result = pal_osSemaphoreRelease(dualSem.sem1); 00677 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00678 00679 00680 PAL_PRINTF("waiting for connection:\r\n"); 00681 /*#S10*/ 00682 result = pal_accept(g_testSockets[0], &address2, &addrlen, &g_testSockets[1]); 00683 PAL_PRINTF("after accept: %" PRIu32 "\r\n", result); 00684 if (PAL_SUCCESS != result ) 00685 { 00686 result = pal_accept(g_testSockets[0], &address2, &addrlen, &g_testSockets[1]); 00687 PAL_PRINTF("after accept: %" PRIu32 "\r\n",result); 00688 } 00689 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00690 00691 /*#S11*/ 00692 result = pal_recv(g_testSockets[1], s_rcv_buffer2, 49, &read); 00693 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00694 00695 /*#S12*/ 00696 result = pal_send(g_testSockets[1], messageOut, 15, &sent); 00697 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00698 00699 00700 //cleanup 00701 00702 /*#S13*/ 00703 pal_close(&g_testSockets[1]); 00704 pal_close(&g_testSockets[0]); 00705 00706 result = pal_osSemaphoreWait(semaphoreID2, 5000, &tmp); 00707 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00708 pal_osDelay(2000); 00709 pal_osThreadTerminate(&threadID1); 00710 result = pal_osSemaphoreDelete(&semaphoreID); 00711 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00712 TEST_ASSERT_EQUAL_HEX(NULLPTR, semaphoreID); 00713 00714 result = pal_osSemaphoreDelete(&semaphoreID2); 00715 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00716 TEST_ASSERT_EQUAL_HEX(NULLPTR, semaphoreID2); 00717 } 00718 00719 00720 00721 PAL_PRIVATE volatile uint32_t s_callbackCounterNonBlock = 0; 00722 00723 PAL_PRIVATE void nonBlockCallback(void * arg) 00724 { 00725 s_callbackCounterNonBlock++; 00726 } 00727 00728 #define PAL_NET_TEST_HTTP_HEADER_LEN 5 00729 00730 /*! \brief /b nonBlockingAsyncTest checks the asynchronous- nonblocking socket scenario. 00731 ** \test 00732 * | # | Step | Expected | 00733 * |---|--------------------------------|-------------| 00734 * | 1 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 00735 * | 2 | Create an asynchronous non-blocking TCP socket with `nonBlockCallback` as callback. | PAL_SUCCESS | 00736 * | 3 | Set the port to test port in the address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 00737 * | 4 | Connect the socket. | PAL_SUCCESS or PAL_ERR_SOCKET_IN_PROGRES | 00738 * | 5 | Send a test message to the test server using `pal_send` (repeat until success). | PAL_SUCCESS or PAL_ERR_SOCKET_IN_PROGRES | 00739 * | 6 | Wait for the callback and receive server response using `pal_recv` (repeat until success). | PAL_SUCCESS or PAL_ERR_SOCKET_WOULD_BLOCK| 00740 * | 7 | Close the socket. | PAL_SUCCESS | 00741 */ 00742 TEST(pal_socket, nonBlockingAsyncTest) 00743 { 00744 palStatus_t result = PAL_SUCCESS; 00745 palSocketAddress_t address = { 0 }; 00746 const char* message = "GET / HTTP/1.0\r\nHost:10.45.48.68:8000\r\n\r\n"; 00747 size_t sent = 0; 00748 char buffer[100] = { 0 }; 00749 size_t read = 0; 00750 s_callbackcounter = 0; 00751 palSocketLength_t addrlen = 0; 00752 int32_t waitIterations = 0; 00753 00754 /*#1*/ 00755 result = pal_getAddressInfo(PAL_NET_TEST_SERVER_NAME, &address, &addrlen); 00756 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00757 00758 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 00759 /*#2*/ 00760 result = pal_asynchronousSocketWithArgument(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, nonBlockCallback, "non-blockSocketCallbackArg", &g_testSockets[0]); 00761 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00762 00763 /*#3*/ 00764 result = pal_setSockAddrPort(&address, PAL_NET_TEST_SERVER_HTTP_PORT); 00765 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00766 00767 /*#4*/ 00768 result = pal_connect(g_testSockets[0], &address, 16); 00769 if (PAL_ERR_SOCKET_IN_PROGRES == result) 00770 { 00771 result = pal_connect(g_testSockets[0], &address, 16); 00772 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) 00773 { 00774 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00775 } 00776 pal_osDelay(400); 00777 } 00778 else 00779 { 00780 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00781 } 00782 s_callbackCounterNonBlock = 0; 00783 00784 /*#5*/ 00785 result = pal_send(g_testSockets[0], message, strlen(message), &sent); 00786 00787 while (PAL_ERR_SOCKET_IN_PROGRES == result) 00788 { 00789 pal_osDelay(100); 00790 result = pal_send(g_testSockets[0], message, strlen(message), &sent); 00791 } 00792 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00793 00794 /*#6*/ 00795 result = pal_recv(g_testSockets[0], buffer, PAL_NET_TEST_HTTP_HEADER_LEN, &read); // may block 00796 while ((PAL_ERR_SOCKET_WOULD_BLOCK == result) && (10 > waitIterations )) 00797 { 00798 s_callbackCounterNonBlock = 0; 00799 while (s_callbackCounterNonBlock == 0) 00800 { 00801 waitIterations++; 00802 pal_osDelay(100); 00803 } 00804 result = pal_recv(g_testSockets[0], buffer, PAL_NET_TEST_HTTP_HEADER_LEN, &read); // shouldnt block 00805 } 00806 00807 /*#7*/ 00808 pal_close(&g_testSockets[0]); 00809 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00810 TEST_ASSERT(read >= 4); 00811 TEST_ASSERT(buffer[0] == 'H' && buffer[1] == 'T'&& buffer[2] == 'T' && buffer[3] == 'P'); 00812 TEST_ASSERT(s_callbackCounterNonBlock > 0); 00813 00814 #endif // PAL_NET_ASYNCHRONOUS_SOCKET_API 00815 } 00816 00817 /*! \brief /b tProvUDPTest tests UDP socket send/receive and checks that we get the correct error for receive timeout. 00818 ** \test 00819 * | # | Step | Expected | 00820 * |---|--------------------------------|-------------| 00821 * | 1 | Create a blocking UDP socket using `pal_socket`. | PAL_SUCCESS | 00822 * | 2 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 00823 * | 3 | Set the port to test port in the address structure using `pal_setSockAddrPort`. | PAL_SUCCESS | 00824 * | 4 | Set socket timeouts using `pal_setSocketOptions`. | PAL_SUCCESS | 00825 * | 5 | Send a test message (short HTTP request) to test the server using `pal_send`. | PAL_SUCCESS | 00826 * | 6 | Receive the (blocking) server response using `pal_recv`. | PAL_SUCCESS | 00827 * | 7 | Receive the (blocking) server response again using `pal_recv` and fail. | PAL_ERR_SOCKET_WOULD_BLOCK | 00828 * | 8 | Close the socket. | PAL_SUCCESS | 00829 */ 00830 TEST(pal_socket, tProvUDPTest) 00831 { 00832 palStatus_t result = PAL_SUCCESS; 00833 palSocketAddress_t address = { 0,{0} }; 00834 uint8_t buffer[100] = { 0 }; 00835 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 }; 00836 size_t sent = 0; 00837 size_t read = 0; 00838 palSocketLength_t addrlen = 16; 00839 int timeout = PAL_MILLI_PER_SECOND; 00840 00841 /*#1*/ 00842 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM , false, 0, &g_testSockets[0]); 00843 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00844 00845 /*#2*/ 00846 result = pal_getAddressInfo(PAL_NET_TEST_SERVER_NAME_UDP, &address, &addrlen); 00847 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00848 00849 /*#3*/ 00850 result = pal_setSockAddrPort(&address, PAL_NET_TEST_SERVER_UDP_PORT); 00851 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00852 00853 /*#4*/ 00854 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_SNDTIMEO , &timeout, sizeof(timeout)); 00855 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00856 00857 timeout = 1000; 00858 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO , &timeout, sizeof(timeout)); 00859 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00860 00861 /*#5*/ 00862 result = pal_sendTo(g_testSockets[0], buffer_dns, sizeof(buffer_dns), &address, addrlen, &sent); 00863 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00864 TEST_ASSERT_EQUAL_HEX(sent, sizeof(buffer_dns)); 00865 00866 /*#6*/ 00867 result = pal_receiveFrom(g_testSockets[0], buffer, 16, NULL, NULL, &read); 00868 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 00869 TEST_ASSERT_EQUAL(read, 16); 00870 00871 /*#7*/ 00872 result = pal_receiveFrom(g_testSockets[0], buffer, 100, NULL, NULL, &read); // should get timeout 00873 TEST_ASSERT_EQUAL_HEX(result, PAL_ERR_SOCKET_WOULD_BLOCK ); 00874 00875 /*#8*/ 00876 pal_close(&g_testSockets[0]); 00877 } 00878 00879 PAL_PRIVATE void fillUDPTestBuffer(pal_udp_test_data_t *data, uint8_t* buffer) 00880 { 00881 memset(buffer, 0, data->bufferSize); 00882 data->chunkSize = (data->messageSize - data->totalSize > data->bufferSize) ? data->bufferSize : (data->messageSize - data->totalSize); 00883 memset(buffer, ++(data->currentValue), data->chunkSize); 00884 data->totalSize += data->chunkSize; 00885 } 00886 00887 // UDP test sender thread function. 00888 PAL_PRIVATE void socketUDPBufferedTestSender(const void *arg) 00889 { 00890 palStatus_t result = PAL_SUCCESS; 00891 pal_udp_test_data_t *data = (pal_udp_test_data_t*)arg; // cast from const to non-const 00892 size_t sent = 0, totalSent = 0; 00893 00894 g_testSendBuffer = (uint8_t*)malloc(sizeof(uint8_t) * data->bufferSize); 00895 TEST_ASSERT_NOT_EQUAL(NULLPTR, g_testSendBuffer); 00896 00897 data->totalSize = 0; 00898 data->chunkSize = 0; 00899 data->currentValue = data->startValue; 00900 while (totalSent != data->messageSize) 00901 { 00902 fillUDPTestBuffer(data, g_testSendBuffer); 00903 result = pal_sendTo(g_testSockets[0], g_testSendBuffer, data->chunkSize, &(data->interfaceInfo.address), data->interfaceInfo.addressSize, &sent); 00904 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00905 totalSent += sent; 00906 pal_osDelay(5); // allow some time for the RX bits to be set 00907 }; 00908 00909 free(g_testSendBuffer); 00910 g_testSendBuffer = NULLPTR; 00911 } 00912 00913 /*! \brief Test UDP socket read in chunks 00914 * 00915 * \note The test generates data and calculates its hash, then this data is re-generated from a dedicated thread and 00916 * received on the current thread which calculates the received data hash and compares it to the original hash 00917 * 00918 * @param[in] bufSize - the read buffer size 00919 * 00920 ** \test 00921 * | # | Step | Expected | 00922 * |---|--------------------------------|-------------| 00923 * | 1 | Initialize the MD context. | PAL_SUCCESS | 00924 * | 2 | Allocate buffer. | PAL_SUCCESS | 00925 * | 3 | Generate data incrementally and update the MD context. | PAL_SUCCESS | 00926 * | 4 | Get the hash output size and validate it. | PAL_SUCCESS | 00927 * | 5 | Get the calculated hash. | PAL_SUCCESS | 00928 * | 6 | Free the MD context resources. | PAL_SUCCESS | 00929 * | 7 | Get the interface address. | PAL_SUCCESS | 00930 * | 8 | Create a (blocking) UDP socket. | PAL_SUCCESS | 00931 * | 9 | Set the socket port and set send/receive timeouts. | PAL_SUCCESS | 00932 * | 10 | Bind the socket. | PAL_SUCCESS | 00933 * | 11 | Initialize the MD context. | PAL_SUCCESS | 00934 * | 12 | Launch the data sender thread. | PAL_SUCCESS | 00935 * | 13 | Read data from the socket until there's no more data or all data has been received. | PAL_SUCCESS | 00936 * | 14 | Update the MD context. | PAL_SUCCESS | 00937 * | 15 | Terminate the sending thread. | PAL_SUCCESS | 00938 * | 16 | Close the socket. | PAL_SUCCESS | 00939 * | 17 | Get the hash output size and validate it. | PAL_SUCCESS | 00940 * | 18 | Get the calculated hash and compare it. | PAL_SUCCESS | 00941 * | 19 | Free the MD context resources. | PAL_SUCCESS | 00942 * | 20 | Free allocated buffer. | PAL_SUCCESS | 00943 */ 00944 PAL_PRIVATE void socketUDPBuffered(size_t bufSize) 00945 { 00946 palStatus_t result = PAL_SUCCESS; 00947 pal_udp_test_data_t data = { PAL_NET_TEST_BUFFERED_UDP_MESSAGE_SIZE, bufSize, 0 }; 00948 uint8_t expectedHash[PAL_SHA256_SIZE] = { 0 }, actualHash[PAL_SHA256_SIZE] = { 0 }; 00949 size_t read = 0, totalRead = 0, hashlen = 0; 00950 int timeout = PAL_MILLI_PER_SECOND; 00951 palMDHandle_t handle = NULLPTR; 00952 palThreadID_t thread = NULLPTR; 00953 00954 /*#1*/ 00955 result = pal_mdInit(&handle, PAL_SHA256); 00956 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00957 TEST_ASSERT_NOT_EQUAL(NULLPTR, handle); 00958 00959 /*#2*/ 00960 g_testRecvBuffer = (uint8_t*)malloc(sizeof(uint8_t) * bufSize); 00961 TEST_ASSERT_NOT_EQUAL(NULLPTR, g_testRecvBuffer); 00962 00963 /*#3*/ 00964 data.totalSize = data.chunkSize = 0; 00965 data.currentValue = data.startValue; 00966 while (data.totalSize != data.messageSize) 00967 { 00968 fillUDPTestBuffer(&data, g_testRecvBuffer); 00969 result = pal_mdUpdate(handle, g_testRecvBuffer, data.chunkSize); 00970 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00971 }; 00972 00973 /*#4*/ 00974 result = pal_mdGetOutputSize(handle, &hashlen); 00975 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00976 TEST_ASSERT_EQUAL_HEX(PAL_SHA256_SIZE, hashlen); 00977 00978 /*#5*/ 00979 result = pal_mdFinal(handle, expectedHash); 00980 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00981 00982 /*#6*/ 00983 result = pal_mdFree(&handle); 00984 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00985 00986 /*#7*/ 00987 memset(&(data.interfaceInfo), 0, sizeof(data.interfaceInfo)); 00988 result = pal_getNetInterfaceInfo(0, &(data.interfaceInfo)); 00989 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00990 00991 /*#8*/ 00992 result = pal_socket(PAL_AF_INET, PAL_SOCK_DGRAM , false, 0, &g_testSockets[0]); 00993 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00994 00995 /*#9*/ 00996 result = pal_setSockAddrPort(&(data.interfaceInfo.address), PAL_NET_TEST_BUFFERED_UDP_PORT); 00997 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00998 00999 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO , &timeout, sizeof(timeout)); 01000 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01001 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_SNDTIMEO , &timeout, sizeof(timeout)); 01002 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01003 01004 /*#10*/ 01005 result = pal_bind(g_testSockets[0], &(data.interfaceInfo.address), data.interfaceInfo.addressSize); 01006 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01007 01008 /*#11*/ 01009 handle = NULLPTR; 01010 result = pal_mdInit(&handle, PAL_SHA256); 01011 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01012 TEST_ASSERT_NOT_EQUAL(NULLPTR, handle); 01013 01014 /*#12*/ 01015 result = pal_osThreadCreateWithAlloc(socketUDPBufferedTestSender, &data, PAL_osPriorityNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &thread); 01016 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01017 TEST_ASSERT_NOT_EQUAL(NULLPTR, thread); 01018 01019 /*#13*/ 01020 do 01021 { 01022 read = 0; 01023 memset(g_testRecvBuffer, 0, data.bufferSize); 01024 result = pal_receiveFrom(g_testSockets[0], g_testRecvBuffer, data.bufferSize, &(data.interfaceInfo.address), &(data.interfaceInfo.addressSize), &read); 01025 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01026 /*#14*/ 01027 result = pal_mdUpdate(handle, g_testRecvBuffer, read); 01028 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01029 totalRead += read; 01030 } while (read > 0 && totalRead < data.messageSize); 01031 01032 /*#15*/ 01033 result = pal_osThreadTerminate(&thread); 01034 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01035 01036 /*#16*/ 01037 result = pal_close(&g_testSockets[0]); 01038 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01039 01040 /*#17*/ 01041 hashlen = 0; 01042 result = pal_mdGetOutputSize(handle, &hashlen); 01043 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01044 TEST_ASSERT_EQUAL_HEX(PAL_SHA256_SIZE, hashlen); 01045 01046 /*#18*/ 01047 result = pal_mdFinal(handle, actualHash); 01048 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01049 TEST_ASSERT_EQUAL_MEMORY(expectedHash, actualHash, PAL_SHA256_SIZE); 01050 01051 /*#19*/ 01052 result = pal_mdFree(&handle); 01053 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01054 01055 /*#20*/ 01056 free(g_testRecvBuffer); 01057 g_testRecvBuffer = NULLPTR; 01058 } 01059 01060 /*! \brief Test function UDP socket read in small chunks 01061 * 01062 ** \test 01063 */ 01064 TEST(pal_socket, socketUDPBufferedSmall) 01065 { 01066 socketUDPBuffered(PAL_NET_TEST_BUFFERED_UDP_BUF_SIZE_SMALL); 01067 } 01068 01069 /*! \brief Test function UDP socket read in large chunks 01070 * 01071 ** \test 01072 */ 01073 TEST(pal_socket, socketUDPBufferedLarge) 01074 { 01075 socketUDPBuffered(PAL_NET_TEST_BUFFERED_UDP_BUF_SIZE_LARGE); 01076 } 01077 01078 #ifdef __LINUX__ // Linux CI tests for socketTCPBufferedSmall & socketTCPBufferedLarge must use an ipv4 address in order to connect to the external host 01079 PAL_PRIVATE palStatus_t getAddressInfoIPv4(char const *url, palSocketAddress_t *address, palSocketLength_t* addressLength) 01080 { 01081 struct addrinfo *info = NULLPTR; 01082 struct addrinfo hints = { 0 }; 01083 struct sockaddr_in *sockAddress = NULLPTR; 01084 palIpV4Addr_t ipV4Address = { 0 }; 01085 int ret; 01086 palStatus_t result; 01087 01088 hints.ai_family = AF_INET; 01089 ret = getaddrinfo(url, NULL, &hints, &info); 01090 TEST_ASSERT_EQUAL(0, ret); 01091 TEST_ASSERT_NOT_EQUAL(NULLPTR, info); 01092 TEST_ASSERT_EQUAL(AF_INET, info->ai_family); 01093 01094 sockAddress = (struct sockaddr_in*)info->ai_addr; 01095 memcpy(ipV4Address, &(sockAddress->sin_addr), PAL_IPV4_ADDRESS_SIZE); 01096 freeaddrinfo(info); 01097 01098 result = pal_setSockAddrIPV4Addr(address, ipV4Address); 01099 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01100 *addressLength = sizeof(struct sockaddr_in); 01101 return result; 01102 } 01103 #endif 01104 01105 /*! \brief Test TCP socket read in chunks 01106 * 01107 * \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. 01108 * 01109 * @param[in] bufSize - the read buffer size 01110 * 01111 ** \test 01112 * | # | Step | Expected | 01113 * |---|--------------------------------|-------------| 01114 * | 1 | Create a (blocking) TCP socket. | PAL_SUCCESS | 01115 * | 2 | Look up the IP address of the CDN server. | PAL_SUCCESS | 01116 * | 3 | Set the port to the CDN server's HTTP port and set send/receive timeouts. | PAL_SUCCESS | 01117 * | 4 | Connect the socket to the CDN server. | PAL_SUCCESS | 01118 * | 5 | Send an HTTP get request to the CDN server. | PAL_SUCCESS | 01119 * | 6 | Initialize the MD context. | PAL_SUCCESS | 01120 * | 7 | Allocate HTTP response buffer. | PAL_SUCCESS | 01121 * | 8 | Read the server's response until there's no more data to read. | PAL_SUCCESS | 01122 * | 9 | If we're done dealing with the HTTP headers then update the MD context. | PAL_SUCCESS | 01123 * | 10 | Locate the end of the HTTP headers in the server's response (HTTP headers end with a double CRLF). | PAL_SUCCESS | 01124 * | 11 | Update the MD context. | PAL_SUCCESS | 01125 * | 12 | Close the socket. | PAL_SUCCESS | 01126 * | 13 | Get the hash output size and validate it. | PAL_SUCCESS | 01127 * | 14 | Get the calculated hash and compare it to the pre-known hash. | PAL_SUCCESS | 01128 * | 15 | Free the MD context resources. | PAL_SUCCESS | 01129 * | 16 | Free HTTP response buffer. | PAL_SUCCESS | 01130 */ 01131 PAL_PRIVATE void socketTCPBuffered(size_t bufSize) 01132 { 01133 palStatus_t result = PAL_SUCCESS; 01134 palSocketAddress_t address = { 0 }; 01135 palSocketLength_t addrlen = 0; 01136 int timeout = 5000; 01137 uint8_t next = '\r', state = 0; 01138 size_t read = 0, sent = 0, hashlen = 0; 01139 bool body = false; 01140 palMDHandle_t handle = NULLPTR; 01141 uint8_t actualHash[PAL_SHA256_SIZE] = { 0 }; 01142 const uint8_t expectedHash[] = // pre-calculated jquery.js 3.2.1 SHA256 01143 { 01144 0x0d, 0x90, 0x27, 0x28, 0x9f, 0xfa, 0x5d, 0x9f, 0x6c, 0x8b, 0x4e, 0x07, 0x82, 0xbb, 0x31, 0xbb, 01145 0xff, 0x2c, 0xef, 0x5e, 0xe3, 0x70, 0x8c, 0xcb, 0xcb, 0x7a, 0x22, 0xdf, 0x91, 0x28, 0xbb, 0x21 01146 }; 01147 01148 /*#1*/ 01149 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, &g_testSockets[0]); 01150 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01151 01152 /*#2*/ 01153 result = test_getAddressInfo(PAL_NET_TEST_GOOGLE_CDN_HOST, &address, &addrlen); 01154 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01155 01156 /*#3*/ 01157 result = pal_setSockAddrPort(&address, PAL_NET_TEST_GOOGLE_CDN_HOST_PORT); 01158 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01159 01160 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_SNDTIMEO , &timeout, sizeof(timeout)); 01161 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01162 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO , &timeout, sizeof(timeout)); 01163 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01164 01165 /*#4*/ 01166 result = pal_connect(g_testSockets[0], &address, addrlen); 01167 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01168 01169 /*#5*/ 01170 result = pal_send(g_testSockets[0], PAL_NET_TEST_GOOGLE_CDN_REQUEST, sizeof(PAL_NET_TEST_GOOGLE_CDN_REQUEST) - 1, &sent); 01171 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01172 01173 /*#6*/ 01174 result = pal_mdInit(&handle, PAL_SHA256); 01175 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01176 TEST_ASSERT_NOT_EQUAL(NULLPTR, handle); 01177 01178 /*#7*/ 01179 g_testRecvBuffer = (uint8_t*)malloc(sizeof(uint8_t) * bufSize + 1); 01180 TEST_ASSERT_NOT_EQUAL(NULLPTR, g_testRecvBuffer); 01181 01182 /*#8*/ 01183 do 01184 { 01185 read = 0; 01186 memset(g_testRecvBuffer, 0, bufSize + 1); 01187 result = pal_recv(g_testSockets[0], g_testRecvBuffer, bufSize, &read); 01188 TEST_ASSERT_TRUE((PAL_SUCCESS == result && read > 0) || (PAL_ERR_SOCKET_CONNECTION_CLOSED == result && read == 0)); 01189 01190 /*#9*/ 01191 if (body) 01192 { 01193 result = pal_mdUpdate(handle, g_testRecvBuffer, read); 01194 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01195 continue; 01196 } 01197 01198 /*#10*/ 01199 for (size_t i = 0; i < bufSize; i++) // dealing with the HTTP headers - headers end on a double CRLF 01200 { 01201 if (g_testRecvBuffer[i] == next) 01202 { 01203 next = (next == '\r') ? '\n' : '\r'; 01204 state = state | (state + 1); 01205 if (state == 0xf) 01206 { 01207 /*#11*/ 01208 body = true; 01209 result = pal_mdUpdate(handle, (g_testRecvBuffer + i + 1), strlen(((char*)g_testRecvBuffer) + i + 1)); 01210 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01211 break; 01212 } 01213 } 01214 else if (state != 0) 01215 { 01216 next = '\r'; 01217 state = 0; 01218 } 01219 } 01220 } while (read > 0); 01221 01222 /*#12*/ 01223 result = pal_close(&g_testSockets[0]); 01224 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01225 01226 /*#13*/ 01227 result = pal_mdGetOutputSize(handle, &hashlen); 01228 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01229 TEST_ASSERT_EQUAL_HEX(PAL_SHA256_SIZE, hashlen); 01230 01231 /*#14*/ 01232 result = pal_mdFinal(handle, actualHash); 01233 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01234 TEST_ASSERT_EQUAL_MEMORY(expectedHash, actualHash, PAL_SHA256_SIZE); 01235 01236 /*#15*/ 01237 result = pal_mdFree(&handle); 01238 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01239 01240 /*#16*/ 01241 free(g_testRecvBuffer); 01242 g_testRecvBuffer = NULLPTR; 01243 } 01244 01245 /*! \brief Test function TCP socket read in small chunks 01246 * 01247 ** \test 01248 */ 01249 TEST(pal_socket, socketTCPBufferedSmall) 01250 { 01251 socketTCPBuffered(PAL_NET_TEST_BUFFERED_TCP_BUF_SIZE_SMALL); 01252 } 01253 01254 /*! \brief Test function TCP socket read in large chunks 01255 * 01256 ** \test 01257 */ 01258 TEST(pal_socket, socketTCPBufferedLarge) 01259 { 01260 socketTCPBuffered(PAL_NET_TEST_BUFFERED_TCP_BUF_SIZE_LARGE); 01261 } 01262 01263 // flag marking if the pal_getAddressInfoAsync callback has been invoked 01264 PAL_PRIVATE bool g_getAddressInfoAsyncCallbackInvoked = false; 01265 01266 // callback invoked from the call to pal_getAddressInfoAsync 01267 PAL_PRIVATE void getAddressInfoAsyncCallback(const char* url, palSocketAddress_t* address, palSocketLength_t* addressLength, palStatus_t status, void* arg) 01268 { 01269 palStatus_t* statusArg = (palStatus_t*)arg; 01270 *statusArg = status; 01271 g_getAddressInfoAsyncCallbackInvoked = true; 01272 } 01273 01274 /*! \brief Test get address info asynchronously 01275 ** \test 01276 * | # | Step | Expected | 01277 * |---|-------------------------------------------------------------------------------------------------------|-------------| 01278 * | 1 | Invoke a synchronous get address info so we'll have something to compare to the asynchronous results. | PAL_SUCCESS | 01279 * | 2 | Invoke an asynchronous get address info. | PAL_SUCCESS | 01280 * | 3 | Wait until the asynchronous get address info callback is called or max wait time has ended. | PAL_SUCCESS | 01281 * | 4 | Compare the synchronous results to the asynchronous results. | PAL_SUCCESS | 01282 */ 01283 TEST(pal_socket, getAddressInfoAsync) 01284 { 01285 int counter = 0; 01286 palSocketAddress_t addressSync = { 0 }, addressAsync = { 0 }; 01287 palSocketLength_t addrlenSync = 0, addrlenAsync = 0; 01288 palStatus_t status, statusCallback; 01289 01290 /*#1*/ 01291 status = pal_getAddressInfo(PAL_NET_TEST_SERVER_NAME, &addressSync, &addrlenSync); 01292 TEST_ASSERT_TRUE_MESSAGE((PAL_SUCCESS == status), "synchronous call to pal_getAddressInfo failed"); 01293 01294 /*#2*/ 01295 statusCallback = PAL_ERR_SOCKET_ERROR_BASE ; 01296 status = pal_getAddressInfoAsync(PAL_NET_TEST_SERVER_NAME, &addressAsync, &addrlenAsync, getAddressInfoAsyncCallback, &statusCallback); 01297 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01298 01299 /*#3*/ 01300 while ((!g_getAddressInfoAsyncCallbackInvoked) && counter < 20) // wait until callback is invoked or max time of ~5 seconds 01301 { 01302 counter++; 01303 pal_osDelay(250); 01304 } 01305 TEST_ASSERT_TRUE_MESSAGE(g_getAddressInfoAsyncCallbackInvoked, "getAddressInfoAsyncCallback was not invoked"); 01306 g_getAddressInfoAsyncCallbackInvoked = false; 01307 01308 /*#4*/ 01309 TEST_ASSERT_EQUAL_HEX(status, statusCallback); 01310 TEST_ASSERT_EQUAL_HEX(addrlenSync, addrlenAsync); 01311 TEST_ASSERT_EQUAL_HEX(addressSync.addressType, addressAsync.addressType); 01312 TEST_ASSERT_EQUAL_MEMORY(addressSync.addressData, addressAsync.addressData, PAL_NET_MAX_ADDR_SIZE); 01313 } 01314 01315 /*! \brief Test pal socket APIs input parameter validations 01316 ** \test 01317 */ 01318 TEST(pal_socket, socketApiInputParamValidation) 01319 { 01320 #ifdef DEBUG 01321 palStatus_t status; 01322 palSocketAddress_t addr; 01323 addr.addressType = PAL_AF_UNSPEC; 01324 uint16_t port = 0; 01325 01326 status = pal_registerNetworkInterface(NULL, NULL); 01327 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01328 status = pal_setSockAddrPort(NULL, 0); 01329 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01330 status = pal_setSockAddrPort(&addr, 0); 01331 TEST_ASSERT_EQUAL_HEX(PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY , status); 01332 status = pal_setSockAddrIPV4Addr(NULL, NULL); 01333 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01334 status = pal_setSockAddrIPV6Addr(NULL, NULL); 01335 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01336 status = pal_getSockAddrIPV4Addr(NULL, NULL); 01337 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01338 status = pal_getSockAddrIPV4Addr(&addr, NULL); 01339 TEST_ASSERT_EQUAL_HEX(PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY , status); 01340 status = pal_getSockAddrIPV6Addr(NULL, NULL); 01341 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01342 status = pal_getSockAddrIPV6Addr(&addr, NULL); 01343 TEST_ASSERT_EQUAL_HEX(PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY , status); 01344 status = pal_getSockAddrPort(NULL, NULL); 01345 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01346 status = pal_getSockAddrPort(&addr, &port); 01347 TEST_ASSERT_EQUAL_HEX(PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY , status); 01348 status = pal_setSocketOptions(NULL, 0, NULL, 0); 01349 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01350 status = pal_isNonBlocking(NULL, NULL); 01351 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01352 status = pal_bind(NULL, NULL, 0); 01353 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01354 status = pal_receiveFrom(NULL, NULL, 0, NULL, NULL, NULL); 01355 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01356 status = pal_sendTo(NULL, NULL, 0, NULL, 0, NULL); 01357 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01358 status = pal_close(NULL); 01359 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01360 status = pal_getNumberOfNetInterfaces(NULL); 01361 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01362 status = pal_getNetInterfaceInfo(0, NULL); 01363 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01364 #if PAL_NET_TCP_AND_TLS_SUPPORT 01365 status = pal_accept(NULL, NULL, NULL, NULL); 01366 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01367 status = pal_connect(NULL, NULL, 0); 01368 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01369 status = pal_recv(NULL, NULL, 0, NULL); 01370 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01371 status = pal_send(NULL, NULL, 0, NULL); 01372 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01373 #endif // PAL_NET_TCP_AND_TLS_SUPPORT 01374 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 01375 status = pal_asynchronousSocketWithArgument(PAL_AF_UNSPEC, PAL_SOCK_DGRAM , false, 0, NULL, NULL, NULL); 01376 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01377 #endif // PAL_NET_ASYNCHRONOUS_SOCKET_API 01378 #if PAL_NET_DNS_SUPPORT 01379 status = pal_getAddressInfo(NULL, NULL, NULL); 01380 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01381 status = pal_getAddressInfoAsync(NULL, NULL, NULL, NULL, NULL); 01382 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01383 #endif // PAL_NET_DNS_SUPPORT 01384 #endif //DEBUG 01385 } 01386 01387 PAL_PRIVATE void keepAliveFunc(bool keepalive) 01388 { 01389 palStatus_t result = PAL_SUCCESS; 01390 palSocketAddress_t address = { 0 }; 01391 char buffer[100] = { 0 }; 01392 size_t read = 0; 01393 palSocketLength_t addrlen = 0; 01394 int timeout = PAL_MILLI_PER_SECOND; 01395 int KeepAliveOn , KeepAliveIntvl, KeepAliveIdle = 0; 01396 int keepaliveNumber=0; 01397 01398 if (keepalive) 01399 { 01400 KeepAliveOn=1; 01401 KeepAliveIntvl=1; 01402 KeepAliveIdle =1; 01403 } 01404 /*#1*/ 01405 result = pal_socket(PAL_AF_INET, PAL_SOCK_STREAM, false, 0, &g_testSockets[0]); 01406 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 01407 01408 /*#2*/ 01409 result = pal_getAddressInfo(PAL_TEST_KEEPALIVE_SERVER_ADDRESS, &address, &addrlen); 01410 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 01411 01412 /*#3*/ 01413 result = pal_setSockAddrPort(&address, PAL_TEST_SERVER_KEEPALIVE_PORT); 01414 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 01415 01416 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_SNDTIMEO , &timeout, sizeof(timeout)); 01417 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01418 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_RCVTIMEO , &timeout, sizeof(timeout)); 01419 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01420 01421 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_KEEPALIVE , &KeepAliveOn, sizeof(KeepAliveOn)); 01422 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01423 if (keepalive) { 01424 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_KEEPIDLE , &KeepAliveIdle, sizeof(KeepAliveIdle)); 01425 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01426 result = pal_setSocketOptions(g_testSockets[0], PAL_SO_KEEPINTVL , &KeepAliveIntvl, sizeof(KeepAliveIntvl)); 01427 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01428 } 01429 01430 /*#4*/ 01431 result = pal_connect(g_testSockets[0], &address, 16); 01432 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 01433 01434 /*#6*/ 01435 while (result != PAL_ERR_SOCKET_CONNECTION_CLOSED ) 01436 { 01437 result = pal_recv(g_testSockets[0], buffer, sizeof(buffer)-1 , &read); 01438 if (result != PAL_ERR_SOCKET_CONNECTION_CLOSED ) 01439 { 01440 if((read != 0) && (buffer[0]!=0)) 01441 { 01442 keepaliveNumber=atoi(buffer); 01443 if (keepalive){ 01444 TEST_ASSERT_TRUE(keepaliveNumber > PAL_TEST_KEEPALIVE_NUM_OF_ACK); 01445 } 01446 else{ 01447 TEST_ASSERT_TRUE(keepaliveNumber < PAL_TEST_KEEPALIVE_NUM_OF_ACK); 01448 } 01449 break; 01450 } 01451 } 01452 01453 } 01454 result = pal_close(&g_testSockets[0]); 01455 TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result); 01456 } 01457 01458 /*! \brief Test keepAlive On/Off 01459 ** \test 01460 * | # | Step | Expected | 01461 * |---|--------------------------------|-------------| 01462 * | 1 | Create a blocking TCP socket using `pal_socket`. | PAL_SUCCESS | 01463 * | 2 | Look up the IP address of the test server using `pal_getAddressInfo`. | PAL_SUCCESS | 01464 * | 3 | Set the port to a test port in the address structure using `pal_setSockAddrPort` and set timeout. | PAL_SUCCESS | 01465 * | 4 | Set keepalive socket options : if keepalive is on set keepalibe idel and intvl . | PAL_SUCCESS | 01466 * | 5 | Connect the socket to the test server using `pal_connect`. | PAL_SUCCESS | 01467 * | 6 | Receive (blocking) the server's response using `pal_recv` and check it keepalive packates sent. | PAL_SUCCESS | 01468 * | 7 | Close the socket. | PAL_SUCCESS | 01469 */ 01470 01471 TEST(pal_socket, keepaliveOn) 01472 { 01473 keepAliveFunc(true); 01474 } 01475 01476 TEST(pal_socket, keepaliveOff) 01477 { 01478 keepAliveFunc(false); 01479 } 01480 01481
Generated on Tue Jul 12 2022 19:01:36 by 1.7.2