Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
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_AF_INET == palAddr->addressType) 00537 { 00538 palIpV4Addr_t ipV4Addr; 00539 version = NSAPI_IPv4; 00540 result = pal_getSockAddrIPV4Addr(palAddr, ipV4Addr); 00541 if (result == PAL_SUCCESS) 00542 { 00543 output.set_ip_bytes(&ipV4Addr, version); 00544 } 00545 } 00546 else if (PAL_AF_INET6 == palAddr->addressType) 00547 { 00548 palIpV6Addr_t ipV6Addr; 00549 version = NSAPI_IPv6; 00550 result = pal_getSockAddrIPV6Addr(palAddr, ipV6Addr); 00551 if (result == PAL_SUCCESS) 00552 { 00553 output.set_ip_bytes(&ipV6Addr, version); 00554 } 00555 } 00556 00557 return result; 00558 } 00559 00560 PAL_PRIVATE palStatus_t socketAddressToPalSockAddr(SocketAddress& input, palSocketAddress_t* out, palSocketLength_t* length) 00561 { 00562 palStatus_t result = PAL_SUCCESS; 00563 int index = 0; 00564 00565 if (input.get_ip_version() == NSAPI_IPv4) 00566 { 00567 palIpV4Addr_t addr; 00568 const void* tmp = input.get_ip_bytes(); 00569 for (index = 0; index < PAL_IPV4_ADDRESS_SIZE; index++) 00570 { 00571 addr[index] = ((const uint8_t*)tmp)[index]; 00572 } 00573 result = pal_setSockAddrIPV4Addr(out, addr); 00574 *length = PAL_NET_MAX_ADDR_SIZE; // TODO: check 00575 00576 } 00577 else if (input.get_ip_version() == NSAPI_IPv6) 00578 { 00579 palIpV6Addr_t addr; 00580 const void* tmp = input.get_ip_bytes(); 00581 for (index = 0; index < PAL_IPV6_ADDRESS_SIZE; index++) 00582 { 00583 addr[index] = ((const uint8_t*)tmp)[index]; 00584 } 00585 result = pal_setSockAddrIPV6Addr(out, addr); 00586 *length = PAL_NET_MAX_ADDR_SIZE; // TODO: check 00587 } 00588 else 00589 { 00590 result = PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY ; 00591 } 00592 00593 if (result == PAL_SUCCESS) 00594 { 00595 result = pal_setSockAddrPort(out, input.get_port()); 00596 } 00597 return result; 00598 } 00599 00600 00601 00602 00603 palStatus_t pal_plat_socket (palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palSocket_t* socket) 00604 { 00605 int result = PAL_SUCCESS; 00606 PALSocketWrapper* socketObj = NULL; 00607 Socket* internalSocket = NULL; 00608 00609 PAL_VALIDATE_ARGUMENTS((NULL == socket)) 00610 00611 if (PAL_NET_DEFAULT_INTERFACE == interfaceNum) 00612 { 00613 interfaceNum = 0; 00614 } 00615 00616 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 00617 { 00618 internalSocket = new UDPSocket(s_pal_networkInterfacesSupported[interfaceNum]); 00619 } 00620 #if PAL_NET_TCP_AND_TLS_SUPPORT // functionality below supported only in case TCP is supported. 00621 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 00622 { 00623 internalSocket = new TCPSocket(s_pal_networkInterfacesSupported[interfaceNum]); 00624 } 00625 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 00626 { 00627 internalSocket = new TCPServer(s_pal_networkInterfacesSupported[interfaceNum]); 00628 } 00629 #endif 00630 else 00631 { 00632 result = PAL_ERR_INVALID_ARGUMENT ; 00633 } 00634 00635 if ((PAL_SUCCESS == result ) && (NULL == internalSocket)) 00636 { 00637 result = PAL_ERR_NO_MEMORY ; 00638 } 00639 00640 if (PAL_SUCCESS == result) 00641 { 00642 00643 socketObj = new PALSocketWrapper(); 00644 if (NULL != socketObj) 00645 { 00646 if (0 == socketObj->initialize(internalSocket, type, nonBlockingSocket, NULL, NULL)) 00647 { 00648 *socket = (palSocket_t )socketObj; 00649 } 00650 else 00651 { 00652 result = PAL_ERR_INVALID_ARGUMENT ; 00653 } 00654 00655 } 00656 else 00657 { 00658 delete internalSocket; 00659 result = PAL_ERR_NO_MEMORY ; 00660 } 00661 00662 } 00663 00664 if (PAL_SUCCESS != result) //cleanup 00665 { 00666 if (NULL != internalSocket) 00667 { 00668 delete internalSocket; 00669 } 00670 if (NULL != socketObj) 00671 { 00672 delete socketObj; 00673 } 00674 } 00675 return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized) 00676 } 00677 00678 00679 palStatus_t pal_plat_setSocketOptions (palSocket_t socket, int optionName, const void* optionValue, palSocketLength_t optionLength) 00680 { 00681 int result = PAL_SUCCESS; 00682 PALSocketWrapper* socketObj = (PALSocketWrapper*)socket; 00683 int socketOption = PAL_SOCKET_OPTION_ERROR; 00684 00685 PAL_VALIDATE_ARGUMENTS(NULL == socket); 00686 00687 socketOption = translateNSAPItoPALSocketOption(optionName); 00688 if (PAL_SOCKET_OPTION_ERROR != socketOption) 00689 { 00690 if (PAL_SO_REUSEADDR == optionName) 00691 { 00692 result = socketObj->setsockopt(NSAPI_SOCKET, socketOption, optionValue, optionLength); 00693 } 00694 #if PAL_NET_TCP_AND_TLS_SUPPORT 00695 else if (PAL_SO_KEEPIDLE == optionName || 00696 PAL_SO_KEEPINTVL == optionName ) 00697 { 00698 // Timeouts are in milliseconds 00699 uint32_t timeout = (*(int *)optionValue) * 1000; 00700 result = socketObj->setsockopt(NSAPI_SOCKET, socketOption, (void*)&timeout, sizeof(timeout)); 00701 } 00702 #endif 00703 else 00704 { 00705 result = socketObj->setsockopt(NSAPI_SOCKET, socketOption, optionValue, optionLength); 00706 } 00707 00708 if (result < 0) 00709 { 00710 result = translateErrorToPALError(result); 00711 } 00712 } 00713 else 00714 { 00715 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 00716 { 00717 int timeout = *((int*)optionValue); 00718 // SO_xxxTIMEO should only affect blocking sockets - it only limits the block, 00719 // whereas NSAPI's set_timeout is coupled with the blocking setting 00720 if (!socketObj->isNonBlocking()) { 00721 socketObj->set_timeout(timeout); 00722 } 00723 } 00724 else 00725 { 00726 result = PAL_ERR_SOCKET_OPTION_NOT_SUPPORTED ; 00727 } 00728 } 00729 00730 00731 return result; 00732 } 00733 00734 palStatus_t pal_plat_isNonBlocking (palSocket_t socket, bool* isNonBlocking) 00735 { 00736 PALSocketWrapper* socketObj = NULL; 00737 PAL_VALIDATE_ARGUMENTS(NULL == socket); 00738 00739 socketObj = (PALSocketWrapper*)socket; 00740 00741 *isNonBlocking = socketObj->isNonBlocking(); 00742 00743 return PAL_SUCCESS; 00744 00745 } 00746 00747 palStatus_t pal_plat_bind (palSocket_t socket, palSocketAddress_t* myAddress, palSocketLength_t addressLength) 00748 { 00749 int result = PAL_SUCCESS; 00750 PALSocketWrapper* socketObj = (PALSocketWrapper*)socket; 00751 SocketAddress internalAddr; 00752 00753 PAL_VALIDATE_ARGUMENTS ((NULL == socket)); 00754 00755 result = palSockAddrToSocketAddress(myAddress, addressLength, internalAddr); 00756 if (result == 0) 00757 { 00758 result = socketObj->bind(internalAddr); 00759 if (result < 0) 00760 { 00761 result = translateErrorToPALError(result); 00762 } 00763 } 00764 00765 return result; 00766 } 00767 00768 00769 palStatus_t pal_plat_receiveFrom (palSocket_t socket, void* buffer, size_t length, palSocketAddress_t* from, palSocketLength_t* fromLength, size_t* bytesReceived) 00770 { 00771 int result = PAL_SUCCESS; 00772 int status = 0; 00773 *bytesReceived = 0; 00774 SocketAddress sockAddr; 00775 PALSocketWrapper* socketObj; 00776 uint8_t* internalBufferPtr = (uint8_t*)buffer; 00777 uint32_t bufferUsed = 0; 00778 00779 PAL_VALIDATE_ARGUMENTS((NULL == socket)); 00780 00781 socketObj = (PALSocketWrapper*)socket; 00782 00783 if (true == socketObj->isRxBufferSet()) 00784 { 00785 internalBufferPtr[0] = socketObj->getAndResetRxBuffer(); 00786 internalBufferPtr++; 00787 length--; 00788 bufferUsed += 1; 00789 } 00790 00791 if (length > 0) 00792 { 00793 status = socketObj->recvfrom(&sockAddr, internalBufferPtr, length); 00794 if (status < 0) 00795 { 00796 result = translateErrorToPALError(status); 00797 } 00798 else if (status == 0) 00799 { 00800 result = PAL_ERR_SOCKET_CONNECTION_CLOSED ; 00801 } 00802 else // only return address / bytesReceived in case of success 00803 { 00804 if ((NULL != from) && (NULL != fromLength)) 00805 { 00806 result = socketAddressToPalSockAddr(sockAddr, from, fromLength); 00807 } 00808 *bytesReceived = status + bufferUsed; 00809 } 00810 } 00811 else 00812 { 00813 *bytesReceived = bufferUsed; 00814 } 00815 00816 return result; 00817 00818 } 00819 00820 palStatus_t pal_plat_sendTo (palSocket_t socket, const void* buffer, size_t length, const palSocketAddress_t* to, palSocketLength_t toLength, size_t* bytesSent) 00821 { 00822 int result = PAL_SUCCESS; 00823 int status = 0; 00824 SocketAddress sockAddr; 00825 00826 PAL_VALIDATE_ARGUMENTS((NULL == socket)); 00827 00828 PALSocketWrapper* socketObj = (PALSocketWrapper*)socket; 00829 00830 *bytesSent = 0; 00831 result = palSockAddrToSocketAddress(to, toLength, sockAddr); 00832 if (result == 0) 00833 { 00834 status = socketObj->sendto(sockAddr, buffer, length); 00835 if (status < 0) 00836 { 00837 result = translateErrorToPALError(status); 00838 } 00839 else 00840 { 00841 *bytesSent = status; 00842 } 00843 } 00844 00845 return result; 00846 } 00847 00848 palStatus_t pal_plat_close (palSocket_t* socket) 00849 { 00850 int result = PAL_SUCCESS; 00851 if (NULL == *socket) 00852 { 00853 PAL_LOG(DBG, "socket close called on socket which was already closed"); 00854 return result; // socket already closed (or not opened) - no need to close. 00855 } 00856 PALSocketWrapper* socketObj = (PALSocketWrapper*)*socket; 00857 result = socketObj->close(); 00858 if (result < 0) 00859 { 00860 result = translateErrorToPALError(result); 00861 } 00862 delete socketObj; 00863 *socket = NULL; 00864 return result; 00865 } 00866 00867 palStatus_t pal_plat_getNumberOfNetInterfaces ( uint32_t* numInterfaces) 00868 { 00869 *numInterfaces = s_pal_numberOFInterfaces; 00870 return PAL_SUCCESS; 00871 } 00872 00873 palStatus_t pal_plat_getNetInterfaceInfo (uint32_t interfaceNum, palNetInterfaceInfo_t * interfaceInfo) 00874 { 00875 palStatus_t result = PAL_SUCCESS; 00876 const char* address = NULL; 00877 SocketAddress addr; 00878 PAL_VALIDATE_ARGUMENTS((interfaceNum >= s_pal_numberOFInterfaces)); 00879 00880 address = s_pal_networkInterfacesSupported[interfaceNum]->get_ip_address(); // ip address returned is a null terminated string 00881 if (NULL != address) 00882 { 00883 addr.set_ip_address(address); 00884 result = socketAddressToPalSockAddr(addr, &interfaceInfo->address, &interfaceInfo->addressSize); 00885 } 00886 00887 00888 return result; 00889 } 00890 00891 typedef void(*palSelectCallbackFunction_t)(); 00892 00893 PAL_PRIVATE palSemaphoreID_t s_palSelectSemaphore = 0; 00894 PAL_PRIVATE bool s_palSelectSemaphoreInited = false; 00895 uint32_t s_select_event_happened[PAL_NET_SOCKET_SELECT_MAX_SOCKETS]; 00896 00897 // select callbacks definition 00898 // TODO: nirson01 change to define these using a macro. 00899 void palSelectCallback0() 00900 { 00901 s_select_event_happened[0]++; 00902 pal_osSemaphoreRelease(s_palSelectSemaphore); 00903 } 00904 void palSelectCallback1() 00905 { 00906 s_select_event_happened[1]++; 00907 pal_osSemaphoreRelease(s_palSelectSemaphore); 00908 } 00909 void palSelectCallback2() 00910 { 00911 s_select_event_happened[2]++; 00912 pal_osSemaphoreRelease(s_palSelectSemaphore); 00913 } 00914 void palSelectCallback3() 00915 { 00916 s_select_event_happened[3]++; 00917 pal_osSemaphoreRelease(s_palSelectSemaphore); 00918 } 00919 void palSelectCallback4() 00920 { 00921 s_select_event_happened[4]++; 00922 pal_osSemaphoreRelease(s_palSelectSemaphore); 00923 } 00924 void palSelectCallback5() 00925 { 00926 s_select_event_happened[5]++; 00927 pal_osSemaphoreRelease(s_palSelectSemaphore); 00928 } 00929 void palSelectCallback6() 00930 { 00931 s_select_event_happened[6]++; 00932 pal_osSemaphoreRelease(s_palSelectSemaphore); 00933 } 00934 void palSelectCallback7() 00935 { 00936 s_select_event_happened[7]++; 00937 pal_osSemaphoreRelease(s_palSelectSemaphore); 00938 } 00939 00940 palSelectCallbackFunction_t s_palSelectPalCallbackFunctions[PAL_NET_SOCKET_SELECT_MAX_SOCKETS] = { palSelectCallback0, palSelectCallback1, palSelectCallback2, palSelectCallback3, palSelectCallback4, palSelectCallback5, palSelectCallback6, palSelectCallback7 }; 00941 00942 00943 #if PAL_NET_TCP_AND_TLS_SUPPORT // functionality below supported only in case TCP is supported. 00944 00945 00946 palStatus_t pal_plat_listen (palSocket_t socket, int backlog) 00947 { 00948 int result = PAL_SUCCESS; 00949 PAL_VALIDATE_ARGUMENTS(NULL == socket); 00950 00951 PALSocketWrapper* socketObj = (PALSocketWrapper*)socket; 00952 result = socketObj->listen(backlog); 00953 if (result < 0) 00954 { 00955 return translateErrorToPALError(result); 00956 } 00957 return PAL_SUCCESS; 00958 } 00959 00960 00961 palStatus_t pal_plat_accept (palSocket_t socket, palSocketAddress_t * address, palSocketLength_t* addressLen, palSocket_t* acceptedSocket) 00962 { 00963 int result = PAL_SUCCESS; 00964 00965 SocketAddress incomingAddr; 00966 00967 PAL_VALIDATE_ARGUMENTS ((NULL == socket)); 00968 00969 PALSocketWrapper* socketObj = (PALSocketWrapper*)socket; 00970 result = socketObj->accept( (TCPSocket*)(*(PALSocketWrapper**)acceptedSocket)->getActiveSocket(), &incomingAddr); 00971 if (result < 0) 00972 { 00973 result = translateErrorToPALError(result); 00974 } 00975 else 00976 { 00977 result = socketAddressToPalSockAddr(incomingAddr, address, addressLen); 00978 } 00979 return result; 00980 } 00981 00982 00983 palStatus_t pal_plat_connect (palSocket_t socket, const palSocketAddress_t* address, palSocketLength_t addressLen) 00984 { 00985 int result = PAL_SUCCESS; 00986 SocketAddress internalAddr; 00987 PALSocketWrapper* socketObj = (PALSocketWrapper*)socket; 00988 PAL_VALIDATE_ARGUMENTS ((NULL == socket)); 00989 00990 result = palSockAddrToSocketAddress(address, addressLen, internalAddr); 00991 if (result == PAL_SUCCESS) 00992 { 00993 result = socketObj->connect(internalAddr); 00994 if (result < 0) 00995 { 00996 result = translateErrorToPALError(result); 00997 } 00998 } 00999 01000 return result; 01001 } 01002 01003 palStatus_t pal_plat_recv (palSocket_t socket, void *buf, size_t len, size_t* recievedDataSize) 01004 { 01005 int result = PAL_SUCCESS; 01006 int status = 0; 01007 uint8_t* internalBufferPtr = (uint8_t*)buf; 01008 uint32_t bufferUsed = 0; 01009 01010 PALSocketWrapper* socketObj = (PALSocketWrapper*)socket; 01011 PAL_VALIDATE_ARGUMENTS ((NULL == socket)); 01012 01013 if (true == socketObj->isRxBufferSet()) 01014 { 01015 internalBufferPtr[0] = socketObj->getAndResetRxBuffer(); 01016 internalBufferPtr++; 01017 len--; 01018 bufferUsed += 1; 01019 } 01020 01021 if (len > 0) 01022 { 01023 status = socketObj->recv(internalBufferPtr, len); 01024 if (status < 0) 01025 { 01026 result = translateErrorToPALError(status); 01027 } 01028 else if (status == 0) { 01029 return PAL_ERR_SOCKET_CONNECTION_CLOSED ; 01030 } 01031 } 01032 *recievedDataSize = status + bufferUsed; 01033 return result; 01034 } 01035 01036 palStatus_t pal_plat_send (palSocket_t socket, const void *buf, size_t len, size_t* sentDataSize) 01037 { 01038 palStatus_t result = PAL_SUCCESS; 01039 int status = 0; 01040 01041 PALSocketWrapper* socketObj = (PALSocketWrapper*)socket; 01042 PAL_VALIDATE_ARGUMENTS ((NULL == socket)); 01043 01044 status = socketObj->send(buf, len); 01045 if (status < 0) 01046 { 01047 result = translateErrorToPALError(status); 01048 } 01049 else 01050 { 01051 *sentDataSize = status; 01052 } 01053 return result; 01054 } 01055 01056 #endif //PAL_NET_TCP_AND_TLS_SUPPORT 01057 01058 01059 #if PAL_NET_ASYNCHRONOUS_SOCKET_API 01060 01061 01062 palStatus_t pal_plat_asynchronousSocket (palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void* arg, palSocket_t* socket) 01063 { 01064 int result = PAL_SUCCESS; 01065 PALSocketWrapper * socketObj = NULL; 01066 Socket* internalSocket = NULL; 01067 01068 PAL_VALIDATE_ARGUMENTS((NULL == socket)); 01069 01070 if (PAL_NET_DEFAULT_INTERFACE == interfaceNum) 01071 { 01072 interfaceNum = 0; 01073 } 01074 01075 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 01076 { 01077 internalSocket = new UDPSocket(s_pal_networkInterfacesSupported[interfaceNum]); 01078 } 01079 #if PAL_NET_TCP_AND_TLS_SUPPORT // functionality below supported only in case TCP is supported. 01080 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 01081 { 01082 internalSocket = new TCPSocket(s_pal_networkInterfacesSupported[interfaceNum]); 01083 } 01084 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 01085 { 01086 internalSocket = new TCPServer(s_pal_networkInterfacesSupported[interfaceNum]); 01087 } 01088 #endif 01089 else 01090 { 01091 result = PAL_ERR_INVALID_ARGUMENT ; 01092 } 01093 01094 if ((PAL_SUCCESS == result) && (NULL == internalSocket)) 01095 { 01096 result = PAL_ERR_NO_MEMORY ; 01097 } 01098 01099 if (PAL_SUCCESS == result) 01100 { 01101 socketObj = new PALSocketWrapper(); 01102 if (NULL != socketObj) 01103 { 01104 if (0 == socketObj->initialize(internalSocket, type, nonBlockingSocket, callback, arg)) 01105 { 01106 *socket = (palSocket_t )socketObj; 01107 } 01108 else 01109 { 01110 result = PAL_ERR_INVALID_ARGUMENT ; 01111 } 01112 } 01113 else 01114 { 01115 delete internalSocket; 01116 result = PAL_ERR_NO_MEMORY ; 01117 } 01118 } 01119 01120 if (PAL_SUCCESS != result) //cleanup 01121 { 01122 if (NULL != internalSocket) 01123 { 01124 delete internalSocket; 01125 } 01126 if (NULL != socketObj) 01127 { 01128 delete socketObj; 01129 } 01130 } 01131 return result; // TODO(nirson01) ADD debug print for error propagation(once debug print infrastructure is finalized) 01132 } 01133 01134 #endif 01135 01136 #if PAL_NET_DNS_SUPPORT 01137 01138 palStatus_t pal_plat_getAddressInfo (const char *url, palSocketAddress_t *address, palSocketLength_t* length) 01139 { 01140 palStatus_t result = PAL_SUCCESS; 01141 SocketAddress zeroAddress("0.0.0.0"); // zero address for check 01142 SocketAddress translatedAddress; // by default use the fist supported net interface - TODO: do we need to select a different interface? 01143 01144 01145 #if PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_ANY 01146 result = s_pal_networkInterfacesSupported[0]->gethostbyname(url, &translatedAddress); 01147 #elif PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_IPV4_ONLY 01148 result = s_pal_networkInterfacesSupported[0]->gethostbyname(url, &translatedAddress, NSAPI_IPv4); 01149 #elif PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_IPV6_ONLY 01150 result = s_pal_networkInterfacesSupported[0]->gethostbyname(url, &translatedAddress, NSAPI_IPv6); 01151 #else 01152 #error PAL_NET_DNS_IP_SUPPORT is not defined to a valid value. 01153 #endif 01154 01155 if (result == 0) 01156 { 01157 if (zeroAddress == translatedAddress) // got zero address - return error 01158 { 01159 result = PAL_ERR_SOCKET_DNS_ERROR ; 01160 } 01161 else // address ok 01162 { 01163 result = socketAddressToPalSockAddr(translatedAddress, address, length); 01164 } 01165 01166 } 01167 else // error happened 01168 { 01169 result = translateErrorToPALError(result); 01170 } 01171 return result; 01172 } 01173 01174 #endif 01175 01176
Generated on Tue Jul 12 2022 19:01:36 by 1.7.2