Simple interface for Mbed Cloud Client

Dependents:  

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