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.
InternetSocket.cpp
00001 /* InternetSocket 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 "InternetSocket.h" 00018 #include "platform/Callback.h" 00019 00020 using namespace mbed; 00021 00022 InternetSocket::InternetSocket() 00023 : _stack(0), _socket(0), _timeout(osWaitForever), 00024 _readers(0), _writers(0), _pending(0), 00025 _factory_allocated(false) 00026 { 00027 } 00028 00029 InternetSocket::~InternetSocket() 00030 { 00031 close(); 00032 } 00033 00034 nsapi_error_t InternetSocket::open(NetworkStack *stack) 00035 { 00036 _lock.lock(); 00037 00038 if (_stack != NULL || stack == NULL) { 00039 _lock.unlock(); 00040 return NSAPI_ERROR_PARAMETER ; 00041 } 00042 _stack = stack; 00043 00044 nsapi_socket_t socket; 00045 nsapi_error_t err = _stack->socket_open(&socket, get_proto()); 00046 if (err) { 00047 _lock.unlock(); 00048 return err; 00049 } 00050 00051 _socket = socket; 00052 _event = callback(this, &InternetSocket::event); 00053 _stack->socket_attach(_socket, Callback<void()>::thunk, &_event); 00054 00055 _lock.unlock(); 00056 return NSAPI_ERROR_OK ; 00057 } 00058 00059 nsapi_error_t InternetSocket::close() 00060 { 00061 _lock.lock(); 00062 00063 nsapi_error_t ret = NSAPI_ERROR_OK ; 00064 if (!_socket) { 00065 _lock.unlock(); 00066 return NSAPI_ERROR_NO_SOCKET ; 00067 } 00068 00069 // Just in case - tell the stack not to callback any more, then remove this socket. 00070 _stack->socket_attach(_socket, 0, 0); 00071 nsapi_socket_t socket = _socket; 00072 _socket = 0; 00073 ret = _stack->socket_close(socket); 00074 _stack = 0; // Invalidate the stack pointer - otherwise open() fails. 00075 00076 // Wakeup anything in a blocking operation 00077 // on this socket 00078 event(); 00079 00080 // Wait until all readers and writers are gone 00081 while (_readers || _writers) { 00082 _lock.unlock(); 00083 _event_flag.wait_any(FINISHED_FLAG, osWaitForever); 00084 _lock.lock(); 00085 } 00086 00087 _lock.unlock(); 00088 00089 // When allocated by accept() call, will destroy itself on close(); 00090 if (_factory_allocated) { 00091 delete this; 00092 } 00093 return ret; 00094 } 00095 00096 int InternetSocket::modify_multicast_group(const SocketAddress &address, nsapi_socket_option_t socketopt) 00097 { 00098 nsapi_ip_mreq_t mreq; 00099 00100 // Set up group address 00101 mreq.imr_multiaddr = address.get_addr(); 00102 mreq.imr_interface = nsapi_addr_t(); // Default address, NSAPI_UNSPEC 00103 00104 return this->setsockopt (NSAPI_SOCKET , socketopt, &mreq, sizeof(mreq)); 00105 } 00106 00107 int InternetSocket::join_multicast_group(const SocketAddress &address) 00108 { 00109 return modify_multicast_group(address, NSAPI_ADD_MEMBERSHIP ); 00110 } 00111 00112 int InternetSocket::leave_multicast_group(const SocketAddress &address) 00113 { 00114 return modify_multicast_group(address, NSAPI_DROP_MEMBERSHIP ); 00115 } 00116 00117 00118 nsapi_error_t InternetSocket::bind(uint16_t port) 00119 { 00120 // Underlying bind is thread safe 00121 SocketAddress addr(0, port); 00122 return bind(addr); 00123 } 00124 00125 nsapi_error_t InternetSocket::bind(const char *address, uint16_t port) 00126 { 00127 // Underlying bind is thread safe 00128 SocketAddress addr(address, port); 00129 return bind(addr); 00130 } 00131 00132 nsapi_error_t InternetSocket::bind(const SocketAddress &address) 00133 { 00134 _lock.lock(); 00135 nsapi_error_t ret; 00136 00137 if (!_socket) { 00138 ret = NSAPI_ERROR_NO_SOCKET ; 00139 } else { 00140 ret = _stack->socket_bind(_socket, address); 00141 } 00142 00143 _lock.unlock(); 00144 return ret; 00145 } 00146 00147 void InternetSocket::set_blocking (bool blocking) 00148 { 00149 // InternetSocket::set_timeout is thread safe 00150 set_timeout (blocking ? -1 : 0); 00151 } 00152 00153 void InternetSocket::set_timeout (int timeout) 00154 { 00155 _lock.lock(); 00156 00157 if (timeout >= 0) { 00158 _timeout = (uint32_t)timeout; 00159 } else { 00160 _timeout = osWaitForever; 00161 } 00162 00163 _lock.unlock(); 00164 } 00165 00166 nsapi_error_t InternetSocket::setsockopt (int level, int optname, const void *optval, unsigned optlen) 00167 { 00168 _lock.lock(); 00169 nsapi_error_t ret; 00170 00171 if (!_socket) { 00172 ret = NSAPI_ERROR_NO_SOCKET ; 00173 } else { 00174 ret = _stack->setsockopt(_socket, level, optname, optval, optlen); 00175 } 00176 00177 _lock.unlock(); 00178 return ret; 00179 } 00180 00181 nsapi_error_t InternetSocket::getsockopt (int level, int optname, void *optval, unsigned *optlen) 00182 { 00183 _lock.lock(); 00184 nsapi_error_t ret; 00185 00186 if (!_socket) { 00187 ret = NSAPI_ERROR_NO_SOCKET ; 00188 } else { 00189 ret = _stack->getsockopt(_socket, level, optname, optval, optlen); 00190 } 00191 00192 _lock.unlock(); 00193 return ret; 00194 00195 } 00196 void InternetSocket::event() 00197 { 00198 _event_flag.set(READ_FLAG | WRITE_FLAG); 00199 00200 _pending += 1; 00201 if (_callback && _pending == 1) { 00202 _callback(); 00203 } 00204 } 00205 00206 void InternetSocket::sigio (Callback<void()> callback) 00207 { 00208 _lock.lock(); 00209 _callback = callback; 00210 _lock.unlock(); 00211 } 00212 00213 void InternetSocket::attach(Callback<void()> callback) 00214 { 00215 sigio (callback); 00216 }
Generated on Tue Jul 12 2022 20:52:44 by
1.7.2