Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FXAS21002 FXOS8700Q
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 }
Generated on Tue Jul 12 2022 20:21:02 by
