mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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?

UserRevisionLine numberNew 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 }