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.
SpwfSAInterface.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 20015 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 /** 00018 ****************************************************************************** 00019 * @file SpwfSAInterface.cpp 00020 * @author STMicroelectronics 00021 * @brief Implementation of the NetworkStack for the SPWF Device 00022 ****************************************************************************** 00023 * @copy 00024 * 00025 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 00026 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 00027 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 00028 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 00029 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 00030 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 00031 * 00032 * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2> 00033 ****************************************************************************** 00034 */ 00035 00036 #include "SpwfSAInterface.h" 00037 #include "mbed_debug.h" 00038 #include "BlockExecuter.h" 00039 00040 #if MBED_CONF_RTOS_PRESENT 00041 #define SYNC_HANDLER ScopedMutexLock sync_handler(_spwf_mutex) // assuming a recursive mutex 00042 #else 00043 #define SYNC_HANDLER 00044 #endif 00045 00046 00047 SpwfSAInterface::SpwfSAInterface(PinName tx, PinName rx, 00048 PinName rts, PinName cts, bool debug, 00049 PinName wakeup, PinName reset) 00050 : _spwf(tx, rx, rts, cts, *this, debug, wakeup, reset), 00051 _dbg_on(debug) 00052 { 00053 inner_constructor(); 00054 reset_credentials(); 00055 } 00056 00057 nsapi_error_t SpwfSAInterface::init(void) 00058 { 00059 _spwf.setTimeout(SPWF_INIT_TIMEOUT); 00060 00061 if(_spwf.startup(0)) { 00062 return NSAPI_ERROR_OK; 00063 } 00064 else return NSAPI_ERROR_DEVICE_ERROR; 00065 } 00066 00067 nsapi_error_t SpwfSAInterface::connect(void) 00068 { 00069 int mode; 00070 char *pass_phrase = ap_pass; 00071 SYNC_HANDLER; 00072 00073 // check for valid SSID 00074 if(ap_ssid[0] == '\0') { 00075 return NSAPI_ERROR_PARAMETER; 00076 } 00077 00078 switch(ap_sec) 00079 { 00080 case NSAPI_SECURITY_NONE: 00081 mode = 0; 00082 pass_phrase = NULL; 00083 break; 00084 case NSAPI_SECURITY_WEP: 00085 mode = 1; 00086 break; 00087 case NSAPI_SECURITY_WPA: 00088 case NSAPI_SECURITY_WPA2: 00089 mode = 2; 00090 break; 00091 default: 00092 mode = 2; 00093 break; 00094 } 00095 00096 // First: disconnect 00097 if(_connected_to_network) { 00098 if(!disconnect()) { 00099 return NSAPI_ERROR_DEVICE_ERROR; 00100 } 00101 } 00102 00103 //initialize the device before connecting 00104 if(!_isInitialized) 00105 { 00106 if(init() != NSAPI_ERROR_OK) return NSAPI_ERROR_DEVICE_ERROR; 00107 _isInitialized=true; 00108 } 00109 00110 // Then: (re-)connect 00111 _spwf.setTimeout(SPWF_CONNECT_TIMEOUT); 00112 00113 if (!_spwf.connect(ap_ssid, pass_phrase, mode)) { 00114 return NSAPI_ERROR_AUTH_FAILURE; 00115 } 00116 00117 if (!_spwf.getIPAddress()) { 00118 return NSAPI_ERROR_DHCP_FAILURE; 00119 } 00120 00121 _connected_to_network = true; 00122 return NSAPI_ERROR_OK; 00123 } 00124 00125 nsapi_error_t SpwfSAInterface::connect(const char *ssid, const char *pass, nsapi_security_t security, 00126 uint8_t channel) 00127 { 00128 nsapi_error_t ret; 00129 SYNC_HANDLER; 00130 00131 if (channel != 0) { 00132 return NSAPI_ERROR_UNSUPPORTED; 00133 } 00134 00135 ret = set_credentials(ssid, pass, security); 00136 if(ret != NSAPI_ERROR_OK) return ret; 00137 00138 return connect(); 00139 } 00140 00141 nsapi_error_t SpwfSAInterface::disconnect(void) 00142 { 00143 SYNC_HANDLER; 00144 00145 _spwf.setTimeout(SPWF_DISCONNECT_TIMEOUT); 00146 CHECK_NOT_CONNECTED_ERR(); 00147 00148 if (!_spwf.disconnect()) { 00149 return NSAPI_ERROR_DEVICE_ERROR; 00150 } 00151 00152 return NSAPI_ERROR_OK; 00153 } 00154 00155 const char *SpwfSAInterface::get_ip_address(void) 00156 { 00157 SYNC_HANDLER; 00158 00159 _spwf.setTimeout(SPWF_MISC_TIMEOUT); 00160 return _spwf.getIPAddress(); 00161 } 00162 00163 const char *SpwfSAInterface::get_mac_address(void) 00164 { 00165 SYNC_HANDLER; 00166 00167 _spwf.setTimeout(SPWF_MISC_TIMEOUT); 00168 return _spwf.getMACAddress(); 00169 } 00170 00171 const char *SpwfSAInterface::get_gateway(void) 00172 { 00173 SYNC_HANDLER; 00174 00175 if(!_connected_to_network) return NULL; 00176 00177 _spwf.setTimeout(SPWF_MISC_TIMEOUT); 00178 return _spwf.getGateway(); 00179 } 00180 00181 const char *SpwfSAInterface::get_netmask(void) 00182 { 00183 SYNC_HANDLER; 00184 00185 if(!_connected_to_network) return NULL; 00186 00187 _spwf.setTimeout(SPWF_MISC_TIMEOUT); 00188 return _spwf.getNetmask(); 00189 } 00190 00191 nsapi_error_t SpwfSAInterface::socket_open(void **handle, nsapi_protocol_t proto) 00192 { 00193 int internal_id; 00194 SYNC_HANDLER; 00195 00196 for (internal_id = 0; internal_id < SPWFSA_SOCKET_COUNT; internal_id++) { 00197 if(_ids[internal_id].internal_id == SPWFSA_SOCKET_COUNT) break; 00198 } 00199 00200 if(internal_id == SPWFSA_SOCKET_COUNT) { 00201 debug_if(_dbg_on, "NO Socket ID Error\r\n"); 00202 return NSAPI_ERROR_NO_SOCKET; 00203 } 00204 00205 spwf_socket_t *socket = &_ids[internal_id]; 00206 socket->internal_id = internal_id; 00207 socket->spwf_id = SPWFSA_SOCKET_COUNT; 00208 socket->server_gone = false; 00209 socket->no_more_data = false; 00210 socket->proto = proto; 00211 socket->addr = SocketAddress(); 00212 00213 *handle = socket; 00214 return NSAPI_ERROR_OK; 00215 } 00216 00217 nsapi_error_t SpwfSAInterface::socket_connect(void *handle, const SocketAddress &addr) 00218 { 00219 spwf_socket_t *socket = (spwf_socket_t*)handle; 00220 SYNC_HANDLER; 00221 00222 MBED_ASSERT(((unsigned int)socket->internal_id) < ((unsigned int)SPWFSA_SOCKET_COUNT)); 00223 00224 if(_socket_has_connected(socket->internal_id)) { 00225 return NSAPI_ERROR_IS_CONNECTED; 00226 } 00227 00228 _spwf.setTimeout(SPWF_OPEN_TIMEOUT); 00229 00230 const char *proto = (socket->proto == NSAPI_UDP) ? "u" : "t"; //"s" for secure socket? 00231 00232 if(addr.get_ip_version() != NSAPI_IPv4) { // IPv6 not supported (yet) 00233 return NSAPI_ERROR_UNSUPPORTED; 00234 } 00235 00236 { 00237 BlockExecuter netsock_wa_obj(Callback<void()>(&_spwf, &SPWFSAxx::_unblock_event_callback), 00238 Callback<void()>(&_spwf, &SPWFSAxx::_block_event_callback)); /* disable calling (external) callback in IRQ context */ 00239 00240 /* block asynchronous indications */ 00241 if(!_spwf._winds_off()) { 00242 return NSAPI_ERROR_DEVICE_ERROR; 00243 } 00244 00245 { 00246 BlockExecuter bh_handler(Callback<void()>(&_spwf, &SPWFSAxx::_execute_bottom_halves)); 00247 { 00248 BlockExecuter winds_enabler(Callback<void()>(&_spwf, &SPWFSAxx::_winds_on)); 00249 00250 if(!_spwf.open(proto, &socket->spwf_id, addr.get_ip_address(), addr.get_port())) { 00251 MBED_ASSERT(_spwf._call_event_callback_blocked == 1); 00252 00253 return NSAPI_ERROR_DEVICE_ERROR; 00254 } 00255 00256 /* check for the module to report a valid id */ 00257 MBED_ASSERT(((unsigned int)socket->spwf_id) < ((unsigned int)SPWFSA_SOCKET_COUNT)); 00258 00259 _internal_ids[socket->spwf_id] = socket->internal_id; 00260 socket->addr = addr; 00261 00262 MBED_ASSERT(_spwf._call_event_callback_blocked == 1); 00263 00264 return NSAPI_ERROR_OK; 00265 } 00266 } 00267 } 00268 } 00269 00270 nsapi_error_t SpwfSAInterface::socket_bind(void *handle, const SocketAddress &address) 00271 { 00272 return NSAPI_ERROR_UNSUPPORTED; 00273 } 00274 00275 nsapi_error_t SpwfSAInterface::socket_listen(void *handle, int backlog) 00276 { 00277 return NSAPI_ERROR_UNSUPPORTED; 00278 } 00279 00280 nsapi_error_t SpwfSAInterface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address) 00281 { 00282 return NSAPI_ERROR_UNSUPPORTED; 00283 } 00284 00285 nsapi_error_t SpwfSAInterface::socket_close(void *handle) 00286 { 00287 spwf_socket_t *socket = (spwf_socket_t*)handle; 00288 int internal_id = socket->internal_id; 00289 SYNC_HANDLER; 00290 00291 if(!_socket_is_open(internal_id)) return NSAPI_ERROR_NO_SOCKET; 00292 00293 if(_socket_has_connected(socket)) { 00294 _spwf.setTimeout(SPWF_CLOSE_TIMEOUT); 00295 if (!_spwf.close(socket->spwf_id)) { 00296 return NSAPI_ERROR_DEVICE_ERROR; 00297 } 00298 _internal_ids[socket->spwf_id] = SPWFSA_SOCKET_COUNT; 00299 } 00300 00301 _ids[internal_id].internal_id = SPWFSA_SOCKET_COUNT; 00302 _ids[internal_id].spwf_id = SPWFSA_SOCKET_COUNT; 00303 00304 return NSAPI_ERROR_OK; 00305 } 00306 00307 nsapi_size_or_error_t SpwfSAInterface::socket_send(void *handle, const void *data, unsigned size) 00308 { 00309 spwf_socket_t *socket = (spwf_socket_t*)handle; 00310 SYNC_HANDLER; 00311 00312 CHECK_NOT_CONNECTED_ERR(); 00313 00314 _spwf.setTimeout(SPWF_SEND_TIMEOUT); 00315 return _spwf.send(socket->spwf_id, data, size, socket->internal_id); 00316 } 00317 00318 nsapi_size_or_error_t SpwfSAInterface::socket_recv(void *handle, void *data, unsigned size) 00319 { 00320 SYNC_HANDLER; 00321 00322 return _socket_recv(handle, data, size, false); 00323 } 00324 00325 nsapi_size_or_error_t SpwfSAInterface::_socket_recv(void *handle, void *data, unsigned size, bool datagram) 00326 { 00327 spwf_socket_t *socket = (spwf_socket_t*)handle; 00328 00329 CHECK_NOT_CONNECTED_ERR(); 00330 00331 if(!_socket_has_connected(socket)) { 00332 return NSAPI_ERROR_WOULD_BLOCK; 00333 } else if(socket->no_more_data) { 00334 return 0; 00335 } 00336 00337 _spwf.setTimeout(SPWF_RECV_TIMEOUT); 00338 00339 int32_t recv = _spwf.recv(socket->spwf_id, (char*)data, (uint32_t)size, datagram); 00340 00341 MBED_ASSERT(!_spwf._is_event_callback_blocked()); 00342 MBED_ASSERT((recv != 0) || (size == 0)); 00343 00344 if (recv < 0) { 00345 if(!_socket_is_still_connected(socket)) { 00346 socket->no_more_data = true; 00347 return 0; 00348 } 00349 00350 return NSAPI_ERROR_WOULD_BLOCK; 00351 } 00352 00353 return recv; 00354 } 00355 00356 nsapi_size_or_error_t SpwfSAInterface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) 00357 { 00358 spwf_socket_t *socket = (spwf_socket_t*)handle; 00359 SYNC_HANDLER; 00360 00361 CHECK_NOT_CONNECTED_ERR(); 00362 00363 if ((_socket_has_connected(socket)) && (socket->addr != addr)) { 00364 _spwf.setTimeout(SPWF_CLOSE_TIMEOUT); 00365 if (!_spwf.close(socket->spwf_id)) { 00366 return NSAPI_ERROR_DEVICE_ERROR; 00367 } 00368 _internal_ids[socket->spwf_id] = SPWFSA_SOCKET_COUNT; 00369 socket->spwf_id = SPWFSA_SOCKET_COUNT; 00370 } 00371 00372 _spwf.setTimeout(SPWF_CONN_SND_TIMEOUT); 00373 if (!_socket_has_connected(socket)) { 00374 nsapi_error_t err = socket_connect(socket, addr); 00375 if (err < 0) { 00376 return err; 00377 } 00378 } 00379 00380 return socket_send(socket, data, size); 00381 } 00382 00383 nsapi_size_or_error_t SpwfSAInterface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) 00384 { 00385 spwf_socket_t *socket = (spwf_socket_t*)handle; 00386 nsapi_error_t ret; 00387 SYNC_HANDLER; 00388 00389 ret = _socket_recv(socket, data, size, true); 00390 if (ret >= 0 && addr) { 00391 *addr = socket->addr; 00392 } 00393 00394 return ret; 00395 } 00396 00397 void SpwfSAInterface::socket_attach(void *handle, void (*callback)(void *), void *data) 00398 { 00399 spwf_socket_t *socket = (spwf_socket_t*)handle; 00400 SYNC_HANDLER; 00401 00402 if(!_socket_is_open(socket)) return; // might happen e.g. after module hard fault or voluntary disconnection 00403 00404 _cbs[socket->internal_id].callback = callback; 00405 _cbs[socket->internal_id].data = data; 00406 } 00407 00408 void SpwfSAInterface::event(void) { 00409 for (int internal_id = 0; internal_id < SPWFSA_SOCKET_COUNT; internal_id++) { 00410 if (_cbs[internal_id].callback && (_ids[internal_id].internal_id != SPWFSA_SOCKET_COUNT)) { 00411 _cbs[internal_id].callback(_cbs[internal_id].data); 00412 } 00413 } 00414 } 00415 00416 nsapi_error_t SpwfSAInterface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) 00417 { 00418 SYNC_HANDLER; 00419 00420 if((ssid == NULL) || (strlen(ssid) == 0)) { 00421 return NSAPI_ERROR_PARAMETER; 00422 } 00423 00424 if((pass != NULL) && (strlen(pass) > 0)) { 00425 if(strlen(pass) < sizeof(ap_pass)) { 00426 if(security == NSAPI_SECURITY_NONE) { 00427 return NSAPI_ERROR_PARAMETER; 00428 } 00429 } else { 00430 return NSAPI_ERROR_PARAMETER; 00431 } 00432 } else if(security != NSAPI_SECURITY_NONE) { 00433 return NSAPI_ERROR_PARAMETER; 00434 } 00435 00436 reset_credentials(); 00437 00438 ap_sec = security; 00439 strncpy(ap_ssid, ssid, sizeof(ap_ssid) - 1); 00440 strncpy(ap_pass, pass, sizeof(ap_pass) - 1); 00441 00442 return NSAPI_ERROR_OK; 00443 } 00444 00445 nsapi_error_t SpwfSAInterface::set_channel(uint8_t channel) 00446 { 00447 return NSAPI_ERROR_UNSUPPORTED; 00448 } 00449 00450 int8_t SpwfSAInterface::get_rssi(void) 00451 { 00452 SYNC_HANDLER; 00453 00454 if(!_connected_to_network) return 0; 00455 00456 _spwf.setTimeout(SPWF_MISC_TIMEOUT); 00457 return _spwf.getRssi(); 00458 } 00459 00460 nsapi_size_or_error_t SpwfSAInterface::scan(WiFiAccessPoint *res, unsigned count) 00461 { 00462 SYNC_HANDLER; 00463 00464 nsapi_size_or_error_t ret; 00465 00466 //initialize the device before scanning 00467 if(!_isInitialized) 00468 { 00469 if(init() != NSAPI_ERROR_OK) return NSAPI_ERROR_DEVICE_ERROR; 00470 } 00471 00472 _spwf.setTimeout(SPWF_SCAN_TIMEOUT); 00473 00474 { 00475 BlockExecuter netsock_wa_obj(Callback<void()>(&_spwf, &SPWFSAxx::_unblock_event_callback), 00476 Callback<void()>(&_spwf, &SPWFSAxx::_block_event_callback)); /* disable calling (external) callback in IRQ context */ 00477 00478 /* block asynchronous indications */ 00479 if(!_spwf._winds_off()) { 00480 MBED_ASSERT(_spwf._call_event_callback_blocked == 1); 00481 00482 return NSAPI_ERROR_DEVICE_ERROR; 00483 } 00484 00485 ret = _spwf.scan(res, count); 00486 00487 /* unblock asynchronous indications */ 00488 _spwf._winds_on(); 00489 } 00490 00491 MBED_ASSERT(!_spwf._is_event_callback_blocked()); 00492 00493 //de-initialize the device after scanning 00494 if(!_isInitialized) 00495 { 00496 nsapi_error_t err = disconnect(); 00497 if((err != NSAPI_ERROR_OK) && (err != NSAPI_ERROR_NO_CONNECTION)) return err; 00498 } 00499 00500 return ret; 00501 } 00502 00503 #if MBED_CONF_IDW0XX1_PROVIDE_DEFAULT 00504 00505 WiFiInterface *WiFiInterface::get_default_instance() { 00506 static SpwfSAInterface spwf(MBED_CONF_IDW0XX1_TX, MBED_CONF_IDW0XX1_RX); 00507 return &spwf; 00508 } 00509 00510 #endif
Generated on Tue Jul 12 2022 16:59:38 by
1.7.2