Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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 Sun Jul 17 2022 08:25:32 by 1.7.2