Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_network.cpp Source File

pal_plat_network.cpp

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_plat_network.h"
00020 
00021 #include "mbed.h"
00022 
00023 #define TRACE_GROUP "PAL"
00024 
00025 typedef void(*palSelectCallbackFunction_t)();
00026 
00027 #if defined (__CC_ARM) || defined(__IAR_SYSTEMS_ICC__)
00028 
00029 void palSelectCallbackNull(void* arg)
00030 {
00031 }
00032 
00033 #define NULL_FUNCTION palSelectCallbackNull
00034 
00035 
00036 #elif defined (__GNUC__)
00037 
00038 #define NULL_FUNCTION NULL
00039 
00040 #endif
00041 
00042 
00043 #define PAL_SOCKET_OPTION_ERROR (-1)
00044 
00045 
00046 typedef enum {
00047     PAL_PLAT_SOCKET_NOT_CONNECTED = 0,
00048     PAL_PLAT_SOCKET_CONNECTING = 1,
00049     PAL_PLAT_SOCKET_CONNECTED = 2
00050 
00051 } palConnectState;
00052 
00053 
00054 void palConnectCallBack()
00055 {
00056 }
00057 
00058         class PALSocketWrapper
00059         {
00060         public:
00061             PALSocketWrapper() : initialized(false), activeSocket(NULL), isNonBlockingOnCreation(false), callbackFunction(NULL_FUNCTION), callbackArgument(NULL), selectCallbackFunction(NULL), connectState(PAL_PLAT_SOCKET_NOT_CONNECTED), socketTypeVal(PAL_SOCK_DGRAM), attachCallbackObject(NULL), rxBuffer(0), rxBufferSet(false)
00062         {
00063 
00064             }
00065             nsapi_error_t initialize(Socket* socket, palSocketType_t socketType,bool isNonBlocking, palAsyncSocketCallback_t callback, void* argument);
00066             palAsyncSocketCallback_t getCallback( ) const;
00067             void* getCallbackArgument() const ;
00068             bool isNonBlocking() const ;
00069             bool isConnected() const ;
00070             void attachCallback();
00071             Socket* getActiveSocket();
00072             void setActiveSocket(Socket *socket);
00073 
00074             palSocketType_t getSocketType() const;
00075             char getAndResetRxBuffer();
00076             bool isRxBufferSet() const;
00077             palStatus_t setRxBuffer(char data);
00078             void updateCallback(/*palAsyncSocketCallback_t callback, void* argument,*/ palSelectCallbackFunction_t selectCallback);
00079             virtual ~PALSocketWrapper()
00080             {
00081                 if (NULL != activeSocket  )
00082                 {
00083                     activeSocket->close();
00084                     delete activeSocket;
00085                 }
00086             }
00087 
00088             // nsapi socket funcitons exposed:
00089             nsapi_error_t close();
00090             nsapi_error_t bind(const SocketAddress &address);
00091             void set_blocking(bool blocking);
00092             void set_timeout(int timeout);
00093             nsapi_error_t setsockopt(int level, int optname, const void *optval, unsigned optlen);
00094             nsapi_error_t getsockopt(int level, int optname, void *optval, unsigned *optlen);
00095             void attach(mbed::Callback<void()> func);
00096             //void sigio(mbed::Callback<void()> func); // switch attach to sigio for verison 5.4
00097             // nsapi UDP socket funcitons exposed:
00098             nsapi_size_or_error_t recvfrom(SocketAddress *address, void *data, nsapi_size_t size);
00099             nsapi_size_or_error_t sendto(const SocketAddress &address, const void *data, nsapi_size_t size);
00100             //nsapi TCP socket funcitons exposed:
00101             nsapi_error_t connect(const SocketAddress &address);
00102             nsapi_size_or_error_t send(const void *data, nsapi_size_t size);
00103             nsapi_size_or_error_t recv(void *data, nsapi_size_t size);
00104             //nsapi TCP server socket funcitons exposed:
00105             nsapi_error_t listen(int backlog = 1);
00106             Socket* accept(nsapi_error_t *error);
00107             void freeSocket(bool freeSocket);
00108 
00109         private:
00110             bool initialized;
00111             Socket* activeSocket;
00112             bool isNonBlockingOnCreation;
00113             palAsyncSocketCallback_t callbackFunction;
00114             void* callbackArgument;
00115             palSelectCallbackFunction_t selectCallbackFunction;
00116             palConnectState connectState;
00117             palSocketType_t socketTypeVal;
00118             Callback<void()> attachCallbackObject;
00119             events::EventQueue* shared_event_queue;
00120             char rxBuffer;
00121             bool rxBufferSet;
00122             bool deleteSocket;
00123         };
00124 
00125         void PALSocketWrapper::updateCallback( palSelectCallbackFunction_t selectCallback )
00126         {
00127             bool shouldSetCallback = false;
00128             if ((NULL == selectCallbackFunction) && (NULL == callbackFunction)) //callback already set - no need to set again
00129             {
00130                 shouldSetCallback = true;
00131             }
00132 
00133             selectCallbackFunction = selectCallback;
00134 
00135             if ((NULL != selectCallbackFunction) || (NULL != callbackFunction))
00136             {
00137                 if (shouldSetCallback)
00138                 {
00139                     Callback<void()> mycall(this, &PALSocketWrapper::attachCallback);
00140                     activeSocket->sigio(mycall);
00141                 }
00142             }
00143             else
00144             {
00145                 activeSocket->sigio(NULL);
00146             }
00147         }
00148 
00149         Socket* PALSocketWrapper::getActiveSocket()
00150         {
00151             return activeSocket;
00152         }
00153 
00154         void PALSocketWrapper::setActiveSocket(Socket* socket)
00155         {
00156             activeSocket = socket;
00157         }
00158 
00159         char PALSocketWrapper::getAndResetRxBuffer()
00160         {
00161             rxBufferSet = false;
00162             return rxBuffer;
00163         }
00164 
00165         bool PALSocketWrapper::isRxBufferSet() const
00166         {
00167             return rxBufferSet;
00168         }
00169 
00170         palStatus_t PALSocketWrapper::setRxBuffer( char data)
00171         {
00172             PAL_VALIDATE_CONDITION_WITH_ERROR((true == rxBufferSet), PAL_ERR_SOCKET_GENERIC );
00173 
00174             rxBuffer = data;
00175             rxBufferSet = true;
00176 
00177             return PAL_SUCCESS;
00178         }
00179 
00180         palAsyncSocketCallback_t PALSocketWrapper::getCallback() const
00181         {
00182             return callbackFunction;
00183         }
00184 
00185         palSocketType_t  PALSocketWrapper::getSocketType() const
00186         {
00187             return socketTypeVal;
00188         }
00189 
00190 
00191         void * PALSocketWrapper::getCallbackArgument() const
00192         {
00193             return callbackArgument;
00194         }
00195 
00196         bool PALSocketWrapper::isNonBlocking() const
00197         {
00198             return isNonBlockingOnCreation;
00199         }
00200 
00201         bool PALSocketWrapper::isConnected() const
00202         {
00203             return ((PAL_PLAT_SOCKET_CONNECTED == connectState) && (PAL_SOCK_STREAM == socketTypeVal));
00204         }
00205 
00206         void PALSocketWrapper::attachCallback()
00207         {
00208             if (NULL != callbackFunction)
00209             {
00210                 // Since the socket callback may be called from interrupt context, depending on the
00211                 // network interface used, we need to debounce the client callback to happen from
00212                 // a thread context to keep client side implementation platform agnostic.
00213                 assert(shared_event_queue);
00214                 shared_event_queue->call(callbackFunction, callbackArgument);
00215             }
00216             if (NULL != selectCallbackFunction)
00217             {
00218                 // Note: this is not tested yet
00219                 assert(shared_event_queue);
00220                 shared_event_queue->call(selectCallbackFunction);
00221             }
00222             if (PAL_PLAT_SOCKET_CONNECTING == connectState)
00223             {
00224                 connectState = PAL_PLAT_SOCKET_CONNECTED;// if we got a callback while connecting assume we are connected
00225                 if (palConnectCallBack == selectCallbackFunction)
00226                 {
00227                     selectCallbackFunction = NULL;
00228                 }
00229             }
00230         }
00231 
00232         nsapi_error_t  PALSocketWrapper::initialize(Socket* socket, palSocketType_t socketType, bool isNonBlocking, palAsyncSocketCallback_t callback, void* argument)
00233         {
00234         // check that we got a valid socket and the socket type is supported
00235             PAL_VALIDATE_CONDITION_WITH_ERROR(((true == initialized) || (NULL == socket) ||
00236                                               ((socketType != PAL_SOCK_STREAM) && (socketType != PAL_SOCK_STREAM_SERVER) &&
00237                                                (socketType != PAL_SOCK_DGRAM))),NSAPI_ERROR_PARAMETER);
00238 
00239 
00240             // Pre fetch and store the shared queue used for bouncing the callbacks out of interrupt
00241             // context, as the user of it may be ran from interrupt and it can't go and start
00242             // creating worker threads from there.
00243             // Note: the code uses mbed_highprio_event_queue() instead of mbed_event_queue()
00244             // as the high priority queue and its thread is likely there already thanks to
00245             // arm_hal_timer.cpp. Technically the client side does not really care, if the events
00246             // were delayed a bit by other events or not.
00247             shared_event_queue = mbed_highprio_event_queue();
00248             PAL_VALIDATE_CONDITION_WITH_ERROR((shared_event_queue == NULL),NSAPI_ERROR_UNSUPPORTED);
00249 
00250             Callback<void()> mycall(this, &PALSocketWrapper::attachCallback);
00251             attachCallbackObject = mycall;
00252             activeSocket = socket;
00253             socketTypeVal = socketType;
00254             isNonBlockingOnCreation = isNonBlocking;
00255             deleteSocket = true;
00256             activeSocket->set_blocking(!isNonBlocking);
00257             if (NULL != callback)
00258             {
00259                 callbackFunction = callback;
00260                 callbackArgument = argument;
00261                 activeSocket->sigio(attachCallbackObject);
00262             }
00263 
00264             initialized = true;
00265             return NSAPI_ERROR_OK;
00266         }
00267 
00268         nsapi_error_t PALSocketWrapper::close()
00269         {
00270             nsapi_error_t status= NSAPI_ERROR_OK;
00271             if (NULL != activeSocket)
00272             {
00273                 status = activeSocket->close();
00274                 // When allocated by accept() call, socket will destroy itself on close();
00275                 if (deleteSocket)
00276                 {
00277                     delete activeSocket;
00278                 }
00279                 activeSocket = NULL;
00280             }
00281             return  status;
00282         }
00283 
00284         nsapi_error_t PALSocketWrapper::bind(const SocketAddress &address)
00285         {
00286             nsapi_error_t status = NSAPI_ERROR_OK;
00287             PAL_VALIDATE_CONDITION_WITH_ERROR((false == initialized), NSAPI_ERROR_PARAMETER);
00288             status= activeSocket->bind(address);
00289             return  status;
00290         }
00291 
00292         void PALSocketWrapper::set_blocking(bool blocking)
00293         {
00294             activeSocket->set_blocking(blocking);
00295         }
00296 
00297         void PALSocketWrapper::set_timeout(int timeout)
00298         {
00299             activeSocket->set_timeout(timeout);
00300         }
00301 
00302         nsapi_error_t PALSocketWrapper::setsockopt(int level, int optname, const void *optval, unsigned optlen)
00303         {
00304             nsapi_error_t status = NSAPI_ERROR_OK;
00305             PAL_VALIDATE_CONDITION_WITH_ERROR((false == initialized),NSAPI_ERROR_PARAMETER);
00306             status = activeSocket->setsockopt(level,  optname, optval,  optlen);
00307             return  status;
00308         }
00309 
00310         nsapi_error_t PALSocketWrapper::getsockopt(int level, int optname, void *optval, unsigned *optlen)
00311         {
00312             nsapi_error_t status = NSAPI_ERROR_OK;
00313             PAL_VALIDATE_CONDITION_WITH_ERROR((false == initialized),NSAPI_ERROR_PARAMETER);
00314             status = activeSocket->getsockopt( level,  optname,  optval,  optlen);
00315             return  status;
00316         }
00317 
00318         void PALSocketWrapper::attach(mbed::Callback<void()> func)
00319         {
00320             activeSocket->sigio(func);
00321         }
00322         //void sigio(mbed::Callback<void()> func); // switch attach to sigio for verison 5.4
00323         // nsapi UDP socket funcitons exposed:
00324         nsapi_size_or_error_t PALSocketWrapper::recvfrom(SocketAddress *address, void *data, nsapi_size_t size)
00325         {
00326             nsapi_size_or_error_t status = NSAPI_ERROR_OK;
00327             PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_DGRAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // udp sockets only
00328 
00329             status = activeSocket->recvfrom(address, data,  size);
00330             return  status;
00331         }
00332 
00333         nsapi_size_or_error_t PALSocketWrapper::sendto(const SocketAddress &address, const void *data, nsapi_size_t size)
00334         {
00335             nsapi_size_or_error_t status = NSAPI_ERROR_OK;
00336             PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_DGRAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // udp sockets only
00337             status = activeSocket->sendto(address, data, size);
00338             return  status;
00339         }
00340 
00341         //nsapi TCP socket funcitons exposed:
00342         nsapi_error_t PALSocketWrapper::connect(const SocketAddress &address)
00343         {
00344             nsapi_error_t status = NSAPI_ERROR_OK;
00345             PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM != socketTypeVal)), NSAPI_ERROR_PARAMETER);  // tcp sockets only
00346 
00347             connectState = PAL_PLAT_SOCKET_CONNECTING;
00348             updateCallback(palConnectCallBack); // make sure callback is enabled to see if we get callback to signal connections end
00349             status = activeSocket->connect(address);
00350             if (status >= 0 || status == NSAPI_ERROR_IS_CONNECTED)
00351             {
00352                 connectState = PAL_PLAT_SOCKET_CONNECTED;
00353                 updateCallback(NULL); // make sure callback is enabled to see if we get callback to signal connections end
00354             }
00355             else if ((NSAPI_ERROR_WOULD_BLOCK != status) && (NSAPI_ERROR_IN_PROGRESS != status) && (NSAPI_ERROR_ALREADY != status))
00356             {
00357                 connectState = PAL_PLAT_SOCKET_NOT_CONNECTED;
00358             }
00359             return  status;
00360         }
00361 
00362         nsapi_size_or_error_t PALSocketWrapper::send(const void *data, nsapi_size_t size)
00363         {
00364             nsapi_size_or_error_t status = NSAPI_ERROR_OK;
00365             PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // tcp sockets only
00366 
00367             status = ((TCPSocket*)activeSocket)->send(data, size);
00368             return  status;
00369         }
00370 
00371         nsapi_size_or_error_t PALSocketWrapper::recv(void *data, nsapi_size_t size)
00372         {
00373             nsapi_size_or_error_t status = NSAPI_ERROR_OK;
00374             PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM != socketTypeVal)),NSAPI_ERROR_PARAMETER); // tcp sockets only
00375             status = activeSocket->recv(data, size);
00376             return  status;
00377         }
00378         //nsapi TCP server socket funcitons exposed:
00379         nsapi_error_t PALSocketWrapper::listen(int backlog )
00380         {
00381             nsapi_error_t status = NSAPI_ERROR_OK;
00382             PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM_SERVER != socketTypeVal)), NSAPI_ERROR_PARAMETER); // udp sockets only
00383             status = activeSocket->listen(backlog);
00384             return  status;
00385         }
00386 
00387         Socket* PALSocketWrapper::accept(nsapi_error_t *error)
00388         {
00389             *error = NSAPI_ERROR_OK;
00390 
00391             if (!initialized || PAL_SOCK_STREAM_SERVER != socketTypeVal) {
00392                 *error = NSAPI_ERROR_PARAMETER;
00393             }
00394 
00395             return activeSocket->accept(error);
00396         }
00397 
00398         void PALSocketWrapper::freeSocket(bool freeSocket)
00399         {
00400            deleteSocket = freeSocket;
00401         }
00402 
00403 
00404 PAL_PRIVATE NetworkInterface* s_pal_networkInterfacesSupported[PAL_MAX_SUPORTED_NET_INTERFACES] = { 0 };
00405 
00406 PAL_PRIVATE  uint32_t s_pal_numberOFInterfaces = 0;
00407 
00408 PAL_PRIVATE  uint32_t s_pal_network_initialized = 0;
00409 
00410 PAL_PRIVATE palStatus_t create_socket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void* arg,  palSocket_t* socket);
00411 
00412 PAL_PRIVATE palStatus_t translateErrorToPALError(int errnoValue)
00413 {
00414     palStatus_t status;
00415     switch (errnoValue)
00416     {
00417     case NSAPI_ERROR_NO_MEMORY:
00418         status = PAL_ERR_NO_MEMORY ;
00419         break;
00420     case NSAPI_ERROR_PARAMETER:
00421         status = PAL_ERR_SOCKET_INVALID_VALUE ;
00422         break;
00423     case NSAPI_ERROR_WOULD_BLOCK:
00424         status = PAL_ERR_SOCKET_WOULD_BLOCK ;
00425         break;
00426     case NSAPI_ERROR_DNS_FAILURE:
00427         status = PAL_ERR_SOCKET_DNS_ERROR ;
00428         break;
00429     case NSAPI_ERROR_DHCP_FAILURE:
00430         status = PAL_ERR_SOCKET_HDCP_ERROR ;
00431         break;
00432     case NSAPI_ERROR_AUTH_FAILURE:
00433         status = PAL_ERR_SOCKET_AUTH_ERROR ;
00434         break;
00435     case NSAPI_ERROR_NO_ADDRESS:
00436         status = PAL_ERR_SOCKET_INVALID_ADDRESS ;
00437         break;
00438     case NSAPI_ERROR_NO_CONNECTION:
00439         status = PAL_ERR_SOCKET_NOT_CONNECTED ;
00440         break;
00441     case NSAPI_ERROR_DEVICE_ERROR:
00442         status = PAL_ERR_SOCKET_INPUT_OUTPUT_ERROR ;
00443         break;
00444     case NSAPI_ERROR_UNSUPPORTED:
00445         status = PAL_ERR_NOT_SUPPORTED ;
00446         break;
00447     case NSAPI_ERROR_NO_SOCKET:
00448         status = PAL_ERR_SOCKET_ALLOCATION_FAILED ;
00449         break;
00450     case NSAPI_ERROR_IN_PROGRESS:
00451     case NSAPI_ERROR_ALREADY:
00452         status = PAL_ERR_SOCKET_IN_PROGRES ;
00453         break;
00454     case NSAPI_ERROR_IS_CONNECTED:
00455         status = PAL_SUCCESS;
00456         break;
00457     default:
00458         PAL_LOG_ERR("translateErrorToPALError() cannot translate %d", errnoValue);
00459         status = PAL_ERR_SOCKET_GENERIC ;
00460         break;
00461     }
00462     return status;
00463 }
00464 
00465 palStatus_t pal_plat_socketsInit(void* context)
00466 {
00467     (void)context; // replace with macro
00468     int result = PAL_SUCCESS;
00469     if (s_pal_network_initialized == 1)
00470     {
00471         return PAL_SUCCESS; // already initialized.
00472     }
00473 
00474     s_pal_network_initialized = 1;
00475 
00476     return result;
00477 }
00478 
00479 palStatus_t pal_plat_registerNetworkInterface(void* context, uint32_t* interfaceIndex)
00480 {
00481     palStatus_t result = PAL_SUCCESS;
00482     uint32_t index = 0;
00483     bool found = false;
00484 
00485     for (index = 0; index < s_pal_numberOFInterfaces; index++) // if specific context already registered return exisitng index instead of registering again.
00486     {
00487         if (s_pal_networkInterfacesSupported[index] == context)
00488         {
00489             found = true;
00490             *interfaceIndex = index;
00491             break;
00492         }
00493     }
00494 
00495     if (false == found)
00496     {
00497         if (s_pal_numberOFInterfaces < PAL_MAX_SUPORTED_NET_INTERFACES)
00498         {
00499             s_pal_networkInterfacesSupported[s_pal_numberOFInterfaces] = (NetworkInterface*)context;
00500             *interfaceIndex = s_pal_numberOFInterfaces;
00501             ++s_pal_numberOFInterfaces;
00502         }
00503         else
00504         {
00505             result = PAL_ERR_SOCKET_MAX_NUMBER_OF_INTERFACES_REACHED ;
00506         }
00507     }
00508 
00509     return result;
00510 }
00511 
00512 palStatus_t pal_plat_unregisterNetworkInterface (uint32_t interfaceIndex)
00513 {
00514     s_pal_networkInterfacesSupported[interfaceIndex] = NULL;
00515     --s_pal_numberOFInterfaces;
00516     return PAL_SUCCESS;
00517 }
00518 
00519 palStatus_t pal_plat_socketsTerminate(void* context)
00520 {
00521     (void)context; // replace with macro
00522     return PAL_SUCCESS;
00523 }
00524 
00525 PAL_PRIVATE int translateNSAPItoPALSocketOption(int option)
00526 {
00527     int optionVal = PAL_SOCKET_OPTION_ERROR;
00528     switch (option)
00529     {
00530     case PAL_SO_REUSEADDR:
00531         optionVal = NSAPI_REUSEADDR;
00532         break;
00533 #if PAL_NET_TCP_AND_TLS_SUPPORT // socket options below supported only if TCP is supported.
00534     case PAL_SO_KEEPALIVE:
00535         optionVal = NSAPI_KEEPALIVE;
00536         break;
00537     case PAL_SO_KEEPIDLE:
00538         optionVal = NSAPI_KEEPIDLE;
00539         break;
00540     case PAL_SO_KEEPINTVL:
00541         optionVal = NSAPI_KEEPINTVL;
00542         break;
00543 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
00544     case PAL_SO_SNDTIMEO:
00545     case PAL_SO_RCVTIMEO:
00546     default:
00547         optionVal = PAL_SOCKET_OPTION_ERROR;
00548     }
00549     return optionVal;
00550 }
00551 
00552 
00553 PAL_PRIVATE palStatus_t palSockAddrToSocketAddress(const palSocketAddress_t* palAddr, int length, SocketAddress& output)
00554 {
00555     palStatus_t result = PAL_SUCCESS;
00556     uint16_t port = 0;
00557     nsapi_version_t version = NSAPI_IPv4;
00558 
00559     result = pal_getSockAddrPort(palAddr, &port);
00560     if (result != PAL_SUCCESS)
00561     {
00562         return result;
00563     }
00564     output.set_port(port);
00565 
00566 #if PAL_SUPPORT_IP_V4
00567     if (PAL_AF_INET == palAddr->addressType)
00568     {
00569         palIpV4Addr_t ipV4Addr;
00570         version = NSAPI_IPv4;
00571         result = pal_getSockAddrIPV4Addr(palAddr, ipV4Addr);
00572         if (result == PAL_SUCCESS)
00573         {
00574             output.set_ip_bytes(&ipV4Addr, version);
00575         }
00576     }
00577 #endif
00578 #if PAL_SUPPORT_IP_V6
00579     if (PAL_AF_INET6 == palAddr->addressType)
00580     {
00581         palIpV6Addr_t ipV6Addr;
00582         version = NSAPI_IPv6;
00583         result = pal_getSockAddrIPV6Addr(palAddr, ipV6Addr);
00584         if (result == PAL_SUCCESS)
00585         {
00586             output.set_ip_bytes(&ipV6Addr, version);
00587         }
00588     }
00589 #endif
00590 
00591     return result;
00592 }
00593 
00594 #if (PAL_DNS_API_VERSION != 2)
00595 PAL_PRIVATE palStatus_t socketAddressToPalSockAddr(SocketAddress& input, palSocketAddress_t* out, palSocketLength_t* length)
00596 #else
00597 PAL_PRIVATE palStatus_t socketAddressToPalSockAddr(SocketAddress& input, palSocketAddress_t* out)
00598 #endif
00599 {
00600     palStatus_t result = PAL_SUCCESS;
00601     int index = 0;
00602     bool found = false;
00603 
00604 #if PAL_SUPPORT_IP_V4
00605     if (input.get_ip_version() == NSAPI_IPv4)
00606     {
00607         palIpV4Addr_t addr;
00608         found = true;
00609         const void* tmp = input.get_ip_bytes();
00610         for (index = 0; index < PAL_IPV4_ADDRESS_SIZE; index++)
00611         {
00612             addr[index] = ((const uint8_t*)tmp)[index];
00613         }
00614         result = pal_setSockAddrIPV4Addr(out, addr);
00615 #if (PAL_DNS_API_VERSION != 2)
00616         *length = PAL_NET_MAX_ADDR_SIZE;  // TODO: check
00617 #endif
00618 
00619     }
00620 #endif
00621 #if PAL_SUPPORT_IP_V6
00622     if (input.get_ip_version() == NSAPI_IPv6)
00623     {
00624         palIpV6Addr_t addr;
00625         found = true;
00626         const void* tmp = input.get_ip_bytes();
00627         for (index = 0; index < PAL_IPV6_ADDRESS_SIZE; index++)
00628         {
00629             addr[index] = ((const uint8_t*)tmp)[index];
00630         }
00631         result = pal_setSockAddrIPV6Addr(out, addr);
00632 #if (PAL_DNS_API_VERSION != 2)
00633         *length = PAL_NET_MAX_ADDR_SIZE;  // TODO: check
00634 #endif
00635     }
00636 #endif
00637     if (false == found )
00638     {
00639         result = PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY ;
00640     }
00641 
00642     if (result == PAL_SUCCESS)
00643     {
00644         result = pal_setSockAddrPort(out, input.get_port());
00645     }
00646     return result;
00647 }
00648 
00649 palStatus_t pal_plat_socket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palSocket_t* socket)
00650 {
00651     return create_socket(domain, type, nonBlockingSocket, interfaceNum, NULL, NULL, socket);
00652 }
00653 
00654 palStatus_t pal_plat_setSocketOptions(palSocket_t socket, int optionName, const void* optionValue, palSocketLength_t optionLength)
00655 {
00656     int result = PAL_SUCCESS;
00657     PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
00658     int socketOption = PAL_SOCKET_OPTION_ERROR;
00659 
00660     PAL_VALIDATE_ARGUMENTS(NULL == socket);
00661 
00662     socketOption = translateNSAPItoPALSocketOption(optionName);
00663     if (PAL_SOCKET_OPTION_ERROR != socketOption)
00664     {
00665         if (PAL_SO_REUSEADDR == optionName)
00666         {
00667             result = socketObj->setsockopt(NSAPI_SOCKET, socketOption, optionValue, optionLength);
00668         }
00669 #if PAL_NET_TCP_AND_TLS_SUPPORT
00670         else if (PAL_SO_KEEPIDLE == optionName ||
00671                  PAL_SO_KEEPINTVL == optionName )
00672         {
00673                 // Timeouts are in milliseconds
00674                 uint32_t timeout = (*(int *)optionValue) * 1000;
00675                 result = socketObj->setsockopt(NSAPI_SOCKET, socketOption, (void*)&timeout, sizeof(timeout));
00676         }
00677 #endif
00678         else
00679         {
00680             result = socketObj->setsockopt(NSAPI_SOCKET, socketOption, optionValue, optionLength);
00681         }
00682 
00683         if (result < 0)
00684         {
00685             result = translateErrorToPALError(result);
00686         }
00687     }
00688     else
00689     {
00690         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
00691         {
00692             int timeout = *((int*)optionValue);
00693             // SO_xxxTIMEO should only affect blocking sockets - it only limits the block,
00694             // whereas NSAPI's set_timeout is coupled with the blocking setting
00695             if (!socketObj->isNonBlocking()) {
00696                 socketObj->set_timeout(timeout);
00697             }
00698         }
00699         else
00700         {
00701             result = PAL_ERR_SOCKET_OPTION_NOT_SUPPORTED ;
00702         }
00703     }
00704 
00705 
00706     return result;
00707 }
00708 
00709 palStatus_t pal_plat_isNonBlocking(palSocket_t socket, bool* isNonBlocking)
00710 {
00711     PALSocketWrapper* socketObj =  NULL;
00712     PAL_VALIDATE_ARGUMENTS(NULL == socket);
00713 
00714     socketObj =  (PALSocketWrapper*)socket;
00715 
00716     *isNonBlocking = socketObj->isNonBlocking();
00717 
00718     return PAL_SUCCESS;
00719 
00720 }
00721 
00722 palStatus_t pal_plat_bind(palSocket_t socket, palSocketAddress_t* myAddress, palSocketLength_t addressLength)
00723 {
00724     int result = PAL_SUCCESS;
00725     PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
00726     SocketAddress internalAddr;
00727 
00728     PAL_VALIDATE_ARGUMENTS ((NULL == socket));
00729 
00730     result = palSockAddrToSocketAddress(myAddress, addressLength, internalAddr);
00731     if (result == 0)
00732     {
00733         result = socketObj->bind(internalAddr);
00734         if (result < 0)
00735         {
00736             result =  translateErrorToPALError(result);
00737         }
00738     }
00739 
00740     return result;
00741 }
00742 
00743 
00744 palStatus_t pal_plat_receiveFrom(palSocket_t socket, void* buffer, size_t length, palSocketAddress_t* from, palSocketLength_t* fromLength, size_t* bytesReceived)
00745 {
00746     int result = PAL_SUCCESS;
00747     int status = 0;
00748     *bytesReceived = 0;
00749     SocketAddress sockAddr;
00750     PALSocketWrapper* socketObj;
00751     uint8_t* internalBufferPtr = (uint8_t*)buffer;
00752     uint32_t bufferUsed = 0;
00753 
00754     PAL_VALIDATE_ARGUMENTS((NULL == socket));
00755 
00756     socketObj = (PALSocketWrapper*)socket;
00757 
00758     if (true == socketObj->isRxBufferSet())
00759     {
00760         internalBufferPtr[0] = socketObj->getAndResetRxBuffer();
00761         internalBufferPtr++;
00762         length--;
00763         bufferUsed += 1;
00764     }
00765 
00766     if (length > 0)
00767     {
00768         status = socketObj->recvfrom(&sockAddr, internalBufferPtr, length);
00769         if (status < 0)
00770         {
00771             result = translateErrorToPALError(status);
00772         }
00773         else if (status == 0)
00774         {
00775             result = PAL_ERR_SOCKET_CONNECTION_CLOSED ;
00776         }
00777         else // only return address / bytesReceived in case of success
00778         {
00779 #if (PAL_DNS_API_VERSION != 2)
00780             if ((NULL != from) && (NULL != fromLength))
00781             {
00782                 result = socketAddressToPalSockAddr(sockAddr, from, fromLength);
00783             }
00784 #else
00785             if (NULL != from)
00786             {
00787                 result = socketAddressToPalSockAddr(sockAddr, from);
00788             }
00789 #endif
00790             *bytesReceived = status + bufferUsed;
00791         }
00792     }
00793     else
00794     {
00795         *bytesReceived = bufferUsed;
00796     }
00797 
00798     return result;
00799 
00800 }
00801 
00802 palStatus_t pal_plat_sendTo(palSocket_t socket, const void* buffer, size_t length, const palSocketAddress_t* to, palSocketLength_t toLength, size_t* bytesSent)
00803 {
00804     int result = PAL_SUCCESS;
00805     int status = 0;
00806     SocketAddress sockAddr;
00807 
00808     PAL_VALIDATE_ARGUMENTS((NULL == socket));
00809 
00810     PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
00811 
00812     *bytesSent = 0;
00813     result = palSockAddrToSocketAddress(to, toLength, sockAddr);
00814     if (result == 0)
00815     {
00816         status = socketObj->sendto(sockAddr, buffer, length);
00817         if (status < 0)
00818         {
00819             result = translateErrorToPALError(status);
00820         }
00821         else
00822         {
00823             *bytesSent = status;
00824         }
00825     }
00826 
00827     return result;
00828 }
00829 
00830 palStatus_t pal_plat_close(palSocket_t* socket)
00831 {
00832     int result = PAL_SUCCESS;
00833     if (NULL == *socket)
00834     {
00835         PAL_LOG_DBG("socket close called on socket which was already closed");
00836         return result; // socket already closed (or not opened) - no need to close.
00837     }
00838     PALSocketWrapper* socketObj = (PALSocketWrapper*)*socket;
00839     result = socketObj->close();
00840     if (result < 0)
00841     {
00842         result =  translateErrorToPALError(result);
00843     }
00844     delete socketObj;
00845     *socket = NULL;
00846     return result;
00847 }
00848 
00849 palStatus_t pal_plat_getNumberOfNetInterfaces( uint32_t* numInterfaces)
00850 {
00851     *numInterfaces =  s_pal_numberOFInterfaces;
00852     return PAL_SUCCESS;
00853 }
00854 
00855 palStatus_t pal_plat_getNetInterfaceInfo(uint32_t interfaceNum, palNetInterfaceInfo_t * interfaceInfo)
00856 {
00857     palStatus_t result = PAL_SUCCESS;
00858     const char* address = NULL;
00859     SocketAddress addr;
00860     PAL_VALIDATE_ARGUMENTS((interfaceNum >= s_pal_numberOFInterfaces));
00861 
00862     address = s_pal_networkInterfacesSupported[interfaceNum]->get_ip_address(); // ip address returned is a null terminated string
00863     if (NULL != address)
00864     {
00865         addr.set_ip_address(address);
00866 #if (PAL_DNS_API_VERSION != 2)
00867         result = socketAddressToPalSockAddr(addr, &interfaceInfo->address, &interfaceInfo->addressSize);
00868 #else
00869         result = socketAddressToPalSockAddr(addr, &interfaceInfo->address);
00870 #endif
00871     }
00872 
00873 
00874     return result;
00875 }
00876 
00877 typedef void(*palSelectCallbackFunction_t)();
00878 
00879 PAL_PRIVATE palSemaphoreID_t s_palSelectSemaphore = 0;
00880 
00881 uint32_t s_select_event_happened[PAL_NET_SOCKET_SELECT_MAX_SOCKETS];
00882 
00883 // select callbacks definition
00884 // TODO: nirson01 change to define these using a macro.
00885 void palSelectCallback0()
00886 {
00887     s_select_event_happened[0]++;
00888     pal_osSemaphoreRelease(s_palSelectSemaphore);
00889 }
00890 void palSelectCallback1()
00891 {
00892     s_select_event_happened[1]++;
00893     pal_osSemaphoreRelease(s_palSelectSemaphore);
00894 }
00895 void palSelectCallback2()
00896 {
00897     s_select_event_happened[2]++;
00898     pal_osSemaphoreRelease(s_palSelectSemaphore);
00899 }
00900 void palSelectCallback3()
00901 {
00902     s_select_event_happened[3]++;
00903     pal_osSemaphoreRelease(s_palSelectSemaphore);
00904 }
00905 void palSelectCallback4()
00906 {
00907     s_select_event_happened[4]++;
00908     pal_osSemaphoreRelease(s_palSelectSemaphore);
00909 }
00910 void palSelectCallback5()
00911 {
00912     s_select_event_happened[5]++;
00913     pal_osSemaphoreRelease(s_palSelectSemaphore);
00914 }
00915 void palSelectCallback6()
00916 {
00917     s_select_event_happened[6]++;
00918     pal_osSemaphoreRelease(s_palSelectSemaphore);
00919 }
00920 void palSelectCallback7()
00921 {
00922     s_select_event_happened[7]++;
00923     pal_osSemaphoreRelease(s_palSelectSemaphore);
00924 }
00925 
00926 palSelectCallbackFunction_t s_palSelectPalCallbackFunctions[PAL_NET_SOCKET_SELECT_MAX_SOCKETS] = { palSelectCallback0, palSelectCallback1, palSelectCallback2, palSelectCallback3, palSelectCallback4, palSelectCallback5, palSelectCallback6, palSelectCallback7 };
00927 
00928 
00929 #if PAL_NET_TCP_AND_TLS_SUPPORT // functionality below supported only in case TCP is supported.
00930 
00931 
00932 palStatus_t pal_plat_listen(palSocket_t socket, int backlog)
00933 {
00934     int result = PAL_SUCCESS;
00935     PAL_VALIDATE_ARGUMENTS(NULL == socket);
00936 
00937     PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
00938     result = socketObj->listen(backlog);
00939     if (result < 0)
00940     {
00941         return translateErrorToPALError(result);
00942     }
00943     return PAL_SUCCESS;
00944 }
00945 
00946 
00947 palStatus_t pal_plat_accept(palSocket_t socket, palSocketAddress_t * address, palSocketLength_t* addressLen, palSocket_t* acceptedSocket)
00948 {
00949     int result = PAL_SUCCESS;
00950 
00951     PAL_VALIDATE_ARGUMENTS ((NULL == socket));
00952     PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
00953     PALSocketWrapper *out = (PALSocketWrapper*)*acceptedSocket;
00954 
00955     out->setActiveSocket(socketObj->accept(&result));
00956     out->freeSocket(false);
00957 
00958     if (result < 0)
00959     {
00960         result = translateErrorToPALError(result);
00961     }
00962 
00963     return result;
00964 }
00965 
00966 
00967 palStatus_t pal_plat_connect(palSocket_t socket, const palSocketAddress_t* address, palSocketLength_t addressLen)
00968 {
00969     int result = PAL_SUCCESS;
00970     SocketAddress internalAddr;
00971     PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
00972     PAL_VALIDATE_ARGUMENTS ((NULL == socket));
00973 
00974     result = palSockAddrToSocketAddress(address, addressLen,  internalAddr);
00975     if (result == PAL_SUCCESS)
00976     {
00977         result = socketObj->connect(internalAddr);
00978         if (result < 0)
00979         {
00980             result =  translateErrorToPALError(result);
00981         }
00982     }
00983 
00984     return result;
00985 }
00986 
00987 palStatus_t pal_plat_recv(palSocket_t socket, void *buf, size_t len, size_t* recievedDataSize)
00988 {
00989 
00990     int result = PAL_SUCCESS;
00991     int status = 0;
00992     uint8_t* internalBufferPtr = (uint8_t*)buf;
00993     uint32_t bufferUsed = 0;
00994 
00995     PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
00996     PAL_VALIDATE_ARGUMENTS ((NULL == socket));
00997 
00998     if (true == socketObj->isRxBufferSet())
00999     {
01000         internalBufferPtr[0] = socketObj->getAndResetRxBuffer();
01001         internalBufferPtr++;
01002         len--;
01003         bufferUsed += 1;
01004     }
01005 
01006     if (len > 0)
01007     {
01008         status = socketObj->recv(internalBufferPtr, len);
01009         if (status < 0)
01010         {
01011             result = translateErrorToPALError(status);
01012         }
01013         else if (status == 0) {
01014             return PAL_ERR_SOCKET_CONNECTION_CLOSED ;
01015         }
01016     }
01017 
01018     *recievedDataSize = status + bufferUsed;
01019     return result;
01020 }
01021 
01022 palStatus_t pal_plat_send(palSocket_t socket, const void *buf, size_t len, size_t* sentDataSize)
01023 {
01024     palStatus_t result = PAL_SUCCESS;
01025     int status = 0;
01026 
01027     PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
01028     PAL_VALIDATE_ARGUMENTS ((NULL == socket));
01029 
01030     status = socketObj->send(buf, len);
01031 
01032     if (status < 0)
01033     {
01034         PAL_LOG_DBG("pal_plat_send status %d",status);
01035         result = translateErrorToPALError(status);
01036     }
01037     else
01038     {
01039         *sentDataSize = status;
01040     }
01041 
01042     return result;
01043 }
01044 
01045 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
01046 
01047 
01048 #if PAL_NET_ASYNCHRONOUS_SOCKET_API
01049 
01050 
01051 palStatus_t pal_plat_asynchronousSocket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void* arg,  palSocket_t* socket)
01052 {
01053     return create_socket(domain, type, nonBlockingSocket, interfaceNum, callback, arg, socket);
01054 }
01055 
01056 #endif
01057 
01058 #if PAL_NET_DNS_SUPPORT
01059 #if (PAL_DNS_API_VERSION == 0) || (PAL_DNS_API_VERSION == 1)
01060 palStatus_t pal_plat_getAddressInfo(const char *url, palSocketAddress_t *address, palSocketLength_t* length)
01061 {
01062     palStatus_t result = PAL_SUCCESS;
01063     SocketAddress translatedAddress; // by default use the fist supported net interface - TODO: do we need to select a different interface?
01064     if (s_pal_networkInterfacesSupported[0]) {
01065 #if PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_ANY
01066         result = s_pal_networkInterfacesSupported[0]->gethostbyname(url, &translatedAddress);
01067 #elif PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_IPV4_ONLY
01068         result = s_pal_networkInterfacesSupported[0]->gethostbyname(url, &translatedAddress, NSAPI_IPv4);
01069 #elif PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_IPV6_ONLY
01070         result = s_pal_networkInterfacesSupported[0]->gethostbyname(url, &translatedAddress, NSAPI_IPv6);
01071 #else
01072 #error PAL_NET_DNS_IP_SUPPORT is not defined to a valid value.
01073 #endif
01074     } else {
01075         result = PAL_ERR_INVALID_ARGUMENT ;
01076     }
01077 
01078     if (result == 0) {
01079         result = socketAddressToPalSockAddr(translatedAddress, address, length);
01080     }
01081     else { // error happened
01082         result = translateErrorToPALError(result);
01083     }
01084     return result;
01085 }
01086 
01087 #elif (PAL_DNS_API_VERSION == 2)
01088 void pal_plat_getAddressInfoAsync_callback(void *data, nsapi_error_t result, SocketAddress *address)
01089 {
01090     palStatus_t status = PAL_SUCCESS;
01091     pal_asyncAddressInfo_t* info = (pal_asyncAddressInfo_t*)(data);
01092 
01093     if (result == NSAPI_ERROR_OK) {
01094         status = socketAddressToPalSockAddr(*address, info->address);
01095     }
01096     else { // error happened
01097         status = translateErrorToPALError(result);
01098     }
01099 
01100     info->callback(info->url, info->address, status, info->callbackArgument); // invoke callback
01101     free(info);
01102 }
01103 
01104 palStatus_t pal_plat_getAddressInfoAsync(pal_asyncAddressInfo* info)
01105 {
01106     PAL_LOG_DBG("pal_plat_getAddressInfoAsync");
01107     palStatus_t result;
01108 #if PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_ANY
01109     const nsapi_version_t version = NSAPI_UNSPEC;
01110 #elif PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_IPV4_ONLY
01111     const nsapi_version_t version = NSAPI_IPv4;
01112 #elif PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_IPV6_ONLY
01113     const nsapi_version_t version = NSAPI_IPv6;
01114 #else
01115 #error PAL_NET_DNS_IP_SUPPORT is not defined to a valid value.
01116 #endif
01117 
01118     if (s_pal_networkInterfacesSupported[0] == NULL) {
01119         result = PAL_ERR_INVALID_ARGUMENT ;
01120     } else {
01121         result = s_pal_networkInterfacesSupported[0]->gethostbyname_async(info->url, mbed::Callback<void(nsapi_error_t, SocketAddress *)>(pal_plat_getAddressInfoAsync_callback,(void*)info), version);
01122     }
01123 
01124     PAL_LOG_DBG("pal_plat_getAddressInfoAsync result %d", result);
01125     if (result < 0) {
01126         result = translateErrorToPALError(result);
01127     }
01128     else {
01129         /* Skip over setting queryHandle when:
01130          * 1. info->queryHandle not allocated
01131          * 2. if result is zero then callback pal_plat_getAddressInfoAsync_callback will be called immediately and address info has been deallocated. */
01132         if ( (info->queryHandle != NULL) && result) {
01133             *(info->queryHandle) = result;
01134         }
01135         result = PAL_SUCCESS;
01136     }
01137     return result;
01138 }
01139 
01140 palStatus_t pal_plat_cancelAddressInfoAsync(palDNSQuery_t queryHandle)
01141 {
01142     palStatus_t status = PAL_ERR_INVALID_ARGUMENT ;
01143     if (s_pal_networkInterfacesSupported[0]) {
01144         status = s_pal_networkInterfacesSupported[0]->gethostbyname_async_cancel(queryHandle);
01145     }
01146 
01147     if (PAL_SUCCESS != status) {
01148         PAL_LOG_ERR("pal_cancelAddressInfoAsync failed with %ld", status);
01149     }
01150     return status;
01151 }
01152 #else
01153     #error "Please specify the platform PAL_DNS_API_VERSION 0, 1 or 2."
01154 #endif //  PAL_DNS_API_VERSION
01155 #endif
01156 
01157 PAL_PRIVATE palStatus_t create_socket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void* arg,  palSocket_t* socket)
01158 {
01159     int result = PAL_SUCCESS;
01160     PALSocketWrapper * socketObj = NULL;
01161     InternetSocket* internalSocket = NULL;
01162 
01163     PAL_VALIDATE_ARGUMENTS((NULL == socket));
01164 
01165     if (PAL_NET_DEFAULT_INTERFACE == interfaceNum)
01166     {
01167         interfaceNum = 0;
01168     }
01169 
01170     if ((s_pal_numberOFInterfaces > interfaceNum) && (PAL_SOCK_DGRAM == type) && ((PAL_AF_INET == domain) || (PAL_AF_INET6 == domain) || (PAL_AF_UNSPEC == domain))) //check that we got correct parameters for UDP socket
01171     {
01172         internalSocket = new UDPSocket;
01173     }
01174 #if PAL_NET_TCP_AND_TLS_SUPPORT // functionality below supported only in case TCP is supported.
01175     else if ((s_pal_numberOFInterfaces > interfaceNum) && (PAL_SOCK_STREAM == type || PAL_SOCK_STREAM_SERVER == type) && ((PAL_AF_INET == domain) || (PAL_AF_INET6 == domain) || (PAL_AF_UNSPEC == domain))) //check that we got correct parameters for TCP socket
01176     {
01177         internalSocket = new TCPSocket;
01178     }
01179 #endif
01180     else
01181     {
01182         result = PAL_ERR_INVALID_ARGUMENT ;
01183     }
01184 
01185     if (internalSocket && result == PAL_SUCCESS)
01186     {
01187         int result = internalSocket->open(s_pal_networkInterfacesSupported[interfaceNum]);
01188         if (result < 0)
01189         {
01190             result =  translateErrorToPALError(result);
01191         }
01192     }
01193     else
01194     {
01195         result = PAL_ERR_NO_MEMORY ;
01196     }
01197 
01198     if (PAL_SUCCESS == result)
01199     {
01200         socketObj = new PALSocketWrapper();
01201         if (NULL != socketObj)
01202         {
01203             if (0 == socketObj->initialize(internalSocket, type, nonBlockingSocket, callback, arg))
01204             {
01205                 *socket = (palSocket_t)socketObj;
01206             }
01207             else
01208             {
01209                 result = PAL_ERR_INVALID_ARGUMENT ;
01210             }
01211         }
01212         else
01213         {
01214             delete internalSocket;
01215             result = PAL_ERR_NO_MEMORY ;
01216         }
01217     }
01218 
01219     if (PAL_SUCCESS != result) //cleanup
01220     {
01221         delete internalSocket;
01222         delete socketObj;
01223     }
01224     return result;
01225 }