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.
Dependencies: nRF51_Vdd TextLCD BME280
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 15:15:47 by
