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