Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

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