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
CellularNonIPSocket.cpp
00001 /* CellularNonIPSocket 00002 #include <CellularNonIPSocket.h> 00003 * Copyright (c) 2015 ARM Limited 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "platform/Callback.h" 00019 #include "CellularNonIPSocket.h" 00020 #include <stdio.h> 00021 00022 using namespace mbed; 00023 00024 CellularNonIPSocket::CellularNonIPSocket() 00025 : _timeout(osWaitForever), 00026 _readers(0), _writers(0), _pending(0), 00027 _cp_netif(NULL), 00028 _opened(false) 00029 {} 00030 00031 nsapi_error_t CellularNonIPSocket::open(CellularContext *cellular_context) 00032 { 00033 if (cellular_context == NULL) { 00034 return NSAPI_ERROR_PARAMETER ; 00035 } 00036 00037 return open(cellular_context->get_cp_netif()); 00038 } 00039 00040 CellularNonIPSocket::~CellularNonIPSocket() 00041 { 00042 close(); 00043 } 00044 00045 nsapi_error_t CellularNonIPSocket::open(ControlPlane_netif *cp_netif) 00046 { 00047 _lock.lock(); 00048 00049 if (_cp_netif != NULL || cp_netif == NULL) { 00050 _lock.unlock(); 00051 return NSAPI_ERROR_PARAMETER ; 00052 } 00053 _cp_netif = cp_netif; 00054 00055 _event = callback(this, &CellularNonIPSocket::event); 00056 _cp_netif->attach(Callback<void()>::thunk, &_event); 00057 _opened = true; 00058 00059 _lock.unlock(); 00060 return NSAPI_ERROR_OK ; 00061 } 00062 00063 nsapi_error_t CellularNonIPSocket::close() 00064 { 00065 _lock.lock(); 00066 00067 nsapi_error_t ret = NSAPI_ERROR_OK ; 00068 if (!_opened) { 00069 return NSAPI_ERROR_NO_SOCKET ; 00070 } 00071 00072 // Just in case - tell the stack not to callback any more, then remove this socket. 00073 _cp_netif->attach(0, 0); 00074 _opened = false; 00075 _cp_netif = 0; // Invalidate the cp_netif pointer - otherwise open() fails. 00076 00077 // Wakeup anything in a blocking operation 00078 // on this socket 00079 event(); 00080 00081 // Wait until all readers and writers are gone 00082 while (_readers || _writers) { 00083 _lock.unlock(); 00084 _event_flag.wait_any(FINISHED_FLAG, osWaitForever); 00085 _lock.lock(); 00086 } 00087 00088 _lock.unlock(); 00089 00090 return ret; 00091 } 00092 00093 nsapi_size_or_error_t CellularNonIPSocket::send(const void *data, nsapi_size_t size) 00094 { 00095 _lock.lock(); 00096 nsapi_size_or_error_t ret; 00097 00098 _writers++; 00099 00100 while (true) { 00101 if (!_opened) { 00102 ret = NSAPI_ERROR_NO_SOCKET ; 00103 break; 00104 } 00105 00106 _pending = 0; 00107 nsapi_size_or_error_t sent = _cp_netif->send(data, size); 00108 if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) { 00109 ret = sent; 00110 break; 00111 } else { 00112 uint32_t flag; 00113 00114 // Release lock before blocking so other threads 00115 // accessing this object aren't blocked 00116 _lock.unlock(); 00117 flag = _event_flag.wait_any(WRITE_FLAG, _timeout); 00118 _lock.lock(); 00119 00120 if (flag & osFlagsError) { 00121 // Timeout break 00122 ret = NSAPI_ERROR_WOULD_BLOCK ; 00123 break; 00124 } 00125 } 00126 } 00127 00128 _writers--; 00129 if (!_opened || !_writers) { 00130 _event_flag.set(FINISHED_FLAG); 00131 } 00132 _lock.unlock(); 00133 return ret; 00134 } 00135 00136 nsapi_size_or_error_t CellularNonIPSocket::recv(void *buffer, nsapi_size_t size) 00137 { 00138 _lock.lock(); 00139 nsapi_size_or_error_t ret; 00140 00141 _readers++; 00142 00143 while (true) { 00144 if (!_opened) { 00145 ret = NSAPI_ERROR_NO_SOCKET ; 00146 break; 00147 } 00148 00149 _pending = 0; 00150 nsapi_size_or_error_t recv = _cp_netif->recv(buffer, size); 00151 00152 // Non-blocking sockets always return. Blocking only returns when success or errors other than WOULD_BLOCK 00153 if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) { 00154 ret = recv; 00155 break; 00156 } else { 00157 uint32_t flag; 00158 00159 // Release lock before blocking so other threads 00160 // accessing this object aren't blocked 00161 _lock.unlock(); 00162 flag = _event_flag.wait_any(READ_FLAG, _timeout); 00163 _lock.lock(); 00164 00165 if (flag & osFlagsError) { 00166 // Timeout break 00167 ret = NSAPI_ERROR_WOULD_BLOCK ; 00168 break; 00169 } 00170 } 00171 } 00172 00173 _readers--; 00174 if (!_opened || !_readers) { 00175 _event_flag.set(FINISHED_FLAG); 00176 } 00177 00178 _lock.unlock(); 00179 return ret; 00180 } 00181 00182 void CellularNonIPSocket::set_blocking (bool blocking) 00183 { 00184 set_timeout (blocking ? -1 : 0); 00185 } 00186 00187 void CellularNonIPSocket::set_timeout (int timeout) 00188 { 00189 _lock.lock(); 00190 00191 if (timeout >= 0) { 00192 _timeout = (uint32_t)timeout; 00193 } else { 00194 _timeout = osWaitForever; 00195 } 00196 00197 _lock.unlock(); 00198 } 00199 00200 void CellularNonIPSocket::event() 00201 { 00202 _event_flag.set(READ_FLAG | WRITE_FLAG); 00203 00204 _pending += 1; 00205 if (_callback && _pending == 1) { 00206 _callback(); 00207 } 00208 } 00209 00210 void CellularNonIPSocket::sigio (Callback<void()> callback) 00211 { 00212 _lock.lock(); 00213 _callback = callback; 00214 _lock.unlock(); 00215 } 00216 00217 nsapi_error_t CellularNonIPSocket::connect(const SocketAddress &address) 00218 { 00219 return NSAPI_ERROR_UNSUPPORTED ; 00220 } 00221 00222 Socket *CellularNonIPSocket::accept(nsapi_error_t *error) 00223 { 00224 if (error) { 00225 *error = NSAPI_ERROR_UNSUPPORTED ; 00226 } 00227 return NULL; 00228 } 00229 00230 nsapi_error_t CellularNonIPSocket::listen(int backlog) 00231 { 00232 return NSAPI_ERROR_UNSUPPORTED ; 00233 } 00234 00235 nsapi_size_or_error_t CellularNonIPSocket::sendto(const SocketAddress &address, 00236 const void *data, nsapi_size_t size) 00237 { 00238 return NSAPI_ERROR_UNSUPPORTED ; 00239 } 00240 nsapi_size_or_error_t CellularNonIPSocket::recvfrom(SocketAddress *address, 00241 void *data, nsapi_size_t size) 00242 { 00243 return NSAPI_ERROR_UNSUPPORTED ; 00244 } 00245 00246 nsapi_error_t CellularNonIPSocket::setsockopt(int level, int optname, const void *optval, unsigned optlen) 00247 { 00248 return NSAPI_ERROR_UNSUPPORTED ; 00249 } 00250 00251 nsapi_error_t CellularNonIPSocket::getsockopt(int level, int optname, void *optval, unsigned *optlen) 00252 { 00253 return NSAPI_ERROR_UNSUPPORTED ; 00254 } 00255 00256 nsapi_error_t CellularNonIPSocket::getpeername(SocketAddress *address) 00257 { 00258 return NSAPI_ERROR_UNSUPPORTED ; 00259 } 00260 00261 nsapi_error_t CellularNonIPSocket::bind(const SocketAddress &address) 00262 { 00263 return NSAPI_ERROR_UNSUPPORTED ; 00264 }
Generated on Tue Jul 12 2022 13:54:05 by
