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