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 #define TCP_EVENT "UDP_Events" 00022 #define READ_FLAG 0x1u 00023 #define WRITE_FLAG 0x2u 00024 00025 UDPSocket::UDPSocket() 00026 : _pending(0), _event_flag() 00027 { 00028 } 00029 00030 UDPSocket::~UDPSocket() 00031 { 00032 close(); 00033 } 00034 00035 nsapi_protocol_t UDPSocket::get_proto() 00036 { 00037 return NSAPI_UDP ; 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 while (true) { 00060 if (!_socket) { 00061 ret = NSAPI_ERROR_NO_SOCKET ; 00062 break; 00063 } 00064 00065 _pending = 0; 00066 nsapi_size_or_error_t sent = _stack->socket_sendto(_socket, address, data, size); 00067 if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) { 00068 ret = sent; 00069 break; 00070 } else { 00071 uint32_t flag; 00072 00073 // Release lock before blocking so other threads 00074 // accessing this object aren't blocked 00075 _lock.unlock(); 00076 flag = _event_flag.wait_any(WRITE_FLAG, _timeout); 00077 _lock.lock(); 00078 00079 if (flag & osFlagsError) { 00080 // Timeout break 00081 ret = NSAPI_ERROR_WOULD_BLOCK ; 00082 break; 00083 } 00084 } 00085 } 00086 00087 _lock.unlock(); 00088 return ret; 00089 } 00090 00091 nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer, nsapi_size_t size) 00092 { 00093 _lock.lock(); 00094 nsapi_size_or_error_t ret; 00095 00096 while (true) { 00097 if (!_socket) { 00098 ret = NSAPI_ERROR_NO_SOCKET ; 00099 break; 00100 } 00101 00102 _pending = 0; 00103 nsapi_size_or_error_t recv = _stack->socket_recvfrom(_socket, address, buffer, size); 00104 if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) { 00105 ret = recv; 00106 break; 00107 } else { 00108 uint32_t flag; 00109 00110 // Release lock before blocking so other threads 00111 // accessing this object aren't blocked 00112 _lock.unlock(); 00113 flag = _event_flag.wait_any(READ_FLAG, _timeout); 00114 _lock.lock(); 00115 00116 if (flag & osFlagsError) { 00117 // Timeout break 00118 ret = NSAPI_ERROR_WOULD_BLOCK ; 00119 break; 00120 } 00121 } 00122 } 00123 00124 _lock.unlock(); 00125 return ret; 00126 } 00127 00128 void UDPSocket::event() 00129 { 00130 _event_flag.set(READ_FLAG|WRITE_FLAG); 00131 00132 _pending += 1; 00133 if (_callback && _pending == 1) { 00134 _callback(); 00135 } 00136 }
Generated on Tue Jul 12 2022 20:03:25 by
