test

Dependents:   mbed-os-example-blinky-1stDevDemo

Committer:
karen801
Date:
Wed May 23 14:37:10 2018 +0000
Revision:
0:79ce2b184a43
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
karen801 0:79ce2b184a43 1 /* mbed Microcontroller Library
karen801 0:79ce2b184a43 2 * Copyright (c) 20015 ARM Limited
karen801 0:79ce2b184a43 3 *
karen801 0:79ce2b184a43 4 * Licensed under the Apache License, Version 2.0 (the "License");
karen801 0:79ce2b184a43 5 * you may not use this file except in compliance with the License.
karen801 0:79ce2b184a43 6 * You may obtain a copy of the License at
karen801 0:79ce2b184a43 7 *
karen801 0:79ce2b184a43 8 * http://www.apache.org/licenses/LICENSE-2.0
karen801 0:79ce2b184a43 9 *
karen801 0:79ce2b184a43 10 * Unless required by applicable law or agreed to in writing, software
karen801 0:79ce2b184a43 11 * distributed under the License is distributed on an "AS IS" BASIS,
karen801 0:79ce2b184a43 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
karen801 0:79ce2b184a43 13 * See the License for the specific language governing permissions and
karen801 0:79ce2b184a43 14 * limitations under the License.
karen801 0:79ce2b184a43 15 */
karen801 0:79ce2b184a43 16
karen801 0:79ce2b184a43 17 /**
karen801 0:79ce2b184a43 18 ******************************************************************************
karen801 0:79ce2b184a43 19 * @file SpwfSAInterface.cpp
karen801 0:79ce2b184a43 20 * @author STMicroelectronics
karen801 0:79ce2b184a43 21 * @brief Implementation of the NetworkStack for the SPWF Device
karen801 0:79ce2b184a43 22 ******************************************************************************
karen801 0:79ce2b184a43 23 * @copy
karen801 0:79ce2b184a43 24 *
karen801 0:79ce2b184a43 25 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
karen801 0:79ce2b184a43 26 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
karen801 0:79ce2b184a43 27 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
karen801 0:79ce2b184a43 28 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
karen801 0:79ce2b184a43 29 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
karen801 0:79ce2b184a43 30 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
karen801 0:79ce2b184a43 31 *
karen801 0:79ce2b184a43 32 * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
karen801 0:79ce2b184a43 33 ******************************************************************************
karen801 0:79ce2b184a43 34 */
karen801 0:79ce2b184a43 35
karen801 0:79ce2b184a43 36 #include "SpwfSAInterface.h"
karen801 0:79ce2b184a43 37 #include "mbed_debug.h"
karen801 0:79ce2b184a43 38 #include "BlockExecuter.h"
karen801 0:79ce2b184a43 39
karen801 0:79ce2b184a43 40 #if MBED_CONF_RTOS_PRESENT
karen801 0:79ce2b184a43 41 static Mutex _spwf_mutex; // assuming a recursive mutex
karen801 0:79ce2b184a43 42 static void _spwf_lock() {
karen801 0:79ce2b184a43 43 (void)(_spwf_mutex.lock());
karen801 0:79ce2b184a43 44 }
karen801 0:79ce2b184a43 45 static Callback<void()> _callback_spwf_lock(&_spwf_lock);
karen801 0:79ce2b184a43 46
karen801 0:79ce2b184a43 47 static void _spwf_unlock() {
karen801 0:79ce2b184a43 48 (void)(_spwf_mutex.unlock());
karen801 0:79ce2b184a43 49 }
karen801 0:79ce2b184a43 50 static Callback<void()> _callback_spwf_unlock(&_spwf_unlock);
karen801 0:79ce2b184a43 51
karen801 0:79ce2b184a43 52 #define SYNC_HANDLER \
karen801 0:79ce2b184a43 53 BlockExecuter sync_handler(_callback_spwf_unlock, _callback_spwf_lock)
karen801 0:79ce2b184a43 54 #else
karen801 0:79ce2b184a43 55 #define SYNC_HANDLER
karen801 0:79ce2b184a43 56 #endif
karen801 0:79ce2b184a43 57
karen801 0:79ce2b184a43 58
karen801 0:79ce2b184a43 59 SpwfSAInterface::SpwfSAInterface(PinName tx, PinName rx,
karen801 0:79ce2b184a43 60 PinName rts, PinName cts, bool debug,
karen801 0:79ce2b184a43 61 PinName wakeup, PinName reset)
karen801 0:79ce2b184a43 62 : _spwf(tx, rx, rts, cts, *this, debug, wakeup, reset),
karen801 0:79ce2b184a43 63 _dbg_on(debug)
karen801 0:79ce2b184a43 64 {
karen801 0:79ce2b184a43 65 inner_constructor();
karen801 0:79ce2b184a43 66 reset_credentials();
karen801 0:79ce2b184a43 67 }
karen801 0:79ce2b184a43 68
karen801 0:79ce2b184a43 69 nsapi_error_t SpwfSAInterface::init(void)
karen801 0:79ce2b184a43 70 {
karen801 0:79ce2b184a43 71 _spwf.setTimeout(SPWF_INIT_TIMEOUT);
karen801 0:79ce2b184a43 72
karen801 0:79ce2b184a43 73 if(_spwf.startup(0)) {
karen801 0:79ce2b184a43 74 return NSAPI_ERROR_OK;
karen801 0:79ce2b184a43 75 }
karen801 0:79ce2b184a43 76 else return NSAPI_ERROR_DEVICE_ERROR;
karen801 0:79ce2b184a43 77 }
karen801 0:79ce2b184a43 78
karen801 0:79ce2b184a43 79 nsapi_error_t SpwfSAInterface::connect(void)
karen801 0:79ce2b184a43 80 {
karen801 0:79ce2b184a43 81 int mode;
karen801 0:79ce2b184a43 82 char *pass_phrase = ap_pass;
karen801 0:79ce2b184a43 83 SYNC_HANDLER;
karen801 0:79ce2b184a43 84
karen801 0:79ce2b184a43 85 // check for valid SSID
karen801 0:79ce2b184a43 86 if(ap_ssid[0] == '\0') {
karen801 0:79ce2b184a43 87 return NSAPI_ERROR_PARAMETER;
karen801 0:79ce2b184a43 88 }
karen801 0:79ce2b184a43 89
karen801 0:79ce2b184a43 90 switch(ap_sec)
karen801 0:79ce2b184a43 91 {
karen801 0:79ce2b184a43 92 case NSAPI_SECURITY_NONE:
karen801 0:79ce2b184a43 93 mode = 0;
karen801 0:79ce2b184a43 94 pass_phrase = NULL;
karen801 0:79ce2b184a43 95 break;
karen801 0:79ce2b184a43 96 case NSAPI_SECURITY_WEP:
karen801 0:79ce2b184a43 97 mode = 1;
karen801 0:79ce2b184a43 98 break;
karen801 0:79ce2b184a43 99 case NSAPI_SECURITY_WPA:
karen801 0:79ce2b184a43 100 case NSAPI_SECURITY_WPA2:
karen801 0:79ce2b184a43 101 mode = 2;
karen801 0:79ce2b184a43 102 break;
karen801 0:79ce2b184a43 103 default:
karen801 0:79ce2b184a43 104 mode = 2;
karen801 0:79ce2b184a43 105 break;
karen801 0:79ce2b184a43 106 }
karen801 0:79ce2b184a43 107
karen801 0:79ce2b184a43 108 // First: disconnect
karen801 0:79ce2b184a43 109 if(_connected_to_network) {
karen801 0:79ce2b184a43 110 if(!disconnect()) {
karen801 0:79ce2b184a43 111 return NSAPI_ERROR_DEVICE_ERROR;
karen801 0:79ce2b184a43 112 }
karen801 0:79ce2b184a43 113 }
karen801 0:79ce2b184a43 114
karen801 0:79ce2b184a43 115 //initialize the device before connecting
karen801 0:79ce2b184a43 116 if(!_isInitialized)
karen801 0:79ce2b184a43 117 {
karen801 0:79ce2b184a43 118 if(init() != NSAPI_ERROR_OK) return NSAPI_ERROR_DEVICE_ERROR;
karen801 0:79ce2b184a43 119 _isInitialized=true;
karen801 0:79ce2b184a43 120 }
karen801 0:79ce2b184a43 121
karen801 0:79ce2b184a43 122 // Then: (re-)connect
karen801 0:79ce2b184a43 123 _spwf.setTimeout(SPWF_CONNECT_TIMEOUT);
karen801 0:79ce2b184a43 124
karen801 0:79ce2b184a43 125 if (!_spwf.connect(ap_ssid, pass_phrase, mode)) {
karen801 0:79ce2b184a43 126 return NSAPI_ERROR_AUTH_FAILURE;
karen801 0:79ce2b184a43 127 }
karen801 0:79ce2b184a43 128
karen801 0:79ce2b184a43 129 if (!_spwf.getIPAddress()) {
karen801 0:79ce2b184a43 130 return NSAPI_ERROR_DHCP_FAILURE;
karen801 0:79ce2b184a43 131 }
karen801 0:79ce2b184a43 132
karen801 0:79ce2b184a43 133 _connected_to_network = true;
karen801 0:79ce2b184a43 134 return NSAPI_ERROR_OK;
karen801 0:79ce2b184a43 135 }
karen801 0:79ce2b184a43 136
karen801 0:79ce2b184a43 137 nsapi_error_t SpwfSAInterface::connect(const char *ssid, const char *pass, nsapi_security_t security,
karen801 0:79ce2b184a43 138 uint8_t channel)
karen801 0:79ce2b184a43 139 {
karen801 0:79ce2b184a43 140 nsapi_error_t ret;
karen801 0:79ce2b184a43 141 SYNC_HANDLER;
karen801 0:79ce2b184a43 142
karen801 0:79ce2b184a43 143 if (channel != 0) {
karen801 0:79ce2b184a43 144 return NSAPI_ERROR_UNSUPPORTED;
karen801 0:79ce2b184a43 145 }
karen801 0:79ce2b184a43 146
karen801 0:79ce2b184a43 147 ret = set_credentials(ssid, pass, security);
karen801 0:79ce2b184a43 148 if(ret != NSAPI_ERROR_OK) return ret;
karen801 0:79ce2b184a43 149
karen801 0:79ce2b184a43 150 return connect();
karen801 0:79ce2b184a43 151 }
karen801 0:79ce2b184a43 152
karen801 0:79ce2b184a43 153 nsapi_error_t SpwfSAInterface::disconnect(void)
karen801 0:79ce2b184a43 154 {
karen801 0:79ce2b184a43 155 SYNC_HANDLER;
karen801 0:79ce2b184a43 156
karen801 0:79ce2b184a43 157 _spwf.setTimeout(SPWF_DISCONNECT_TIMEOUT);
karen801 0:79ce2b184a43 158
karen801 0:79ce2b184a43 159 if (!_spwf.disconnect()) {
karen801 0:79ce2b184a43 160 return NSAPI_ERROR_DEVICE_ERROR;
karen801 0:79ce2b184a43 161 }
karen801 0:79ce2b184a43 162
karen801 0:79ce2b184a43 163 return NSAPI_ERROR_OK;
karen801 0:79ce2b184a43 164 }
karen801 0:79ce2b184a43 165
karen801 0:79ce2b184a43 166 const char *SpwfSAInterface::get_ip_address(void)
karen801 0:79ce2b184a43 167 {
karen801 0:79ce2b184a43 168 SYNC_HANDLER;
karen801 0:79ce2b184a43 169
karen801 0:79ce2b184a43 170 _spwf.setTimeout(SPWF_MISC_TIMEOUT);
karen801 0:79ce2b184a43 171 return _spwf.getIPAddress();
karen801 0:79ce2b184a43 172 }
karen801 0:79ce2b184a43 173
karen801 0:79ce2b184a43 174 const char *SpwfSAInterface::get_mac_address(void)
karen801 0:79ce2b184a43 175 {
karen801 0:79ce2b184a43 176 SYNC_HANDLER;
karen801 0:79ce2b184a43 177
karen801 0:79ce2b184a43 178 _spwf.setTimeout(SPWF_MISC_TIMEOUT);
karen801 0:79ce2b184a43 179 return _spwf.getMACAddress();
karen801 0:79ce2b184a43 180 }
karen801 0:79ce2b184a43 181
karen801 0:79ce2b184a43 182 const char *SpwfSAInterface::get_gateway(void)
karen801 0:79ce2b184a43 183 {
karen801 0:79ce2b184a43 184 SYNC_HANDLER;
karen801 0:79ce2b184a43 185
karen801 0:79ce2b184a43 186 if(!_connected_to_network) return NULL;
karen801 0:79ce2b184a43 187
karen801 0:79ce2b184a43 188 _spwf.setTimeout(SPWF_MISC_TIMEOUT);
karen801 0:79ce2b184a43 189 return _spwf.getGateway();
karen801 0:79ce2b184a43 190 }
karen801 0:79ce2b184a43 191
karen801 0:79ce2b184a43 192 const char *SpwfSAInterface::get_netmask(void)
karen801 0:79ce2b184a43 193 {
karen801 0:79ce2b184a43 194 SYNC_HANDLER;
karen801 0:79ce2b184a43 195
karen801 0:79ce2b184a43 196 if(!_connected_to_network) return NULL;
karen801 0:79ce2b184a43 197
karen801 0:79ce2b184a43 198 _spwf.setTimeout(SPWF_MISC_TIMEOUT);
karen801 0:79ce2b184a43 199 return _spwf.getNetmask();
karen801 0:79ce2b184a43 200 }
karen801 0:79ce2b184a43 201
karen801 0:79ce2b184a43 202 nsapi_error_t SpwfSAInterface::socket_open(void **handle, nsapi_protocol_t proto)
karen801 0:79ce2b184a43 203 {
karen801 0:79ce2b184a43 204 int internal_id;
karen801 0:79ce2b184a43 205 SYNC_HANDLER;
karen801 0:79ce2b184a43 206
karen801 0:79ce2b184a43 207 for (internal_id = 0; internal_id < SPWFSA_SOCKET_COUNT; internal_id++) {
karen801 0:79ce2b184a43 208 if(_ids[internal_id].internal_id == SPWFSA_SOCKET_COUNT) break;
karen801 0:79ce2b184a43 209 }
karen801 0:79ce2b184a43 210
karen801 0:79ce2b184a43 211 if(internal_id == SPWFSA_SOCKET_COUNT) {
karen801 0:79ce2b184a43 212 debug_if(_dbg_on, "NO Socket ID Error\r\n");
karen801 0:79ce2b184a43 213 return NSAPI_ERROR_NO_SOCKET;
karen801 0:79ce2b184a43 214 }
karen801 0:79ce2b184a43 215
karen801 0:79ce2b184a43 216 spwf_socket_t *socket = &_ids[internal_id];
karen801 0:79ce2b184a43 217 socket->internal_id = internal_id;
karen801 0:79ce2b184a43 218 socket->spwf_id = SPWFSA_SOCKET_COUNT;
karen801 0:79ce2b184a43 219 socket->server_gone = false;
karen801 0:79ce2b184a43 220 socket->no_more_data = false;
karen801 0:79ce2b184a43 221 socket->proto = proto;
karen801 0:79ce2b184a43 222 socket->addr = SocketAddress();
karen801 0:79ce2b184a43 223
karen801 0:79ce2b184a43 224 *handle = socket;
karen801 0:79ce2b184a43 225 return NSAPI_ERROR_OK;
karen801 0:79ce2b184a43 226 }
karen801 0:79ce2b184a43 227
karen801 0:79ce2b184a43 228 nsapi_error_t SpwfSAInterface::socket_connect(void *handle, const SocketAddress &addr)
karen801 0:79ce2b184a43 229 {
karen801 0:79ce2b184a43 230 spwf_socket_t *socket = (spwf_socket_t*)handle;
karen801 0:79ce2b184a43 231 SYNC_HANDLER;
karen801 0:79ce2b184a43 232
karen801 0:79ce2b184a43 233 MBED_ASSERT(((unsigned int)socket->internal_id) < ((unsigned int)SPWFSA_SOCKET_COUNT));
karen801 0:79ce2b184a43 234
karen801 0:79ce2b184a43 235 if(_socket_has_connected(socket->internal_id)) {
karen801 0:79ce2b184a43 236 return NSAPI_ERROR_IS_CONNECTED;
karen801 0:79ce2b184a43 237 }
karen801 0:79ce2b184a43 238
karen801 0:79ce2b184a43 239 _spwf.setTimeout(SPWF_OPEN_TIMEOUT);
karen801 0:79ce2b184a43 240
karen801 0:79ce2b184a43 241 const char *proto = (socket->proto == NSAPI_UDP) ? "u" : "t"; //"s" for secure socket?
karen801 0:79ce2b184a43 242
karen801 0:79ce2b184a43 243 if(addr.get_ip_version() != NSAPI_IPv4) { // IPv6 not supported (yet)
karen801 0:79ce2b184a43 244 return NSAPI_ERROR_UNSUPPORTED;
karen801 0:79ce2b184a43 245 }
karen801 0:79ce2b184a43 246
karen801 0:79ce2b184a43 247 {
karen801 0:79ce2b184a43 248 BlockExecuter netsock_wa_obj(Callback<void()>(&_spwf, &SPWFSAxx::_unblock_event_callback),
karen801 0:79ce2b184a43 249 Callback<void()>(&_spwf, &SPWFSAxx::_block_event_callback)); /* disable calling (external) callback in IRQ context */
karen801 0:79ce2b184a43 250
karen801 0:79ce2b184a43 251 /* block asynchronous indications */
karen801 0:79ce2b184a43 252 if(!_spwf._winds_off()) {
karen801 0:79ce2b184a43 253 return NSAPI_ERROR_DEVICE_ERROR;
karen801 0:79ce2b184a43 254 }
karen801 0:79ce2b184a43 255
karen801 0:79ce2b184a43 256 {
karen801 0:79ce2b184a43 257 BlockExecuter bh_handler(Callback<void()>(&_spwf, &SPWFSAxx::_execute_bottom_halves));
karen801 0:79ce2b184a43 258 {
karen801 0:79ce2b184a43 259 BlockExecuter winds_enabler(Callback<void()>(&_spwf, &SPWFSAxx::_winds_on));
karen801 0:79ce2b184a43 260
karen801 0:79ce2b184a43 261 if(!_spwf.open(proto, &socket->spwf_id, addr.get_ip_address(), addr.get_port())) {
karen801 0:79ce2b184a43 262 MBED_ASSERT(_spwf._call_event_callback_blocked == 1);
karen801 0:79ce2b184a43 263
karen801 0:79ce2b184a43 264 return NSAPI_ERROR_DEVICE_ERROR;
karen801 0:79ce2b184a43 265 }
karen801 0:79ce2b184a43 266
karen801 0:79ce2b184a43 267 /* check for the module to report a valid id */
karen801 0:79ce2b184a43 268 MBED_ASSERT(((unsigned int)socket->spwf_id) < ((unsigned int)SPWFSA_SOCKET_COUNT));
karen801 0:79ce2b184a43 269
karen801 0:79ce2b184a43 270 _internal_ids[socket->spwf_id] = socket->internal_id;
karen801 0:79ce2b184a43 271 socket->addr = addr;
karen801 0:79ce2b184a43 272
karen801 0:79ce2b184a43 273 MBED_ASSERT(_spwf._call_event_callback_blocked == 1);
karen801 0:79ce2b184a43 274
karen801 0:79ce2b184a43 275 return NSAPI_ERROR_OK;
karen801 0:79ce2b184a43 276 }
karen801 0:79ce2b184a43 277 }
karen801 0:79ce2b184a43 278 }
karen801 0:79ce2b184a43 279 }
karen801 0:79ce2b184a43 280
karen801 0:79ce2b184a43 281 nsapi_error_t SpwfSAInterface::socket_bind(void *handle, const SocketAddress &address)
karen801 0:79ce2b184a43 282 {
karen801 0:79ce2b184a43 283 return NSAPI_ERROR_UNSUPPORTED;
karen801 0:79ce2b184a43 284 }
karen801 0:79ce2b184a43 285
karen801 0:79ce2b184a43 286 nsapi_error_t SpwfSAInterface::socket_listen(void *handle, int backlog)
karen801 0:79ce2b184a43 287 {
karen801 0:79ce2b184a43 288 return NSAPI_ERROR_UNSUPPORTED;
karen801 0:79ce2b184a43 289 }
karen801 0:79ce2b184a43 290
karen801 0:79ce2b184a43 291 nsapi_error_t SpwfSAInterface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address)
karen801 0:79ce2b184a43 292 {
karen801 0:79ce2b184a43 293 return NSAPI_ERROR_UNSUPPORTED;
karen801 0:79ce2b184a43 294 }
karen801 0:79ce2b184a43 295
karen801 0:79ce2b184a43 296 nsapi_error_t SpwfSAInterface::socket_close(void *handle)
karen801 0:79ce2b184a43 297 {
karen801 0:79ce2b184a43 298 spwf_socket_t *socket = (spwf_socket_t*)handle;
karen801 0:79ce2b184a43 299 int internal_id = socket->internal_id;
karen801 0:79ce2b184a43 300 SYNC_HANDLER;
karen801 0:79ce2b184a43 301
karen801 0:79ce2b184a43 302 if(!_socket_is_open(internal_id)) return NSAPI_ERROR_NO_SOCKET;
karen801 0:79ce2b184a43 303
karen801 0:79ce2b184a43 304 if(_socket_has_connected(socket)) {
karen801 0:79ce2b184a43 305 _spwf.setTimeout(SPWF_CLOSE_TIMEOUT);
karen801 0:79ce2b184a43 306 if (!_spwf.close(socket->spwf_id)) {
karen801 0:79ce2b184a43 307 return NSAPI_ERROR_DEVICE_ERROR;
karen801 0:79ce2b184a43 308 }
karen801 0:79ce2b184a43 309 _internal_ids[socket->spwf_id] = SPWFSA_SOCKET_COUNT;
karen801 0:79ce2b184a43 310 }
karen801 0:79ce2b184a43 311
karen801 0:79ce2b184a43 312 _ids[internal_id].internal_id = SPWFSA_SOCKET_COUNT;
karen801 0:79ce2b184a43 313 _ids[internal_id].spwf_id = SPWFSA_SOCKET_COUNT;
karen801 0:79ce2b184a43 314
karen801 0:79ce2b184a43 315 return NSAPI_ERROR_OK;
karen801 0:79ce2b184a43 316 }
karen801 0:79ce2b184a43 317
karen801 0:79ce2b184a43 318 nsapi_size_or_error_t SpwfSAInterface::socket_send(void *handle, const void *data, unsigned size)
karen801 0:79ce2b184a43 319 {
karen801 0:79ce2b184a43 320 spwf_socket_t *socket = (spwf_socket_t*)handle;
karen801 0:79ce2b184a43 321 SYNC_HANDLER;
karen801 0:79ce2b184a43 322
karen801 0:79ce2b184a43 323 CHECK_NOT_CONNECTED_ERR();
karen801 0:79ce2b184a43 324
karen801 0:79ce2b184a43 325 _spwf.setTimeout(SPWF_SEND_TIMEOUT);
karen801 0:79ce2b184a43 326 return _spwf.send(socket->spwf_id, data, size, socket->internal_id);
karen801 0:79ce2b184a43 327 }
karen801 0:79ce2b184a43 328
karen801 0:79ce2b184a43 329 nsapi_size_or_error_t SpwfSAInterface::socket_recv(void *handle, void *data, unsigned size)
karen801 0:79ce2b184a43 330 {
karen801 0:79ce2b184a43 331 SYNC_HANDLER;
karen801 0:79ce2b184a43 332
karen801 0:79ce2b184a43 333 return _socket_recv(handle, data, size, false);
karen801 0:79ce2b184a43 334 }
karen801 0:79ce2b184a43 335
karen801 0:79ce2b184a43 336 nsapi_size_or_error_t SpwfSAInterface::_socket_recv(void *handle, void *data, unsigned size, bool datagram)
karen801 0:79ce2b184a43 337 {
karen801 0:79ce2b184a43 338 spwf_socket_t *socket = (spwf_socket_t*)handle;
karen801 0:79ce2b184a43 339
karen801 0:79ce2b184a43 340 CHECK_NOT_CONNECTED_ERR();
karen801 0:79ce2b184a43 341
karen801 0:79ce2b184a43 342 if(!_socket_has_connected(socket)) {
karen801 0:79ce2b184a43 343 return NSAPI_ERROR_WOULD_BLOCK;
karen801 0:79ce2b184a43 344 } else if(socket->no_more_data) {
karen801 0:79ce2b184a43 345 return 0;
karen801 0:79ce2b184a43 346 }
karen801 0:79ce2b184a43 347
karen801 0:79ce2b184a43 348 _spwf.setTimeout(SPWF_RECV_TIMEOUT);
karen801 0:79ce2b184a43 349
karen801 0:79ce2b184a43 350 int32_t recv = _spwf.recv(socket->spwf_id, (char*)data, (uint32_t)size, datagram);
karen801 0:79ce2b184a43 351
karen801 0:79ce2b184a43 352 MBED_ASSERT(!_spwf._is_event_callback_blocked());
karen801 0:79ce2b184a43 353 MBED_ASSERT((recv != 0) || (size == 0));
karen801 0:79ce2b184a43 354
karen801 0:79ce2b184a43 355 if (recv < 0) {
karen801 0:79ce2b184a43 356 if(!_socket_is_still_connected(socket)) {
karen801 0:79ce2b184a43 357 socket->no_more_data = true;
karen801 0:79ce2b184a43 358 return 0;
karen801 0:79ce2b184a43 359 }
karen801 0:79ce2b184a43 360
karen801 0:79ce2b184a43 361 return NSAPI_ERROR_WOULD_BLOCK;
karen801 0:79ce2b184a43 362 }
karen801 0:79ce2b184a43 363
karen801 0:79ce2b184a43 364 return recv;
karen801 0:79ce2b184a43 365 }
karen801 0:79ce2b184a43 366
karen801 0:79ce2b184a43 367 nsapi_size_or_error_t SpwfSAInterface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
karen801 0:79ce2b184a43 368 {
karen801 0:79ce2b184a43 369 spwf_socket_t *socket = (spwf_socket_t*)handle;
karen801 0:79ce2b184a43 370 SYNC_HANDLER;
karen801 0:79ce2b184a43 371
karen801 0:79ce2b184a43 372 CHECK_NOT_CONNECTED_ERR();
karen801 0:79ce2b184a43 373
karen801 0:79ce2b184a43 374 if ((_socket_has_connected(socket)) && (socket->addr != addr)) {
karen801 0:79ce2b184a43 375 _spwf.setTimeout(SPWF_CLOSE_TIMEOUT);
karen801 0:79ce2b184a43 376 if (!_spwf.close(socket->spwf_id)) {
karen801 0:79ce2b184a43 377 return NSAPI_ERROR_DEVICE_ERROR;
karen801 0:79ce2b184a43 378 }
karen801 0:79ce2b184a43 379 _internal_ids[socket->spwf_id] = SPWFSA_SOCKET_COUNT;
karen801 0:79ce2b184a43 380 socket->spwf_id = SPWFSA_SOCKET_COUNT;
karen801 0:79ce2b184a43 381 }
karen801 0:79ce2b184a43 382
karen801 0:79ce2b184a43 383 _spwf.setTimeout(SPWF_CONN_SND_TIMEOUT);
karen801 0:79ce2b184a43 384 if (!_socket_has_connected(socket)) {
karen801 0:79ce2b184a43 385 nsapi_error_t err = socket_connect(socket, addr);
karen801 0:79ce2b184a43 386 if (err < 0) {
karen801 0:79ce2b184a43 387 return err;
karen801 0:79ce2b184a43 388 }
karen801 0:79ce2b184a43 389 }
karen801 0:79ce2b184a43 390
karen801 0:79ce2b184a43 391 return socket_send(socket, data, size);
karen801 0:79ce2b184a43 392 }
karen801 0:79ce2b184a43 393
karen801 0:79ce2b184a43 394 nsapi_size_or_error_t SpwfSAInterface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
karen801 0:79ce2b184a43 395 {
karen801 0:79ce2b184a43 396 spwf_socket_t *socket = (spwf_socket_t*)handle;
karen801 0:79ce2b184a43 397 nsapi_error_t ret;
karen801 0:79ce2b184a43 398 SYNC_HANDLER;
karen801 0:79ce2b184a43 399
karen801 0:79ce2b184a43 400 ret = _socket_recv(socket, data, size, true);
karen801 0:79ce2b184a43 401 if (ret >= 0 && addr) {
karen801 0:79ce2b184a43 402 *addr = socket->addr;
karen801 0:79ce2b184a43 403 }
karen801 0:79ce2b184a43 404
karen801 0:79ce2b184a43 405 return ret;
karen801 0:79ce2b184a43 406 }
karen801 0:79ce2b184a43 407
karen801 0:79ce2b184a43 408 void SpwfSAInterface::socket_attach(void *handle, void (*callback)(void *), void *data)
karen801 0:79ce2b184a43 409 {
karen801 0:79ce2b184a43 410 spwf_socket_t *socket = (spwf_socket_t*)handle;
karen801 0:79ce2b184a43 411 SYNC_HANDLER;
karen801 0:79ce2b184a43 412
karen801 0:79ce2b184a43 413 if(!_socket_is_open(socket)) return; // might happen e.g. after module hard fault or voluntary disconnection
karen801 0:79ce2b184a43 414
karen801 0:79ce2b184a43 415 _cbs[socket->internal_id].callback = callback;
karen801 0:79ce2b184a43 416 _cbs[socket->internal_id].data = data;
karen801 0:79ce2b184a43 417 }
karen801 0:79ce2b184a43 418
karen801 0:79ce2b184a43 419 void SpwfSAInterface::event(void) {
karen801 0:79ce2b184a43 420 for (int internal_id = 0; internal_id < SPWFSA_SOCKET_COUNT; internal_id++) {
karen801 0:79ce2b184a43 421 if (_cbs[internal_id].callback && (_ids[internal_id].internal_id != SPWFSA_SOCKET_COUNT)) {
karen801 0:79ce2b184a43 422 _cbs[internal_id].callback(_cbs[internal_id].data);
karen801 0:79ce2b184a43 423 }
karen801 0:79ce2b184a43 424 }
karen801 0:79ce2b184a43 425 }
karen801 0:79ce2b184a43 426
karen801 0:79ce2b184a43 427 nsapi_error_t SpwfSAInterface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security)
karen801 0:79ce2b184a43 428 {
karen801 0:79ce2b184a43 429 SYNC_HANDLER;
karen801 0:79ce2b184a43 430
karen801 0:79ce2b184a43 431 if((ssid == NULL) || (strlen(ssid) == 0)) {
karen801 0:79ce2b184a43 432 return NSAPI_ERROR_PARAMETER;
karen801 0:79ce2b184a43 433 }
karen801 0:79ce2b184a43 434
karen801 0:79ce2b184a43 435 if((pass != NULL) && (strlen(pass) > 0)) {
karen801 0:79ce2b184a43 436 if(strlen(pass) < sizeof(ap_pass)) {
karen801 0:79ce2b184a43 437 if(security == NSAPI_SECURITY_NONE) {
karen801 0:79ce2b184a43 438 return NSAPI_ERROR_PARAMETER;
karen801 0:79ce2b184a43 439 }
karen801 0:79ce2b184a43 440 } else {
karen801 0:79ce2b184a43 441 return NSAPI_ERROR_PARAMETER;
karen801 0:79ce2b184a43 442 }
karen801 0:79ce2b184a43 443 } else if(security != NSAPI_SECURITY_NONE) {
karen801 0:79ce2b184a43 444 return NSAPI_ERROR_PARAMETER;
karen801 0:79ce2b184a43 445 }
karen801 0:79ce2b184a43 446
karen801 0:79ce2b184a43 447 reset_credentials();
karen801 0:79ce2b184a43 448
karen801 0:79ce2b184a43 449 ap_sec = security;
karen801 0:79ce2b184a43 450 strncpy(ap_ssid, ssid, sizeof(ap_ssid) - 1);
karen801 0:79ce2b184a43 451 strncpy(ap_pass, pass, sizeof(ap_pass) - 1);
karen801 0:79ce2b184a43 452
karen801 0:79ce2b184a43 453 return NSAPI_ERROR_OK;
karen801 0:79ce2b184a43 454 }
karen801 0:79ce2b184a43 455
karen801 0:79ce2b184a43 456 nsapi_error_t SpwfSAInterface::set_channel(uint8_t channel)
karen801 0:79ce2b184a43 457 {
karen801 0:79ce2b184a43 458 return NSAPI_ERROR_UNSUPPORTED;
karen801 0:79ce2b184a43 459 }
karen801 0:79ce2b184a43 460
karen801 0:79ce2b184a43 461 int8_t SpwfSAInterface::get_rssi(void)
karen801 0:79ce2b184a43 462 {
karen801 0:79ce2b184a43 463 SYNC_HANDLER;
karen801 0:79ce2b184a43 464
karen801 0:79ce2b184a43 465 if(!_connected_to_network) return 0;
karen801 0:79ce2b184a43 466
karen801 0:79ce2b184a43 467 _spwf.setTimeout(SPWF_MISC_TIMEOUT);
karen801 0:79ce2b184a43 468 return _spwf.getRssi();
karen801 0:79ce2b184a43 469 }
karen801 0:79ce2b184a43 470
karen801 0:79ce2b184a43 471 nsapi_size_or_error_t SpwfSAInterface::scan(WiFiAccessPoint *res, unsigned count)
karen801 0:79ce2b184a43 472 {
karen801 0:79ce2b184a43 473 SYNC_HANDLER;
karen801 0:79ce2b184a43 474
karen801 0:79ce2b184a43 475 nsapi_size_or_error_t ret;
karen801 0:79ce2b184a43 476
karen801 0:79ce2b184a43 477 //initialize the device before scanning
karen801 0:79ce2b184a43 478 if(!_isInitialized)
karen801 0:79ce2b184a43 479 {
karen801 0:79ce2b184a43 480 if(init() != NSAPI_ERROR_OK) return NSAPI_ERROR_DEVICE_ERROR;
karen801 0:79ce2b184a43 481 }
karen801 0:79ce2b184a43 482
karen801 0:79ce2b184a43 483 _spwf.setTimeout(SPWF_SCAN_TIMEOUT);
karen801 0:79ce2b184a43 484
karen801 0:79ce2b184a43 485 {
karen801 0:79ce2b184a43 486 BlockExecuter netsock_wa_obj(Callback<void()>(&_spwf, &SPWFSAxx::_unblock_event_callback),
karen801 0:79ce2b184a43 487 Callback<void()>(&_spwf, &SPWFSAxx::_block_event_callback)); /* disable calling (external) callback in IRQ context */
karen801 0:79ce2b184a43 488
karen801 0:79ce2b184a43 489 /* block asynchronous indications */
karen801 0:79ce2b184a43 490 if(!_spwf._winds_off()) {
karen801 0:79ce2b184a43 491 MBED_ASSERT(_spwf._call_event_callback_blocked == 1);
karen801 0:79ce2b184a43 492
karen801 0:79ce2b184a43 493 return NSAPI_ERROR_DEVICE_ERROR;
karen801 0:79ce2b184a43 494 }
karen801 0:79ce2b184a43 495
karen801 0:79ce2b184a43 496 ret = _spwf.scan(res, count);
karen801 0:79ce2b184a43 497
karen801 0:79ce2b184a43 498 /* unblock asynchronous indications */
karen801 0:79ce2b184a43 499 _spwf._winds_on();
karen801 0:79ce2b184a43 500 }
karen801 0:79ce2b184a43 501
karen801 0:79ce2b184a43 502 MBED_ASSERT(!_spwf._is_event_callback_blocked());
karen801 0:79ce2b184a43 503
karen801 0:79ce2b184a43 504 //de-initialize the device after scanning
karen801 0:79ce2b184a43 505 if(!_isInitialized)
karen801 0:79ce2b184a43 506 {
karen801 0:79ce2b184a43 507 nsapi_error_t err = disconnect();
karen801 0:79ce2b184a43 508 if(err != NSAPI_ERROR_OK) return err;
karen801 0:79ce2b184a43 509 }
karen801 0:79ce2b184a43 510
karen801 0:79ce2b184a43 511 return ret;
karen801 0:79ce2b184a43 512 }