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