mbed-os5 only for TYBLE16
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
features/netsocket/CellularNonIPSocket.cpp@1:9db0e321a9f4, 2019-12-31 (annotated)
- Committer:
- kenjiArai
- Date:
- Tue Dec 31 06:02:27 2019 +0000
- Revision:
- 1:9db0e321a9f4
- Parent:
- features/netsocket/cellular/CellularNonIPSocket.cpp@0:5b88d5760320
updated based on mbed-os5.15.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:5b88d5760320 | 1 | /* CellularNonIPSocket |
kenjiArai | 0:5b88d5760320 | 2 | #include <CellularNonIPSocket.h> |
kenjiArai | 0:5b88d5760320 | 3 | * Copyright (c) 2015 ARM Limited |
kenjiArai | 0:5b88d5760320 | 4 | * |
kenjiArai | 0:5b88d5760320 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
kenjiArai | 0:5b88d5760320 | 6 | * you may not use this file except in compliance with the License. |
kenjiArai | 0:5b88d5760320 | 7 | * You may obtain a copy of the License at |
kenjiArai | 0:5b88d5760320 | 8 | * |
kenjiArai | 0:5b88d5760320 | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
kenjiArai | 0:5b88d5760320 | 10 | * |
kenjiArai | 0:5b88d5760320 | 11 | * Unless required by applicable law or agreed to in writing, software |
kenjiArai | 0:5b88d5760320 | 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
kenjiArai | 0:5b88d5760320 | 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
kenjiArai | 0:5b88d5760320 | 14 | * See the License for the specific language governing permissions and |
kenjiArai | 0:5b88d5760320 | 15 | * limitations under the License. |
kenjiArai | 0:5b88d5760320 | 16 | */ |
kenjiArai | 0:5b88d5760320 | 17 | |
kenjiArai | 0:5b88d5760320 | 18 | #include "platform/Callback.h" |
kenjiArai | 0:5b88d5760320 | 19 | #include "CellularNonIPSocket.h" |
kenjiArai | 0:5b88d5760320 | 20 | #include <stdio.h> |
kenjiArai | 0:5b88d5760320 | 21 | |
kenjiArai | 0:5b88d5760320 | 22 | using namespace mbed; |
kenjiArai | 0:5b88d5760320 | 23 | |
kenjiArai | 0:5b88d5760320 | 24 | CellularNonIPSocket::CellularNonIPSocket() |
kenjiArai | 0:5b88d5760320 | 25 | : _timeout(osWaitForever), |
kenjiArai | 0:5b88d5760320 | 26 | _readers(0), _writers(0), _pending(0), |
kenjiArai | 0:5b88d5760320 | 27 | _cp_netif(NULL), |
kenjiArai | 0:5b88d5760320 | 28 | _opened(false) |
kenjiArai | 0:5b88d5760320 | 29 | {} |
kenjiArai | 0:5b88d5760320 | 30 | |
kenjiArai | 0:5b88d5760320 | 31 | nsapi_error_t CellularNonIPSocket::open(CellularContext *cellular_context) |
kenjiArai | 0:5b88d5760320 | 32 | { |
kenjiArai | 0:5b88d5760320 | 33 | if (cellular_context == NULL) { |
kenjiArai | 0:5b88d5760320 | 34 | return NSAPI_ERROR_PARAMETER; |
kenjiArai | 0:5b88d5760320 | 35 | } |
kenjiArai | 0:5b88d5760320 | 36 | |
kenjiArai | 0:5b88d5760320 | 37 | return open(cellular_context->get_cp_netif()); |
kenjiArai | 0:5b88d5760320 | 38 | } |
kenjiArai | 0:5b88d5760320 | 39 | |
kenjiArai | 0:5b88d5760320 | 40 | CellularNonIPSocket::~CellularNonIPSocket() |
kenjiArai | 0:5b88d5760320 | 41 | { |
kenjiArai | 0:5b88d5760320 | 42 | close(); |
kenjiArai | 0:5b88d5760320 | 43 | } |
kenjiArai | 0:5b88d5760320 | 44 | |
kenjiArai | 0:5b88d5760320 | 45 | nsapi_error_t CellularNonIPSocket::open(ControlPlane_netif *cp_netif) |
kenjiArai | 0:5b88d5760320 | 46 | { |
kenjiArai | 0:5b88d5760320 | 47 | _lock.lock(); |
kenjiArai | 0:5b88d5760320 | 48 | |
kenjiArai | 0:5b88d5760320 | 49 | if (_cp_netif != NULL || cp_netif == NULL) { |
kenjiArai | 0:5b88d5760320 | 50 | _lock.unlock(); |
kenjiArai | 0:5b88d5760320 | 51 | return NSAPI_ERROR_PARAMETER; |
kenjiArai | 0:5b88d5760320 | 52 | } |
kenjiArai | 0:5b88d5760320 | 53 | _cp_netif = cp_netif; |
kenjiArai | 0:5b88d5760320 | 54 | |
kenjiArai | 0:5b88d5760320 | 55 | _event = callback(this, &CellularNonIPSocket::event); |
kenjiArai | 0:5b88d5760320 | 56 | _cp_netif->attach(Callback<void()>::thunk, &_event); |
kenjiArai | 0:5b88d5760320 | 57 | _opened = true; |
kenjiArai | 0:5b88d5760320 | 58 | |
kenjiArai | 0:5b88d5760320 | 59 | _lock.unlock(); |
kenjiArai | 0:5b88d5760320 | 60 | return NSAPI_ERROR_OK; |
kenjiArai | 0:5b88d5760320 | 61 | } |
kenjiArai | 0:5b88d5760320 | 62 | |
kenjiArai | 0:5b88d5760320 | 63 | nsapi_error_t CellularNonIPSocket::close() |
kenjiArai | 0:5b88d5760320 | 64 | { |
kenjiArai | 0:5b88d5760320 | 65 | _lock.lock(); |
kenjiArai | 0:5b88d5760320 | 66 | |
kenjiArai | 0:5b88d5760320 | 67 | nsapi_error_t ret = NSAPI_ERROR_OK; |
kenjiArai | 0:5b88d5760320 | 68 | if (!_opened) { |
kenjiArai | 0:5b88d5760320 | 69 | return NSAPI_ERROR_NO_SOCKET; |
kenjiArai | 0:5b88d5760320 | 70 | } |
kenjiArai | 0:5b88d5760320 | 71 | |
kenjiArai | 0:5b88d5760320 | 72 | // Just in case - tell the stack not to callback any more, then remove this socket. |
kenjiArai | 0:5b88d5760320 | 73 | _cp_netif->attach(0, 0); |
kenjiArai | 0:5b88d5760320 | 74 | _opened = false; |
kenjiArai | 0:5b88d5760320 | 75 | _cp_netif = 0; // Invalidate the cp_netif pointer - otherwise open() fails. |
kenjiArai | 0:5b88d5760320 | 76 | |
kenjiArai | 0:5b88d5760320 | 77 | // Wakeup anything in a blocking operation |
kenjiArai | 0:5b88d5760320 | 78 | // on this socket |
kenjiArai | 0:5b88d5760320 | 79 | event(); |
kenjiArai | 0:5b88d5760320 | 80 | |
kenjiArai | 0:5b88d5760320 | 81 | // Wait until all readers and writers are gone |
kenjiArai | 0:5b88d5760320 | 82 | while (_readers || _writers) { |
kenjiArai | 0:5b88d5760320 | 83 | _lock.unlock(); |
kenjiArai | 0:5b88d5760320 | 84 | _event_flag.wait_any(FINISHED_FLAG, osWaitForever); |
kenjiArai | 0:5b88d5760320 | 85 | _lock.lock(); |
kenjiArai | 0:5b88d5760320 | 86 | } |
kenjiArai | 0:5b88d5760320 | 87 | |
kenjiArai | 0:5b88d5760320 | 88 | _lock.unlock(); |
kenjiArai | 0:5b88d5760320 | 89 | |
kenjiArai | 0:5b88d5760320 | 90 | return ret; |
kenjiArai | 0:5b88d5760320 | 91 | } |
kenjiArai | 0:5b88d5760320 | 92 | |
kenjiArai | 0:5b88d5760320 | 93 | nsapi_size_or_error_t CellularNonIPSocket::send(const void *data, nsapi_size_t size) |
kenjiArai | 0:5b88d5760320 | 94 | { |
kenjiArai | 0:5b88d5760320 | 95 | _lock.lock(); |
kenjiArai | 0:5b88d5760320 | 96 | nsapi_size_or_error_t ret; |
kenjiArai | 0:5b88d5760320 | 97 | |
kenjiArai | 0:5b88d5760320 | 98 | _writers++; |
kenjiArai | 0:5b88d5760320 | 99 | |
kenjiArai | 0:5b88d5760320 | 100 | while (true) { |
kenjiArai | 0:5b88d5760320 | 101 | if (!_opened) { |
kenjiArai | 0:5b88d5760320 | 102 | ret = NSAPI_ERROR_NO_SOCKET; |
kenjiArai | 0:5b88d5760320 | 103 | break; |
kenjiArai | 0:5b88d5760320 | 104 | } |
kenjiArai | 0:5b88d5760320 | 105 | |
kenjiArai | 0:5b88d5760320 | 106 | _pending = 0; |
kenjiArai | 0:5b88d5760320 | 107 | nsapi_size_or_error_t sent = _cp_netif->send(data, size); |
kenjiArai | 0:5b88d5760320 | 108 | if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) { |
kenjiArai | 0:5b88d5760320 | 109 | ret = sent; |
kenjiArai | 0:5b88d5760320 | 110 | break; |
kenjiArai | 0:5b88d5760320 | 111 | } else { |
kenjiArai | 0:5b88d5760320 | 112 | uint32_t flag; |
kenjiArai | 0:5b88d5760320 | 113 | |
kenjiArai | 0:5b88d5760320 | 114 | // Release lock before blocking so other threads |
kenjiArai | 0:5b88d5760320 | 115 | // accessing this object aren't blocked |
kenjiArai | 0:5b88d5760320 | 116 | _lock.unlock(); |
kenjiArai | 0:5b88d5760320 | 117 | flag = _event_flag.wait_any(WRITE_FLAG, _timeout); |
kenjiArai | 0:5b88d5760320 | 118 | _lock.lock(); |
kenjiArai | 0:5b88d5760320 | 119 | |
kenjiArai | 0:5b88d5760320 | 120 | if (flag & osFlagsError) { |
kenjiArai | 0:5b88d5760320 | 121 | // Timeout break |
kenjiArai | 0:5b88d5760320 | 122 | ret = NSAPI_ERROR_WOULD_BLOCK; |
kenjiArai | 0:5b88d5760320 | 123 | break; |
kenjiArai | 0:5b88d5760320 | 124 | } |
kenjiArai | 0:5b88d5760320 | 125 | } |
kenjiArai | 0:5b88d5760320 | 126 | } |
kenjiArai | 0:5b88d5760320 | 127 | |
kenjiArai | 0:5b88d5760320 | 128 | _writers--; |
kenjiArai | 0:5b88d5760320 | 129 | if (!_opened || !_writers) { |
kenjiArai | 0:5b88d5760320 | 130 | _event_flag.set(FINISHED_FLAG); |
kenjiArai | 0:5b88d5760320 | 131 | } |
kenjiArai | 0:5b88d5760320 | 132 | _lock.unlock(); |
kenjiArai | 0:5b88d5760320 | 133 | return ret; |
kenjiArai | 0:5b88d5760320 | 134 | } |
kenjiArai | 0:5b88d5760320 | 135 | |
kenjiArai | 0:5b88d5760320 | 136 | nsapi_size_or_error_t CellularNonIPSocket::recv(void *buffer, nsapi_size_t size) |
kenjiArai | 0:5b88d5760320 | 137 | { |
kenjiArai | 0:5b88d5760320 | 138 | _lock.lock(); |
kenjiArai | 0:5b88d5760320 | 139 | nsapi_size_or_error_t ret; |
kenjiArai | 0:5b88d5760320 | 140 | |
kenjiArai | 0:5b88d5760320 | 141 | _readers++; |
kenjiArai | 0:5b88d5760320 | 142 | |
kenjiArai | 0:5b88d5760320 | 143 | while (true) { |
kenjiArai | 0:5b88d5760320 | 144 | if (!_opened) { |
kenjiArai | 0:5b88d5760320 | 145 | ret = NSAPI_ERROR_NO_SOCKET; |
kenjiArai | 0:5b88d5760320 | 146 | break; |
kenjiArai | 0:5b88d5760320 | 147 | } |
kenjiArai | 0:5b88d5760320 | 148 | |
kenjiArai | 0:5b88d5760320 | 149 | _pending = 0; |
kenjiArai | 0:5b88d5760320 | 150 | nsapi_size_or_error_t recv = _cp_netif->recv(buffer, size); |
kenjiArai | 0:5b88d5760320 | 151 | |
kenjiArai | 0:5b88d5760320 | 152 | // Non-blocking sockets always return. Blocking only returns when success or errors other than WOULD_BLOCK |
kenjiArai | 0:5b88d5760320 | 153 | if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) { |
kenjiArai | 0:5b88d5760320 | 154 | ret = recv; |
kenjiArai | 0:5b88d5760320 | 155 | break; |
kenjiArai | 0:5b88d5760320 | 156 | } else { |
kenjiArai | 0:5b88d5760320 | 157 | uint32_t flag; |
kenjiArai | 0:5b88d5760320 | 158 | |
kenjiArai | 0:5b88d5760320 | 159 | // Release lock before blocking so other threads |
kenjiArai | 0:5b88d5760320 | 160 | // accessing this object aren't blocked |
kenjiArai | 0:5b88d5760320 | 161 | _lock.unlock(); |
kenjiArai | 0:5b88d5760320 | 162 | flag = _event_flag.wait_any(READ_FLAG, _timeout); |
kenjiArai | 0:5b88d5760320 | 163 | _lock.lock(); |
kenjiArai | 0:5b88d5760320 | 164 | |
kenjiArai | 0:5b88d5760320 | 165 | if (flag & osFlagsError) { |
kenjiArai | 0:5b88d5760320 | 166 | // Timeout break |
kenjiArai | 0:5b88d5760320 | 167 | ret = NSAPI_ERROR_WOULD_BLOCK; |
kenjiArai | 0:5b88d5760320 | 168 | break; |
kenjiArai | 0:5b88d5760320 | 169 | } |
kenjiArai | 0:5b88d5760320 | 170 | } |
kenjiArai | 0:5b88d5760320 | 171 | } |
kenjiArai | 0:5b88d5760320 | 172 | |
kenjiArai | 0:5b88d5760320 | 173 | _readers--; |
kenjiArai | 0:5b88d5760320 | 174 | if (!_opened || !_readers) { |
kenjiArai | 0:5b88d5760320 | 175 | _event_flag.set(FINISHED_FLAG); |
kenjiArai | 0:5b88d5760320 | 176 | } |
kenjiArai | 0:5b88d5760320 | 177 | |
kenjiArai | 0:5b88d5760320 | 178 | _lock.unlock(); |
kenjiArai | 0:5b88d5760320 | 179 | return ret; |
kenjiArai | 0:5b88d5760320 | 180 | } |
kenjiArai | 0:5b88d5760320 | 181 | |
kenjiArai | 0:5b88d5760320 | 182 | void CellularNonIPSocket::set_blocking(bool blocking) |
kenjiArai | 0:5b88d5760320 | 183 | { |
kenjiArai | 0:5b88d5760320 | 184 | set_timeout(blocking ? -1 : 0); |
kenjiArai | 0:5b88d5760320 | 185 | } |
kenjiArai | 0:5b88d5760320 | 186 | |
kenjiArai | 0:5b88d5760320 | 187 | void CellularNonIPSocket::set_timeout(int timeout) |
kenjiArai | 0:5b88d5760320 | 188 | { |
kenjiArai | 0:5b88d5760320 | 189 | _lock.lock(); |
kenjiArai | 0:5b88d5760320 | 190 | |
kenjiArai | 0:5b88d5760320 | 191 | if (timeout >= 0) { |
kenjiArai | 0:5b88d5760320 | 192 | _timeout = (uint32_t)timeout; |
kenjiArai | 0:5b88d5760320 | 193 | } else { |
kenjiArai | 0:5b88d5760320 | 194 | _timeout = osWaitForever; |
kenjiArai | 0:5b88d5760320 | 195 | } |
kenjiArai | 0:5b88d5760320 | 196 | |
kenjiArai | 0:5b88d5760320 | 197 | _lock.unlock(); |
kenjiArai | 0:5b88d5760320 | 198 | } |
kenjiArai | 0:5b88d5760320 | 199 | |
kenjiArai | 0:5b88d5760320 | 200 | void CellularNonIPSocket::event() |
kenjiArai | 0:5b88d5760320 | 201 | { |
kenjiArai | 0:5b88d5760320 | 202 | _event_flag.set(READ_FLAG | WRITE_FLAG); |
kenjiArai | 0:5b88d5760320 | 203 | |
kenjiArai | 0:5b88d5760320 | 204 | _pending += 1; |
kenjiArai | 0:5b88d5760320 | 205 | if (_callback && _pending == 1) { |
kenjiArai | 0:5b88d5760320 | 206 | _callback(); |
kenjiArai | 0:5b88d5760320 | 207 | } |
kenjiArai | 0:5b88d5760320 | 208 | } |
kenjiArai | 0:5b88d5760320 | 209 | |
kenjiArai | 0:5b88d5760320 | 210 | void CellularNonIPSocket::sigio(Callback<void()> callback) |
kenjiArai | 0:5b88d5760320 | 211 | { |
kenjiArai | 0:5b88d5760320 | 212 | _lock.lock(); |
kenjiArai | 0:5b88d5760320 | 213 | _callback = callback; |
kenjiArai | 0:5b88d5760320 | 214 | _lock.unlock(); |
kenjiArai | 0:5b88d5760320 | 215 | } |
kenjiArai | 0:5b88d5760320 | 216 | |
kenjiArai | 0:5b88d5760320 | 217 | nsapi_error_t CellularNonIPSocket::connect(const SocketAddress &address) |
kenjiArai | 0:5b88d5760320 | 218 | { |
kenjiArai | 0:5b88d5760320 | 219 | return NSAPI_ERROR_UNSUPPORTED; |
kenjiArai | 0:5b88d5760320 | 220 | } |
kenjiArai | 0:5b88d5760320 | 221 | |
kenjiArai | 0:5b88d5760320 | 222 | Socket *CellularNonIPSocket::accept(nsapi_error_t *error) |
kenjiArai | 0:5b88d5760320 | 223 | { |
kenjiArai | 0:5b88d5760320 | 224 | if (error) { |
kenjiArai | 0:5b88d5760320 | 225 | *error = NSAPI_ERROR_UNSUPPORTED; |
kenjiArai | 0:5b88d5760320 | 226 | } |
kenjiArai | 0:5b88d5760320 | 227 | return NULL; |
kenjiArai | 0:5b88d5760320 | 228 | } |
kenjiArai | 0:5b88d5760320 | 229 | |
kenjiArai | 0:5b88d5760320 | 230 | nsapi_error_t CellularNonIPSocket::listen(int backlog) |
kenjiArai | 0:5b88d5760320 | 231 | { |
kenjiArai | 0:5b88d5760320 | 232 | return NSAPI_ERROR_UNSUPPORTED; |
kenjiArai | 0:5b88d5760320 | 233 | } |
kenjiArai | 0:5b88d5760320 | 234 | |
kenjiArai | 0:5b88d5760320 | 235 | nsapi_size_or_error_t CellularNonIPSocket::sendto(const SocketAddress &address, |
kenjiArai | 0:5b88d5760320 | 236 | const void *data, nsapi_size_t size) |
kenjiArai | 0:5b88d5760320 | 237 | { |
kenjiArai | 0:5b88d5760320 | 238 | return NSAPI_ERROR_UNSUPPORTED; |
kenjiArai | 0:5b88d5760320 | 239 | } |
kenjiArai | 0:5b88d5760320 | 240 | nsapi_size_or_error_t CellularNonIPSocket::recvfrom(SocketAddress *address, |
kenjiArai | 0:5b88d5760320 | 241 | void *data, nsapi_size_t size) |
kenjiArai | 0:5b88d5760320 | 242 | { |
kenjiArai | 0:5b88d5760320 | 243 | return NSAPI_ERROR_UNSUPPORTED; |
kenjiArai | 0:5b88d5760320 | 244 | } |
kenjiArai | 0:5b88d5760320 | 245 | |
kenjiArai | 0:5b88d5760320 | 246 | nsapi_error_t CellularNonIPSocket::setsockopt(int level, int optname, const void *optval, unsigned optlen) |
kenjiArai | 0:5b88d5760320 | 247 | { |
kenjiArai | 0:5b88d5760320 | 248 | return NSAPI_ERROR_UNSUPPORTED; |
kenjiArai | 0:5b88d5760320 | 249 | } |
kenjiArai | 0:5b88d5760320 | 250 | |
kenjiArai | 0:5b88d5760320 | 251 | nsapi_error_t CellularNonIPSocket::getsockopt(int level, int optname, void *optval, unsigned *optlen) |
kenjiArai | 0:5b88d5760320 | 252 | { |
kenjiArai | 0:5b88d5760320 | 253 | return NSAPI_ERROR_UNSUPPORTED; |
kenjiArai | 0:5b88d5760320 | 254 | } |
kenjiArai | 0:5b88d5760320 | 255 | |
kenjiArai | 0:5b88d5760320 | 256 | nsapi_error_t CellularNonIPSocket::getpeername(SocketAddress *address) |
kenjiArai | 0:5b88d5760320 | 257 | { |
kenjiArai | 0:5b88d5760320 | 258 | return NSAPI_ERROR_UNSUPPORTED; |
kenjiArai | 0:5b88d5760320 | 259 | } |
kenjiArai | 0:5b88d5760320 | 260 | |
kenjiArai | 0:5b88d5760320 | 261 | nsapi_error_t CellularNonIPSocket::bind(const SocketAddress &address) |
kenjiArai | 0:5b88d5760320 | 262 | { |
kenjiArai | 0:5b88d5760320 | 263 | return NSAPI_ERROR_UNSUPPORTED; |
kenjiArai | 0:5b88d5760320 | 264 | } |