Ram Gandikota / Mbed OS ABCD
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_network.cpp Source File

pal_plat_network.cpp

00001 /*
00002 * Copyright (c) 2016 ARM Limited. All rights reserved.
00003 * SPDX-License-Identifier: Apache-2.0
00004 * Licensed under the Apache License, Version 2.0 (the License); you may
00005 * 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, WITHOUT
00012 * 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_plat_network.h"
00020 #include "pal_rtos.h"
00021 
00022 #include "mbed.h"
00023 
00024 
00025 #if defined (__CC_ARM) || defined(__IAR_SYSTEMS_ICC__)
00026 
00027 
00028 void palSelectCallbackNull()
00029 {
00030 }
00031 
00032 #define NULL_FUNCTION palSelectCallbackNull
00033 
00034 
00035 #elif defined (__GNUC__)
00036 
00037 #define NULL_FUNCTION NULL
00038 
00039 #endif
00040 
00041 
00042 #define PAL_SOCKET_OPTION_ERROR (-1)
00043 
00044 static NetworkInterface* s_pal_networkInterfacesSupported[PAL_MAX_SUPORTED_NET_INTEFACES] = { 0 };
00045 
00046 static  uint32_t s_pal_numberOFInterfaces = 0;
00047 
00048 static  uint32_t s_pal_network_initialized = 0;
00049 
00050 static palStatus_t translateErrorToPALError(int errnoValue)
00051 {
00052     palStatus_t status;
00053     switch (errnoValue)
00054     {
00055     case NSAPI_ERROR_NO_MEMORY:
00056         status = PAL_ERR_NO_MEMORY;
00057         break;
00058     case NSAPI_ERROR_PARAMETER:
00059         status = PAL_ERR_SOCKET_INVALID_VALUE;
00060         break;
00061     case NSAPI_ERROR_WOULD_BLOCK:
00062         status = PAL_ERR_SOCKET_WOULD_BLOCK;
00063         break;
00064     case NSAPI_ERROR_DNS_FAILURE:
00065         status = PAL_ERR_SOCKET_DNS_ERROR;
00066         break;
00067     case NSAPI_ERROR_DHCP_FAILURE:
00068         status = PAL_ERR_SOCKET_HDCP_ERROR;
00069         break;
00070     case NSAPI_ERROR_AUTH_FAILURE:
00071         status = PAL_ERR_SOCKET_AUTH_ERROR;
00072         break;
00073     case NSAPI_ERROR_NO_ADDRESS:
00074         status = PAL_ERR_SOCKET_INVALID_ADDRESS;
00075         break;
00076     case NSAPI_ERROR_NO_CONNECTION:
00077         status = PAL_ERR_SOCKET_NOT_CONNECTED;
00078         break;
00079     case NSAPI_ERROR_DEVICE_ERROR:
00080         status = PAL_ERR_SOCKET_INPUT_OUTPUT_ERROR;
00081         break;
00082     case NSAPI_ERROR_UNSUPPORTED:
00083         status = PAL_ERR_NOT_SUPPORTED;
00084         break;
00085 
00086     default:
00087         status = PAL_ERR_SOCKET_GENERIC;
00088         break;
00089     }
00090     return status;
00091 }
00092 
00093 palStatus_t pal_plat_socketsInit(void* context)
00094 {
00095     (void)context; // replace with macro
00096     int result = PAL_SUCCESS;
00097     if (s_pal_network_initialized == 1)
00098     {
00099         return PAL_SUCCESS; // already initialized.
00100     }
00101         
00102     s_pal_network_initialized = 1;
00103 
00104     return result;
00105 }
00106 
00107 palStatus_t pal_plat_RegisterNetworkInterface(void* context, uint32_t* interfaceIndex)
00108 {
00109     palStatus_t result = PAL_SUCCESS;
00110     uint32_t index = 0;
00111     uint32_t found = 0;
00112     if (NULL != context) // TODO: nirson01 : not thread safe - do we need to fix his?
00113     {
00114         for (index = 0; index < s_pal_numberOFInterfaces; index++) // if specific context already registered return exisitng index instead of registering again.
00115         {
00116             if (s_pal_networkInterfacesSupported[index] == context)
00117             {
00118                 found = 1;
00119                 if (interfaceIndex != NULL)
00120                 {
00121                     *interfaceIndex = index;
00122                 }
00123             }
00124         }
00125         if (0 == found)
00126         {
00127             s_pal_networkInterfacesSupported[s_pal_numberOFInterfaces] = (NetworkInterface*)context;
00128             if (interfaceIndex != NULL)
00129             {
00130                 *interfaceIndex = s_pal_numberOFInterfaces;
00131             }
00132             s_pal_numberOFInterfaces = s_pal_numberOFInterfaces + 1;
00133         }
00134 
00135         
00136     }
00137     else
00138     {
00139         result = PAL_ERR_INVALID_ARGUMENT;
00140     }
00141     return result;
00142 }
00143 
00144 palStatus_t pal_plat_socketsTerminate(void* context)
00145 {
00146     (void)context; // replace with macro
00147     return PAL_SUCCESS;
00148 }
00149 
00150 static int translateNSAPItoPALSocketOption(int option)
00151 {
00152     int optionVal = PAL_SOCKET_OPTION_ERROR;
00153     switch (option)
00154     {
00155     case PAL_SO_REUSEADDR:
00156         optionVal = NSAPI_REUSEADDR;
00157         break;
00158 #if PAL_NET_TCP_AND_TLS_SUPPORT // socket options below supported only if TCP is supported.
00159     case PAL_SO_KEEPALIVE:
00160         optionVal = NSAPI_KEEPALIVE;
00161         break;
00162 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
00163     case PAL_SO_SNDTIMEO:
00164     case PAL_SO_RCVTIMEO:
00165     default:
00166         optionVal = PAL_SOCKET_OPTION_ERROR;
00167     }
00168     return optionVal;
00169 }
00170 
00171 
00172 static palStatus_t palSockAddrToSocketAddress(const palSocketAddress_t* palAddr, int length, SocketAddress& output)
00173 {
00174     palStatus_t result = PAL_SUCCESS;
00175     uint16_t port = 0;
00176     nsapi_version_t version = NSAPI_IPv4;
00177 
00178     result = pal_getSockAddrPort(palAddr, &port);
00179     if (result != PAL_SUCCESS)
00180     {
00181         return result;
00182     }
00183     output.set_port(port);
00184 
00185     if (PAL_AF_INET == palAddr->addressType)
00186     {
00187         palIpV4Addr_t ipV4Addr;
00188         version = NSAPI_IPv4;
00189         result = pal_getSockAddrIPV4Addr(palAddr, ipV4Addr);
00190         if (result == PAL_SUCCESS)
00191         {
00192             output.set_ip_bytes(&ipV4Addr, version);
00193         }
00194     }
00195     else if (PAL_AF_INET6 == palAddr->addressType)
00196     {
00197         palIpV6Addr_t ipV6Addr;
00198         version = NSAPI_IPv6;
00199         result = pal_getSockAddrIPV6Addr(palAddr, ipV6Addr);
00200         if (result == PAL_SUCCESS)
00201         {
00202             output.set_ip_bytes(&ipV6Addr, version);
00203         }
00204     }
00205 
00206     return result;
00207 }
00208 
00209 static palStatus_t socketAddressToPalSockAddr(SocketAddress& input, palSocketAddress_t* out, palSocketLength_t* length)
00210 {
00211     palStatus_t result = PAL_SUCCESS;
00212     int index = 0;
00213     if (input.get_ip_version() == NSAPI_IPv4)
00214     {
00215         palIpV4Addr_t addr;
00216         const void* tmp = input.get_ip_bytes();
00217         for (index = 0; index < PAL_IPV4_ADDRESS_SIZE; index++)
00218         {
00219             addr[index] = ((const uint8_t*)tmp)[index];
00220         }
00221         result = pal_setSockAddrIPV4Addr(out, addr);
00222         *length = PAL_IPV4_ADDRESS_SIZE;  // TODO: check
00223 
00224     }
00225     else if (input.get_ip_version() == NSAPI_IPv6)
00226     {
00227         palIpV6Addr_t addr;
00228         const void* tmp = input.get_ip_bytes();
00229         for (index = 0; index < PAL_IPV6_ADDRESS_SIZE; index++)
00230         {
00231             addr[index] = ((const uint8_t*)tmp)[index];
00232         }
00233         result = pal_setSockAddrIPV6Addr(out, addr);
00234         *length = PAL_IPV6_ADDRESS_SIZE;  // TODO: check
00235     }
00236     else 
00237     {
00238         result = PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY;
00239     }
00240     
00241     if (result == PAL_SUCCESS)
00242     {
00243         result = pal_setSockAddrPort(out, input.get_port());
00244     }
00245     return result;
00246 }
00247 
00248 
00249 
00250 
00251 palStatus_t pal_plat_socket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palSocket_t* socket)
00252 {
00253     int result = PAL_SUCCESS;
00254     Socket* socketObj = NULL;
00255 
00256     if (PAL_NET_DEFAULT_INTERFACE == interfaceNum)
00257     {
00258         interfaceNum = 0;
00259     }
00260 
00261     if ((s_pal_numberOFInterfaces > interfaceNum) && (PAL_SOCK_DGRAM == type) && ((PAL_AF_INET == domain) || (PAL_AF_INET6 == domain) || (PAL_AF_UNSPEC == domain)))
00262     {
00263         socketObj = new UDPSocket(s_pal_networkInterfacesSupported[interfaceNum]);
00264     }
00265 #if PAL_NET_TCP_AND_TLS_SUPPORT // functionality below supported only in case TCP is supported.
00266     else if ((s_pal_numberOFInterfaces > interfaceNum) && (PAL_SOCK_STREAM == type) && ((PAL_AF_INET == domain) || (PAL_AF_INET6 == domain) || (PAL_AF_UNSPEC == domain)))
00267     {
00268         socketObj = new TCPSocket(s_pal_networkInterfacesSupported[interfaceNum]);
00269     }
00270     else if ((s_pal_numberOFInterfaces > interfaceNum) && (PAL_SOCK_STREAM_SERVER == type) && ((PAL_AF_INET == domain) || (PAL_AF_INET6 == domain) || (PAL_AF_UNSPEC == domain)))
00271     {
00272         socketObj = new TCPServer(s_pal_networkInterfacesSupported[interfaceNum]);
00273     }
00274 #endif
00275     else 
00276     {
00277         result =  PAL_ERR_INVALID_ARGUMENT;
00278     }
00279 
00280     if ((PAL_SUCCESS == result ) && (NULL == socketObj))
00281     {
00282         result = PAL_ERR_NO_MEMORY;
00283     }
00284     
00285     if (PAL_SUCCESS == result)
00286     {
00287         if (true == nonBlockingSocket)
00288         {
00289             socketObj->set_blocking(false);
00290         }
00291         else
00292         {
00293             socketObj->set_blocking(true);
00294         }
00295         *socket = (palSocket_t)socketObj;
00296     }
00297     return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized)
00298 }
00299 
00300 
00301 palStatus_t pal_plat_getSocketOptions(palSocket_t socket, palSocketOptionName_t optionName, void* optionValue, palSocketLength_t* optionLength)
00302 {
00303     int result = PAL_SUCCESS;
00304     unsigned int length = *optionLength;
00305     Socket* socketObj = (Socket*)socket;
00306 
00307     int socketOption = translateNSAPItoPALSocketOption(optionName);
00308     
00309     if (PAL_SOCKET_OPTION_ERROR != socketOption)
00310     {
00311         result = socketObj->getsockopt(NSAPI_SOCKET, socketOption, optionValue, &length);
00312         if (result < 0)
00313         {
00314             result =  translateErrorToPALError(result);
00315         }
00316         else 
00317         {
00318             *optionLength = length;
00319         }
00320         
00321     }
00322     else
00323     {
00324         // in MBED socket timeouts are write only via the API - not supported though socket options.
00325         result = PAL_ERR_SOCKET_OPTION_NOT_SUPPORTED;
00326     }
00327         
00328     return result;
00329 }
00330 
00331 
00332 palStatus_t pal_plat_setSocketOptions(palSocket_t socket, int optionName, const void* optionValue, palSocketLength_t optionLength)
00333 {
00334     int result = PAL_SUCCESS;
00335     Socket* socketObj = (Socket*)socket;
00336     int socketOption = PAL_SOCKET_OPTION_ERROR;
00337     
00338     socketOption = translateNSAPItoPALSocketOption(optionName);
00339     if (PAL_SOCKET_OPTION_ERROR != socketOption)
00340     {
00341         result = socketObj->setsockopt(NSAPI_SOCKET, socketOption, optionValue, optionLength);
00342         if (result < 0)
00343         {
00344             result = translateErrorToPALError(result);
00345         }
00346     }
00347     else
00348     {
00349         if ((PAL_SO_SNDTIMEO == optionName) || (PAL_SO_RCVTIMEO == optionName)) // timeouts in MBED API are not managed though socket options, bun instead via a different funciton call
00350         {
00351             int timeout = *((int*)optionValue);
00352             socketObj->set_timeout(timeout);
00353         }
00354         else
00355         {
00356             result = PAL_ERR_SOCKET_OPTION_NOT_SUPPORTED;
00357         }
00358     }
00359 
00360 
00361     return result;
00362 }
00363 
00364 
00365 
00366 palStatus_t pal_plat_bind(palSocket_t socket, palSocketAddress_t* myAddress, palSocketLength_t addressLength)
00367 {
00368     int result = PAL_SUCCESS;
00369     Socket* socketObj = (Socket*)socket;
00370     SocketAddress internalAddr;
00371 
00372     result = palSockAddrToSocketAddress(myAddress, addressLength, internalAddr);
00373     if (result == 0)
00374     {
00375         result = socketObj->bind(internalAddr);
00376         if (result < 0)
00377         {
00378             result =  translateErrorToPALError(result);
00379         }
00380     }
00381 
00382     return result;
00383 }
00384 
00385 
00386 palStatus_t pal_plat_receiveFrom(palSocket_t socket, void* buffer, size_t length, palSocketAddress_t* from, palSocketLength_t* fromLength, size_t* bytesReceived)
00387 {
00388     int result = PAL_SUCCESS;
00389     int status = 0;
00390     *bytesReceived = 0;
00391     SocketAddress sockAddr;
00392     UDPSocket* socketObj;
00393 
00394     socketObj = (UDPSocket*)socket;
00395 
00396     status = socketObj->recvfrom(&sockAddr, buffer, length);
00397     if (status < 0)
00398     {   
00399         result = translateErrorToPALError(status);
00400     }
00401     else if (status == 0){
00402         result = PAL_ERR_SOCKET_CONNECTION_CLOSED;
00403     }
00404     else // only return address / bytesReceived in case of success
00405     {
00406         if ((NULL != from) && (NULL != fromLength))
00407         {
00408             result = socketAddressToPalSockAddr(sockAddr, from, fromLength);
00409             
00410         }
00411         *bytesReceived = status;
00412     }
00413     
00414     return result;
00415 
00416 }
00417 
00418 palStatus_t pal_plat_sendTo(palSocket_t socket, const void* buffer, size_t length, const palSocketAddress_t* to, palSocketLength_t toLength, size_t* bytesSent)
00419 {
00420     int result = PAL_SUCCESS;
00421     int status = 0;
00422     SocketAddress sockAddr;
00423 
00424     UDPSocket* socketObj = (UDPSocket*)socket;
00425 
00426     *bytesSent = 0;
00427     result = palSockAddrToSocketAddress(to, toLength, sockAddr);
00428     if (result == 0)
00429     {
00430         status = socketObj->sendto(sockAddr, buffer, length);
00431         if (status < 0)
00432         {
00433             result = translateErrorToPALError(status);
00434         }
00435         else 
00436         {
00437             *bytesSent = status;
00438         }
00439     }
00440 
00441     return result;
00442 }
00443 
00444 palStatus_t pal_plat_close(palSocket_t* socket)
00445 {
00446     int result = PAL_SUCCESS;
00447     Socket* socketObj = (Socket*)*socket;
00448     result = socketObj->close();
00449     if (result < 0)
00450     {
00451         result =  translateErrorToPALError(result);
00452     }
00453     delete socketObj;
00454     *socket = NULL;
00455     return result;
00456 }
00457 
00458 palStatus_t pal_plat_getNumberOfNetInterfaces( uint32_t* numInterfaces)
00459 {
00460     *numInterfaces =  s_pal_numberOFInterfaces;
00461     return PAL_SUCCESS;
00462 }
00463 
00464 palStatus_t pal_plat_getNetInterfaceInfo(uint32_t interfaceNum, palNetInterfaceInfo_t  * interfaceInfo)
00465 {
00466     palStatus_t result = PAL_SUCCESS;
00467     const char* address = NULL;
00468     SocketAddress addr;
00469     if ((interfaceNum >= s_pal_numberOFInterfaces) || (NULL == interfaceInfo))
00470     {
00471         return PAL_ERR_INVALID_ARGUMENT;
00472     }
00473     address = s_pal_networkInterfacesSupported[interfaceNum]->get_ip_address(); // ip address returned is a null terminated string
00474     if (NULL != address)
00475     {
00476         addr.set_ip_address(address);
00477         result = socketAddressToPalSockAddr(addr, &interfaceInfo->address, &interfaceInfo->addressSize);
00478     }
00479     
00480 
00481     return result;
00482 }
00483 
00484 typedef void(*palSelectCallbackFunction_t)();
00485 
00486 static palSemaphoreID_t s_palSelectSemaphore = 0;
00487 static bool s_palSelectSemaphoreInited = false;
00488 uint32_t s_select_event_happened[PAL_NET_SOCKET_SELECT_MAX_SOCKETS];
00489 
00490 // select callbacks definition
00491 // TODO: nirson01 change to define these using a macro.
00492 void palSelectCallback0() 
00493 { 
00494     s_select_event_happened[0]++;
00495     pal_osSemaphoreRelease(s_palSelectSemaphore); 
00496 }
00497 void palSelectCallback1()
00498 {
00499     s_select_event_happened[1]++;
00500     pal_osSemaphoreRelease(s_palSelectSemaphore);
00501 }
00502 void palSelectCallback2()
00503 {
00504     s_select_event_happened[2]++;
00505     pal_osSemaphoreRelease(s_palSelectSemaphore);
00506 }
00507 void palSelectCallback3()
00508 {
00509     s_select_event_happened[3]++;
00510     pal_osSemaphoreRelease(s_palSelectSemaphore);
00511 }
00512 void palSelectCallback4()
00513 {
00514     s_select_event_happened[4]++;
00515     pal_osSemaphoreRelease(s_palSelectSemaphore);
00516 }
00517 void palSelectCallback5()
00518 {
00519     s_select_event_happened[5]++;
00520     pal_osSemaphoreRelease(s_palSelectSemaphore);
00521 }
00522 void palSelectCallback6()
00523 {
00524     s_select_event_happened[6]++;
00525     pal_osSemaphoreRelease(s_palSelectSemaphore);
00526 }
00527 void palSelectCallback7()
00528 {
00529     s_select_event_happened[7]++;
00530     pal_osSemaphoreRelease(s_palSelectSemaphore);
00531 }
00532 
00533 palSelectCallbackFunction_t s_palSelectPalCallbackFunctions[PAL_NET_SOCKET_SELECT_MAX_SOCKETS] = { palSelectCallback0, palSelectCallback1, palSelectCallback2, palSelectCallback3, palSelectCallback4, palSelectCallback5, palSelectCallback6, palSelectCallback7 };
00534 
00535 
00536 palStatus_t pal_plat_socketMiniSelect(const palSocket_t socketsToCheck[PAL_NET_SOCKET_SELECT_MAX_SOCKETS], uint32_t numberOfSockets, pal_timeVal_t* timeout,
00537     uint8_t palSocketStatus[PAL_NET_SOCKET_SELECT_MAX_SOCKETS], uint32_t * numberOfSocketsSet)
00538 {
00539         uint32_t index = 0;
00540         int32_t counter = 0;
00541         uint32_t timeoutInMiliseconds = 0;
00542         palStatus_t result = PAL_SUCCESS;
00543 
00544         if ((NULL == socketsToCheck) || (NULL == numberOfSocketsSet) || (NULL == timeout))
00545          {
00546              return PAL_ERR_INVALID_ARGUMENT;
00547          }
00548           
00549          timeoutInMiliseconds = (timeout->pal_tv_sec * 1000) + (timeout->pal_tv_usec /1000);
00550          *numberOfSocketsSet = 0;
00551 
00552          if (0 == numberOfSockets)
00553          {
00554              return PAL_SUCCESS;
00555          }
00556          // create semaphore if not initialized before - if it exists ensure count is 0.
00557         
00558          if (false == s_palSelectSemaphoreInited)
00559          {
00560              result = pal_osSemaphoreCreate(0, &s_palSelectSemaphore); // create semaphore to wait until socket event happens (semaphore will be re-used and is only created once, and never freed - if terminate is added free this resoruce if allocaed)
00561              if (PAL_SUCCESS != result)
00562              {
00563                  return result; //single exit ??
00564              }
00565              s_palSelectSemaphoreInited = true;
00566          }
00567          else {
00568              int32_t counters = 0;
00569              result = pal_osSemaphoreWait(s_palSelectSemaphore, 1, &counters); // deplete semaphore count until it is 0.
00570              while (result != PAL_ERR_RTOS_TIMEOUT)
00571              {
00572                  result = pal_osSemaphoreWait(s_palSelectSemaphore, 1, &counters);
00573              }
00574              if (PAL_ERR_RTOS_TIMEOUT != result ) // make sure count is actually 0
00575              {
00576                  return result; //single exit ??
00577              }
00578              
00579          }
00580          for (uint32_t index = 0; index < numberOfSockets; index++)
00581          {
00582              s_select_event_happened[index] = 0; 
00583              palSocketStatus[index] = 0;
00584          }
00585          
00586          for (index = 0; index < numberOfSockets; index++)
00587          {
00588              Socket* socketObj = (Socket*)socketsToCheck[index];
00589              socketObj->attach(s_palSelectPalCallbackFunctions[index]);
00590          }
00591 
00592          result = pal_osSemaphoreWait(s_palSelectSemaphore, timeoutInMiliseconds, &counter);
00593          if (result == PAL_SUCCESS)
00594          {
00595              for (index = 0; index < numberOfSockets; index++)
00596              {
00597                  if (s_select_event_happened[index] > 0)
00598                  {
00599                      palSocketStatus[index] |= PAL_NET_SOCKET_SELECT_RX_BIT | PAL_NET_SOCKET_SELECT_TX_BIT | PAL_NET_SOCKET_SELECT_ERR_BIT;
00600                      *numberOfSocketsSet = *numberOfSocketsSet +1;
00601                  }
00602              }
00603          }
00604          if (result == PAL_ERR_RTOS_TIMEOUT) // to socket callback has been called to free the semaphore -> no socket events happenet untill the timout.
00605          {
00606              *numberOfSocketsSet = 0; // TODO: add debug prints
00607              result = PAL_SUCCESS; // timeout is not actually an error in this case
00608          }
00609 
00610          for (index = 0; index < numberOfSockets; index++)
00611          {
00612              
00613              Socket* socketObj = (Socket*)socketsToCheck[index];
00614              socketObj->attach(NULL_FUNCTION);
00615          }
00616          return result ;
00617 }
00618 
00619 #if PAL_NET_TCP_AND_TLS_SUPPORT // functionality below supported only in case TCP is supported.
00620 
00621 
00622 palStatus_t pal_plat_listen(palSocket_t socket, int backlog)
00623 {
00624     int result = PAL_SUCCESS;
00625 
00626     TCPServer* socketObj = (TCPServer*)socket;
00627 
00628 
00629     result = socketObj->listen(backlog);
00630     if (result < 0)
00631     {
00632         return translateErrorToPALError(result);
00633     }
00634     return PAL_SUCCESS;
00635 }
00636 
00637 
00638 palStatus_t pal_plat_accept(palSocket_t socket, palSocketAddress_t * address, palSocketLength_t* addressLen, palSocket_t* acceptedSocket)
00639 {
00640     int result = PAL_SUCCESS;
00641     
00642     SocketAddress incomingAddr;
00643 
00644     TCPServer* socketObj = (TCPServer*)socket;
00645     result = socketObj->accept((TCPSocket*)(*acceptedSocket), &incomingAddr);
00646     if (result < 0)
00647     {
00648         result = translateErrorToPALError(result);
00649     }
00650     else
00651     {
00652         result = socketAddressToPalSockAddr(incomingAddr, address, addressLen);
00653     }
00654     return result;
00655 }
00656 
00657 
00658 palStatus_t pal_plat_connect(palSocket_t socket, const palSocketAddress_t* address, palSocketLength_t addressLen)
00659 {
00660     int result = PAL_SUCCESS;
00661     SocketAddress internalAddr;
00662     TCPSocket* socketObj = (TCPSocket*)socket;
00663     
00664     result = palSockAddrToSocketAddress(address, addressLen,  internalAddr);
00665     if (result == PAL_SUCCESS)
00666     {
00667         result = socketObj->connect(internalAddr);
00668         if (result < 0)
00669         {
00670             result =  translateErrorToPALError(result);
00671         }
00672     }
00673 
00674     return result;
00675 }
00676 
00677 palStatus_t pal_plat_recv(palSocket_t socket, void *buf, size_t len, size_t* recievedDataSize)
00678 {
00679     int result = PAL_SUCCESS;
00680     int status = 0;
00681 
00682     TCPSocket* socketObj = (TCPSocket*)socket;
00683 
00684 
00685     status = socketObj->recv(buf, len);
00686     if (status < 0)
00687     {
00688         result = translateErrorToPALError(status);
00689     }
00690     else if (status == 0){
00691         return PAL_ERR_SOCKET_CONNECTION_CLOSED;
00692     }
00693     *recievedDataSize = status;
00694     return result;
00695 }
00696 
00697 palStatus_t pal_plat_send(palSocket_t socket, const void *buf, size_t len, size_t* sentDataSize)
00698 {
00699     palStatus_t result = PAL_SUCCESS;
00700     int status = 0;
00701 
00702     TCPSocket* socketObj = (TCPSocket*)socket;
00703     
00704     status = socketObj->send(buf, len);
00705     if (status < 0)
00706     {
00707         result = translateErrorToPALError(status);
00708     }
00709     else 
00710     {
00711         *sentDataSize = status;
00712     }
00713     return result;
00714 }
00715 
00716 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
00717 
00718 
00719 #if PAL_NET_ASYNCHRONOUS_SOCKET_API
00720 
00721 
00722 palStatus_t pal_plat_asynchronousSocket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, palSocket_t* socket)
00723 {
00724     Socket* socketObj = NULL;
00725     palStatus_t result = pal_plat_socket(domain,  type,  nonBlockingSocket,  interfaceNum, socket);
00726     if (result == PAL_SUCCESS)
00727     {
00728         socketObj = (Socket*)*socket;
00729         socketObj->attach(callback); 
00730     }
00731 
00732     return result;
00733 
00734 }
00735 
00736 #endif
00737 
00738 #if PAL_NET_DNS_SUPPORT
00739 
00740 palStatus_t pal_plat_getAddressInfo(const char *url, palSocketAddress_t *address, palSocketLength_t* length)
00741 {
00742     palStatus_t result = PAL_SUCCESS;
00743 
00744     SocketAddress translatedAddress; // by default use the fist supported net interface - TODO: do we need to select a different interface?
00745     result = s_pal_networkInterfacesSupported[0]->gethostbyname(url, &translatedAddress);
00746     if (result == 0)
00747     {
00748         result = socketAddressToPalSockAddr(translatedAddress, address, length);
00749     }
00750     else // error happened
00751     {
00752         result = translateErrorToPALError(result);
00753     }
00754     return result; 
00755 }
00756 
00757 #endif
00758 
00759 
00760 
00761 
00762 
00763