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