Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_network.c Source File

pal_network.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 
00018 #include "pal.h"
00019 #include "pal_network.h"
00020 #include "pal_plat_network.h"
00021 
00022 #define TRACE_GROUP "PAL"
00023 
00024 typedef struct pal_in_addr {
00025     uint32_t s_addr; // that's a 32-bit int (4 bytes)
00026 } pal_in_addr_t;
00027 
00028 #if PAL_SUPPORT_IP_V4
00029 typedef struct pal_socketAddressInternal {
00030     short int          pal_sin_family;  // address family
00031     unsigned short int pal_sin_port;    // port
00032     pal_in_addr_t     pal_sin_addr;    // ipv4 address
00033     unsigned char      pal_sin_zero[8]; //
00034 } pal_socketAddressInternal_t;
00035 #endif
00036 
00037 #if PAL_SUPPORT_IP_V6
00038 typedef struct pal_socketAddressInternal6{
00039     uint16_t       pal_sin6_family;   // address family,
00040     uint16_t       pal_sin6_port;     // port number, Network Byte Order
00041     uint32_t       pal_sin6_flowinfo; // IPv6 flow information
00042     palIpV6Addr_t pal_sin6_addr;     // IPv6 address
00043     uint32_t       pal_sin6_scope_id; // Scope ID
00044 } pal_socketAddressInternal6_t;
00045 #endif
00046 
00047 #if PAL_NET_DNS_SUPPORT
00048 
00049 // structure used by pal_getAddressInfoAsync
00050 #if (PAL_DNS_API_VERSION == 1)
00051 typedef struct pal_asyncAddressInfo
00052 {
00053     char* url;
00054     palSocketAddress_t* address;
00055     palSocketLength_t* addressLength;
00056     palGetAddressInfoAsyncCallback_t callback;
00057     void* callbackArgument;
00058 } pal_asyncAddressInfo_t;
00059 #endif // PAL_DNS_API_VERSION
00060 #endif // PAL_NET_DNS_SUPPORT
00061 
00062 palStatus_t pal_registerNetworkInterface(void* networkInterfaceContext, uint32_t* interfaceIndex)
00063 {
00064     PAL_VALIDATE_ARGUMENTS((networkInterfaceContext == NULL) || (interfaceIndex == NULL));
00065     palStatus_t result = pal_plat_registerNetworkInterface(networkInterfaceContext, interfaceIndex);
00066 
00067     return result;
00068 }
00069 
00070 palStatus_t pal_unregisterNetworkInterface(uint32_t interfaceIndex)
00071 {
00072     PAL_VALIDATE_ARGUMENTS(interfaceIndex > PAL_MAX_SUPORTED_NET_INTERFACES - 1);
00073     return pal_plat_unregisterNetworkInterface (interfaceIndex);
00074 }
00075 
00076 palStatus_t pal_setSockAddrPort(palSocketAddress_t* address, uint16_t port)
00077 {
00078     palStatus_t result = PAL_SUCCESS;
00079     bool found = false;
00080     PAL_VALIDATE_ARGUMENTS(NULL == address);
00081 
00082 #if PAL_SUPPORT_IP_V4
00083     if (address->addressType == PAL_AF_INET)
00084     {
00085         pal_socketAddressInternal_t* innerAddr = (pal_socketAddressInternal_t*)address;
00086         // Set Linux format
00087         innerAddr->pal_sin_port = PAL_HTONS(port);
00088         found = true;
00089     }
00090 #endif
00091 
00092 #if PAL_SUPPORT_IP_V6
00093     if (address->addressType == PAL_AF_INET6)
00094     {
00095         pal_socketAddressInternal6_t * innerAddr = (pal_socketAddressInternal6_t*)address;
00096         // Set Linux format
00097         innerAddr->pal_sin6_port = PAL_HTONS(port);
00098         found = true;
00099     }
00100 #endif
00101     if (false == found)
00102     {
00103         result =  PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY ;
00104     }
00105 
00106     return result;
00107 }
00108 
00109 
00110 
00111 #if PAL_SUPPORT_IP_V4
00112 palStatus_t pal_setSockAddrIPV4Addr(palSocketAddress_t* address, palIpV4Addr_t ipV4Addr)
00113 {
00114     PAL_VALIDATE_ARGUMENTS((NULL == address) || (NULL == ipV4Addr));
00115 
00116     pal_socketAddressInternal_t* innerAddr = (pal_socketAddressInternal_t*)address;
00117     innerAddr->pal_sin_family = PAL_AF_INET;
00118     innerAddr->pal_sin_addr.s_addr = (ipV4Addr[0]) | (ipV4Addr[1] << 8) | (ipV4Addr[2] << 16) | (ipV4Addr[3] << 24);
00119     return PAL_SUCCESS;
00120 }
00121 
00122 palStatus_t pal_getSockAddrIPV4Addr(const palSocketAddress_t* address, palIpV4Addr_t ipV4Addr)
00123 {
00124     PAL_VALIDATE_ARGUMENTS(NULL == address);
00125     PAL_VALIDATE_CONDITION_WITH_ERROR((address->addressType != PAL_AF_INET),PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY );
00126     palStatus_t result = PAL_SUCCESS;
00127 
00128     if (address->addressType == PAL_AF_INET)
00129     {
00130         pal_socketAddressInternal_t* innerAddr = (pal_socketAddressInternal_t*)address;
00131         ipV4Addr[0] = (innerAddr->pal_sin_addr.s_addr) & 0xFF;
00132         ipV4Addr[1] = (innerAddr->pal_sin_addr.s_addr >> 8) & 0xFF;
00133         ipV4Addr[2] = (innerAddr->pal_sin_addr.s_addr >> 16) & 0xFF;
00134         ipV4Addr[3] = (innerAddr->pal_sin_addr.s_addr >> 24) & 0xFF;
00135 
00136     }
00137 
00138     return result;
00139 }
00140 #else
00141 palStatus_t pal_setSockAddrIPV4Addr(palSocketAddress_t* address, palIpV4Addr_t ipV4Addr)
00142 {
00143     return PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY ;
00144 }
00145 palStatus_t pal_getSockAddrIPV4Addr(const palSocketAddress_t* address, palIpV4Addr_t ipV4Addr)
00146 {
00147     return PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY ;
00148 }
00149 
00150 #endif
00151 
00152 
00153 #if PAL_SUPPORT_IP_V6
00154 palStatus_t pal_getSockAddrIPV6Addr(const palSocketAddress_t* address, palIpV6Addr_t ipV6Addr)
00155 {
00156     palStatus_t result = PAL_SUCCESS;
00157     int index = 0;
00158     PAL_VALIDATE_ARGUMENTS (NULL == address);
00159     PAL_VALIDATE_CONDITION_WITH_ERROR((address->addressType != PAL_AF_INET6),PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY );
00160 
00161     pal_socketAddressInternal6_t * innerAddr = (pal_socketAddressInternal6_t*)address;
00162     for (index = 0; index < PAL_IPV6_ADDRESS_SIZE; index++) // TODO: use mem copy?
00163     {
00164         ipV6Addr[index] = innerAddr->pal_sin6_addr[index];
00165     }
00166 
00167 
00168     return result;
00169 }
00170 
00171 palStatus_t pal_setSockAddrIPV6Addr(palSocketAddress_t* address, palIpV6Addr_t ipV6Addr)
00172 {
00173     int index;
00174     PAL_VALIDATE_ARGUMENTS((NULL == address) || (NULL == ipV6Addr));
00175 
00176     pal_socketAddressInternal6_t* innerAddr = (pal_socketAddressInternal6_t*)address;
00177     innerAddr->pal_sin6_family = PAL_AF_INET6;
00178     for (index = 0; index < PAL_IPV6_ADDRESS_SIZE; index++) // TODO: use mem copy?
00179     {
00180         innerAddr->pal_sin6_addr[index] = ipV6Addr[index];
00181     }
00182     return PAL_SUCCESS;
00183 }
00184 #else
00185 palStatus_t pal_setSockAddrIPV6Addr(palSocketAddress_t* address, palIpV6Addr_t ipV6Addr)
00186 {
00187     return PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY ;
00188 }
00189 
00190 palStatus_t pal_getSockAddrIPV6Addr(const palSocketAddress_t* address, palIpV6Addr_t ipV6Addr)
00191 {
00192     return PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY ;
00193 }
00194 
00195 #endif
00196 
00197 
00198 palStatus_t pal_getSockAddrPort(const palSocketAddress_t* address, uint16_t* port)
00199 {
00200     bool found = false;
00201     palStatus_t result = PAL_SUCCESS;
00202 
00203     PAL_VALIDATE_ARGUMENTS ((NULL == address) || (NULL == port));
00204 
00205 #if PAL_SUPPORT_IP_V4
00206 
00207     if (address->addressType == PAL_AF_INET)
00208     {
00209         pal_socketAddressInternal_t* innerAddr = (pal_socketAddressInternal_t*)address;
00210         // Set numeric formal
00211         *port = PAL_NTOHS(innerAddr->pal_sin_port);
00212         found = true;
00213     }
00214 #endif
00215 #if PAL_SUPPORT_IP_V6
00216     if (address->addressType == PAL_AF_INET6)
00217     {
00218         pal_socketAddressInternal6_t * innerAddr = (pal_socketAddressInternal6_t*)address;
00219         // Set numeric formal
00220         *port = PAL_NTOHS(innerAddr->pal_sin6_port);
00221         found = true;
00222     }
00223 #endif
00224     if (false == found)
00225     {
00226         result =  PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY ;
00227     }
00228 
00229     return result;
00230 }
00231 
00232 
00233 palStatus_t pal_socket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palSocket_t* socket)
00234 {
00235     PAL_VALIDATE_ARGUMENTS (NULL == socket);
00236 
00237     palStatus_t result = pal_plat_socket(domain, type, nonBlockingSocket, interfaceNum, socket);;
00238 
00239     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00240 }
00241 
00242 
00243 palStatus_t pal_setSocketOptions(palSocket_t socket, int optionName, const void* optionValue, palSocketLength_t optionLength)
00244 {
00245 
00246     PAL_VALIDATE_ARGUMENTS (NULL == optionValue);
00247 
00248     palStatus_t result = PAL_SUCCESS;
00249     result = pal_plat_setSocketOptions( socket,  optionName, optionValue,  optionLength);
00250     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00251 }
00252 
00253 palStatus_t pal_isNonBlocking(palSocket_t socket, bool* isNonBlocking)
00254 {
00255     PAL_VALIDATE_ARGUMENTS (NULL == isNonBlocking);
00256 
00257     palStatus_t result = pal_plat_isNonBlocking(socket, isNonBlocking);;
00258     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00259 }
00260 
00261 
00262 palStatus_t pal_bind(palSocket_t socket, palSocketAddress_t* myAddress, palSocketLength_t addressLength)
00263 {
00264 
00265     PAL_VALIDATE_ARGUMENTS(NULL == myAddress);
00266 
00267     palStatus_t result = PAL_SUCCESS;
00268     result = pal_plat_bind(socket, myAddress, addressLength);
00269     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00270 }
00271 
00272 
00273 palStatus_t pal_receiveFrom(palSocket_t socket, void* buffer, size_t length, palSocketAddress_t* from, palSocketLength_t* fromLength, size_t* bytesReceived)
00274 {
00275 
00276     PAL_VALIDATE_ARGUMENTS((NULL == buffer) || (NULL == bytesReceived));
00277 
00278     palStatus_t result = PAL_SUCCESS;
00279     result = pal_plat_receiveFrom(socket,  buffer,  length,  from, fromLength, bytesReceived);
00280     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00281 }
00282 
00283 
00284 palStatus_t pal_sendTo(palSocket_t socket, const void* buffer, size_t length, const palSocketAddress_t* to, palSocketLength_t toLength, size_t* bytesSent)
00285 {
00286 
00287     PAL_VALIDATE_ARGUMENTS((NULL == buffer) || (NULL == bytesSent) || (NULL == to));
00288 
00289     palStatus_t result = PAL_SUCCESS;
00290     result = pal_plat_sendTo(socket, buffer, length, to, toLength, bytesSent);
00291     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00292 }
00293 
00294 
00295 palStatus_t pal_close(palSocket_t* socket)
00296 {
00297 
00298     PAL_VALIDATE_ARGUMENTS(NULL == socket);
00299 
00300     palStatus_t result = PAL_SUCCESS;
00301     result = pal_plat_close(socket);
00302     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00303 }
00304 
00305 
00306 palStatus_t pal_getNumberOfNetInterfaces( uint32_t* numInterfaces)
00307 {
00308 
00309     PAL_VALIDATE_ARGUMENTS(NULL == numInterfaces);
00310 
00311     palStatus_t result = PAL_SUCCESS;
00312     result = pal_plat_getNumberOfNetInterfaces(numInterfaces);
00313     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00314 }
00315 
00316 
00317 palStatus_t pal_getNetInterfaceInfo(uint32_t interfaceNum, palNetInterfaceInfo_t * interfaceInfo)
00318 {
00319     PAL_VALIDATE_ARGUMENTS(NULL == interfaceInfo)
00320 
00321     palStatus_t result = PAL_SUCCESS;
00322     result = pal_plat_getNetInterfaceInfo(interfaceNum, interfaceInfo);
00323     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00324 }
00325 
00326 
00327 #if PAL_NET_TCP_AND_TLS_SUPPORT // functionality below supported only in case TCP is supported.
00328 
00329 palStatus_t pal_listen(palSocket_t socket, int backlog)
00330 {
00331     palStatus_t result = pal_plat_listen(socket, backlog);
00332     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00333 }
00334 
00335 
00336 palStatus_t pal_accept(palSocket_t socket, palSocketAddress_t* address, palSocketLength_t* addressLen, palSocket_t* acceptedSocket)
00337 {
00338 
00339     PAL_VALIDATE_ARGUMENTS ((NULL == acceptedSocket) || (NULL == address)|| (NULL == addressLen));
00340 
00341     palStatus_t result = PAL_SUCCESS;
00342     result = pal_plat_accept(socket,  address, addressLen,  acceptedSocket);
00343     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00344 }
00345 
00346 
00347 palStatus_t pal_connect(palSocket_t socket, const palSocketAddress_t* address, palSocketLength_t addressLen)
00348 {
00349     PAL_VALIDATE_ARGUMENTS(NULL == address);
00350 
00351     palStatus_t result = PAL_SUCCESS;
00352 
00353     result = pal_plat_connect( socket, address, addressLen);
00354     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00355 }
00356 
00357 
00358 palStatus_t pal_recv(palSocket_t socket, void* buf, size_t len, size_t* recievedDataSize)
00359 {
00360     PAL_VALIDATE_ARGUMENTS((NULL == recievedDataSize) ||  (NULL == buf));
00361 
00362     palStatus_t result = PAL_SUCCESS;
00363     result = pal_plat_recv(socket, buf, len, recievedDataSize);
00364     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00365 }
00366 
00367 
00368 palStatus_t pal_send(palSocket_t socket, const void* buf, size_t len, size_t* sentDataSize)
00369 {
00370 
00371     PAL_VALIDATE_ARGUMENTS((NULL == buf) || (NULL == sentDataSize));
00372 
00373     palStatus_t result = PAL_SUCCESS;
00374     result = pal_plat_send( socket, buf, len, sentDataSize);
00375     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00376 }
00377 
00378 
00379 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
00380 
00381 
00382 #if PAL_NET_ASYNCHRONOUS_SOCKET_API
00383 
00384 palStatus_t pal_asynchronousSocket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, palSocket_t* socket)
00385 {
00386     PAL_VALIDATE_ARGUMENTS((NULL == socket) || (NULL == callback));
00387 
00388     palStatus_t result = PAL_SUCCESS;
00389     result = pal_plat_asynchronousSocket(domain,  type,  nonBlockingSocket,  interfaceNum,  callback, NULL, socket);
00390     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00391 }
00392 
00393 palStatus_t pal_asynchronousSocketWithArgument(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void* callbackArgument, palSocket_t* socket)
00394 {
00395     PAL_VALIDATE_ARGUMENTS((NULL == socket) || (NULL == callback));
00396 
00397     palStatus_t result = PAL_SUCCESS;
00398     result = pal_plat_asynchronousSocket(domain, type, nonBlockingSocket, interfaceNum, callback, callbackArgument, socket);
00399     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00400 }
00401 
00402 #endif
00403 
00404 #if PAL_NET_DNS_SUPPORT
00405 #if (PAL_DNS_API_VERSION == 0) || (PAL_DNS_API_VERSION == 1)
00406 palStatus_t pal_getAddressInfo(const char *url, palSocketAddress_t *address, palSocketLength_t* addressLength)
00407 {
00408     PAL_VALIDATE_ARGUMENTS ((NULL == url) || (NULL == address) || (NULL == addressLength));
00409 
00410     palStatus_t result = PAL_SUCCESS;
00411     result = pal_plat_getAddressInfo(url, address, addressLength);
00412     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00413 }
00414 #endif
00415 
00416 // the function invoked by the thread created in pal_getAddressInfoAsync
00417 #if (PAL_DNS_API_VERSION == 1)
00418 PAL_PRIVATE void getAddressInfoAsyncThreadFunc(void const* arg)
00419 {
00420     pal_asyncAddressInfo_t* info = (pal_asyncAddressInfo_t*)arg;
00421     palStatus_t status = pal_getAddressInfo(info->url, info->address, info->addressLength);
00422     if (PAL_SUCCESS != status)
00423     {
00424         PAL_LOG_ERR("getAddressInfoAsyncThreadFunc: pal_getAddressInfo failed\n");
00425     }
00426     info->callback(info->url, info->address, info->addressLength, status, info->callbackArgument); // invoke callback
00427     free(info);
00428 }
00429 
00430 palStatus_t pal_getAddressInfoAsync(const char* url,
00431                                     palSocketAddress_t* address,
00432                                     palSocketLength_t* addressLength,
00433                                     palGetAddressInfoAsyncCallback_t callback,
00434                                     void* callbackArgument)
00435 {
00436     PAL_VALIDATE_ARGUMENTS ((NULL == url) || (NULL == address) || (NULL == addressLength) || (NULL == callback))
00437 
00438     palStatus_t status;
00439     palThreadID_t threadID = NULLPTR;
00440 
00441     pal_asyncAddressInfo_t* info = (pal_asyncAddressInfo_t*)malloc(sizeof(pal_asyncAddressInfo_t)); // thread function argument allocation
00442     if (NULL == info) {
00443         status = PAL_ERR_NO_MEMORY ;
00444     }
00445     else {
00446         info->url = (char*)url;
00447         info->address = address;
00448         info->addressLength = addressLength;
00449         info->callback = callback;
00450         info->callbackArgument = callbackArgument;
00451 
00452         status = pal_osThreadCreateWithAlloc(getAddressInfoAsyncThreadFunc, info, PAL_osPriorityReservedDNS , PAL_NET_ASYNC_DNS_THREAD_STACK_SIZE, NULL, &threadID);
00453         if (PAL_SUCCESS != status) {
00454             free(info); // free memory allocation in case thread creation failed
00455         }
00456     }
00457     return status;
00458 }
00459 #elif (PAL_DNS_API_VERSION == 2)
00460 #ifndef TARGET_LIKE_MBED
00461 #error "PAL_DNS_API_VERSION 2 is only supported with mbed-os"
00462 #endif
00463 palStatus_t pal_getAddressInfoAsync(const char* url,
00464                                      palSocketAddress_t* address,
00465                                      palGetAddressInfoAsyncCallback_t callback,
00466                                      void* callbackArgument,
00467                                      palDNSQuery_t* queryHandle)
00468 {
00469     PAL_VALIDATE_ARGUMENTS ((NULL == url) || (NULL == address) || (NULL == callback))
00470 
00471     palStatus_t status;
00472 
00473     pal_asyncAddressInfo_t* info = (pal_asyncAddressInfo_t*)malloc(sizeof(pal_asyncAddressInfo_t));
00474     if (NULL == info) {
00475         status = PAL_ERR_NO_MEMORY ;
00476     }
00477     else {
00478         info->url = (char*)url;
00479         info->address = address;
00480         info->callback = callback;
00481         info->callbackArgument = callbackArgument;
00482         info->queryHandle = queryHandle;
00483         status = pal_plat_getAddressInfoAsync(info);
00484         if (status != PAL_SUCCESS) {
00485             free(info);
00486         }
00487     }
00488     return status;
00489 }
00490 
00491 palStatus_t pal_cancelAddressInfoAsync(palDNSQuery_t queryHandle)
00492 {
00493     return pal_plat_cancelAddressInfoAsync(queryHandle);
00494 }
00495 #endif //  PAL_DNS_API_VERSION
00496 
00497 #endif // PAL_NET_DNS_SUPPORT