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.
UDPSocket.cpp
00001 /* Socket 00002 * Copyright (c) 2015 ARM Limited 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 #include "UDPSocket.h" 00018 #include "Timer.h" 00019 #include "mbed_assert.h" 00020 00021 UDPSocket::UDPSocket() 00022 { 00023 } 00024 00025 UDPSocket::~UDPSocket() 00026 { 00027 close(); 00028 } 00029 00030 nsapi_protocol_t UDPSocket::get_proto() 00031 { 00032 return NSAPI_UDP ; 00033 } 00034 00035 nsapi_error_t UDPSocket::connect(const SocketAddress &address) 00036 { 00037 _remote_peer = address; 00038 return NSAPI_ERROR_OK ; 00039 } 00040 00041 nsapi_size_or_error_t UDPSocket::sendto(const char *host, uint16_t port, const void *data, nsapi_size_t size) 00042 { 00043 SocketAddress address; 00044 nsapi_size_or_error_t err = _stack->gethostbyname(host, &address); 00045 if (err) { 00046 return NSAPI_ERROR_DNS_FAILURE ; 00047 } 00048 00049 address.set_port(port); 00050 00051 // sendto is thread safe 00052 return sendto(address, data, size); 00053 } 00054 00055 nsapi_size_or_error_t UDPSocket::sendto(const SocketAddress &address, const void *data, nsapi_size_t size) 00056 { 00057 _lock.lock(); 00058 nsapi_size_or_error_t ret; 00059 00060 _writers++; 00061 00062 while (true) { 00063 if (!_socket) { 00064 ret = NSAPI_ERROR_NO_SOCKET ; 00065 break; 00066 } 00067 00068 _pending = 0; 00069 nsapi_size_or_error_t sent = _stack->socket_sendto(_socket, address, data, size); 00070 if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) { 00071 ret = sent; 00072 break; 00073 } else { 00074 uint32_t flag; 00075 00076 // Release lock before blocking so other threads 00077 // accessing this object aren't blocked 00078 _lock.unlock(); 00079 flag = _event_flag.wait_any(WRITE_FLAG, _timeout); 00080 _lock.lock(); 00081 00082 if (flag & osFlagsError) { 00083 // Timeout break 00084 ret = NSAPI_ERROR_WOULD_BLOCK ; 00085 break; 00086 } 00087 } 00088 } 00089 00090 _writers--; 00091 if (!_socket || !_writers) { 00092 _event_flag.set(FINISHED_FLAG); 00093 } 00094 _lock.unlock(); 00095 return ret; 00096 } 00097 00098 nsapi_size_or_error_t UDPSocket::send(const void *data, nsapi_size_t size) 00099 { 00100 if (!_remote_peer) { 00101 return NSAPI_ERROR_NO_ADDRESS ; 00102 } 00103 return sendto(_remote_peer, data, size); 00104 } 00105 00106 nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer, nsapi_size_t size) 00107 { 00108 _lock.lock(); 00109 nsapi_size_or_error_t ret; 00110 SocketAddress ignored; 00111 00112 if (!address) { 00113 address = &ignored; 00114 } 00115 00116 _readers++; 00117 00118 while (true) { 00119 if (!_socket) { 00120 ret = NSAPI_ERROR_NO_SOCKET ; 00121 break; 00122 } 00123 00124 _pending = 0; 00125 nsapi_size_or_error_t recv = _stack->socket_recvfrom(_socket, address, buffer, size); 00126 00127 // Filter incomming packets using connected peer address 00128 if (recv >= 0 && _remote_peer && _remote_peer != *address) { 00129 continue; 00130 } 00131 00132 // Non-blocking sockets always return. Blocking only returns when success or errors other than WOULD_BLOCK 00133 if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) { 00134 ret = recv; 00135 break; 00136 } else { 00137 uint32_t flag; 00138 00139 // Release lock before blocking so other threads 00140 // accessing this object aren't blocked 00141 _lock.unlock(); 00142 flag = _event_flag.wait_any(READ_FLAG, _timeout); 00143 _lock.lock(); 00144 00145 if (flag & osFlagsError) { 00146 // Timeout break 00147 ret = NSAPI_ERROR_WOULD_BLOCK ; 00148 break; 00149 } 00150 } 00151 } 00152 00153 _readers--; 00154 if (!_socket || !_readers) { 00155 _event_flag.set(FINISHED_FLAG); 00156 } 00157 00158 _lock.unlock(); 00159 return ret; 00160 } 00161 00162 nsapi_size_or_error_t UDPSocket::recv(void *buffer, nsapi_size_t size) 00163 { 00164 return recvfrom(NULL, buffer, size); 00165 } 00166 00167 Socket *UDPSocket::accept(nsapi_error_t *error) 00168 { 00169 if (error) { 00170 *error = NSAPI_ERROR_UNSUPPORTED ; 00171 } 00172 return NULL; 00173 } 00174 00175 nsapi_error_t UDPSocket::listen(int) 00176 { 00177 return NSAPI_ERROR_UNSUPPORTED ; 00178 }
Generated on Tue Aug 9 2022 00:37:23 by
