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.
Dependencies: X_NUCLEO_IKS01A2 mbed-http
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 00147 if (!_spwf.disconnect()) { 00148 return NSAPI_ERROR_DEVICE_ERROR; 00149 } 00150 00151 return NSAPI_ERROR_OK; 00152 } 00153 00154 const char *SpwfSAInterface::get_ip_address(void) 00155 { 00156 SYNC_HANDLER; 00157 00158 _spwf.setTimeout(SPWF_MISC_TIMEOUT); 00159 return _spwf.getIPAddress(); 00160 } 00161 00162 const char *SpwfSAInterface::get_mac_address(void) 00163 { 00164 SYNC_HANDLER; 00165 00166 _spwf.setTimeout(SPWF_MISC_TIMEOUT); 00167 return _spwf.getMACAddress(); 00168 } 00169 00170 const char *SpwfSAInterface::get_gateway(void) 00171 { 00172 SYNC_HANDLER; 00173 00174 if(!_connected_to_network) return NULL; 00175 00176 _spwf.setTimeout(SPWF_MISC_TIMEOUT); 00177 return _spwf.getGateway(); 00178 } 00179 00180 const char *SpwfSAInterface::get_netmask(void) 00181 { 00182 SYNC_HANDLER; 00183 00184 if(!_connected_to_network) return NULL; 00185 00186 _spwf.setTimeout(SPWF_MISC_TIMEOUT); 00187 return _spwf.getNetmask(); 00188 } 00189 00190 nsapi_error_t SpwfSAInterface::socket_open(void **handle, nsapi_protocol_t proto) 00191 { 00192 int internal_id; 00193 SYNC_HANDLER; 00194 00195 for (internal_id = 0; internal_id < SPWFSA_SOCKET_COUNT; internal_id++) { 00196 if(_ids[internal_id].internal_id == SPWFSA_SOCKET_COUNT) break; 00197 } 00198 00199 if(internal_id == SPWFSA_SOCKET_COUNT) { 00200 debug_if(_dbg_on, "NO Socket ID Error\r\n"); 00201 return NSAPI_ERROR_NO_SOCKET; 00202 } 00203 00204 spwf_socket_t *socket = &_ids[internal_id]; 00205 socket->internal_id = internal_id; 00206 socket->spwf_id = SPWFSA_SOCKET_COUNT; 00207 socket->server_gone = false; 00208 socket->no_more_data = false; 00209 socket->proto = proto; 00210 socket->addr = SocketAddress(); 00211 00212 *handle = socket; 00213 return NSAPI_ERROR_OK; 00214 } 00215 00216 nsapi_error_t SpwfSAInterface::socket_connect(void *handle, const SocketAddress &addr) 00217 { 00218 spwf_socket_t *socket = (spwf_socket_t*)handle; 00219 SYNC_HANDLER; 00220 00221 MBED_ASSERT(((unsigned int)socket->internal_id) < ((unsigned int)SPWFSA_SOCKET_COUNT)); 00222 00223 if(_socket_has_connected(socket->internal_id)) { 00224 return NSAPI_ERROR_IS_CONNECTED; 00225 } 00226 00227 _spwf.setTimeout(SPWF_OPEN_TIMEOUT); 00228 00229 const char *proto = (socket->proto == NSAPI_UDP) ? "u" : "t"; //"s" for secure socket? 00230 00231 if(addr.get_ip_version() != NSAPI_IPv4) { // IPv6 not supported (yet) 00232 return NSAPI_ERROR_UNSUPPORTED; 00233 } 00234 00235 { 00236 BlockExecuter netsock_wa_obj(Callback<void()>(&_spwf, &SPWFSAxx::_unblock_event_callback), 00237 Callback<void()>(&_spwf, &SPWFSAxx::_block_event_callback)); /* disable calling (external) callback in IRQ context */ 00238 00239 /* block asynchronous indications */ 00240 if(!_spwf._winds_off()) { 00241 return NSAPI_ERROR_DEVICE_ERROR; 00242 } 00243 00244 { 00245 BlockExecuter bh_handler(Callback<void()>(&_spwf, &SPWFSAxx::_execute_bottom_halves)); 00246 { 00247 BlockExecuter winds_enabler(Callback<void()>(&_spwf, &SPWFSAxx::_winds_on)); 00248 00249 if(!_spwf.open(proto, &socket->spwf_id, addr.get_ip_address(), addr.get_port())) { 00250 MBED_ASSERT(_spwf._call_event_callback_blocked == 1); 00251 00252 return NSAPI_ERROR_DEVICE_ERROR; 00253 } 00254 00255 /* check for the module to report a valid id */ 00256 MBED_ASSERT(((unsigned int)socket->spwf_id) < ((unsigned int)SPWFSA_SOCKET_COUNT)); 00257 00258 _internal_ids[socket->spwf_id] = socket->internal_id; 00259 socket->addr = addr; 00260 00261 MBED_ASSERT(_spwf._call_event_callback_blocked == 1); 00262 00263 return NSAPI_ERROR_OK; 00264 } 00265 } 00266 } 00267 } 00268 00269 nsapi_error_t SpwfSAInterface::socket_bind(void *handle, const SocketAddress &address) 00270 { 00271 return NSAPI_ERROR_UNSUPPORTED; 00272 } 00273 00274 nsapi_error_t SpwfSAInterface::socket_listen(void *handle, int backlog) 00275 { 00276 return NSAPI_ERROR_UNSUPPORTED; 00277 } 00278 00279 nsapi_error_t SpwfSAInterface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address) 00280 { 00281 return NSAPI_ERROR_UNSUPPORTED; 00282 } 00283 00284 nsapi_error_t SpwfSAInterface::socket_close(void *handle) 00285 { 00286 spwf_socket_t *socket = (spwf_socket_t*)handle; 00287 int internal_id = socket->internal_id; 00288 SYNC_HANDLER; 00289 00290 if(!_socket_is_open(internal_id)) return NSAPI_ERROR_NO_SOCKET; 00291 00292 if(_socket_has_connected(socket)) { 00293 _spwf.setTimeout(SPWF_CLOSE_TIMEOUT); 00294 if (!_spwf.close(socket->spwf_id)) { 00295 return NSAPI_ERROR_DEVICE_ERROR; 00296 } 00297 _internal_ids[socket->spwf_id] = SPWFSA_SOCKET_COUNT; 00298 } 00299 00300 _ids[internal_id].internal_id = SPWFSA_SOCKET_COUNT; 00301 _ids[internal_id].spwf_id = SPWFSA_SOCKET_COUNT; 00302 00303 return NSAPI_ERROR_OK; 00304 } 00305 00306 nsapi_size_or_error_t SpwfSAInterface::socket_send(void *handle, const void *data, unsigned size) 00307 { 00308 spwf_socket_t *socket = (spwf_socket_t*)handle; 00309 SYNC_HANDLER; 00310 00311 CHECK_NOT_CONNECTED_ERR(); 00312 00313 _spwf.setTimeout(SPWF_SEND_TIMEOUT); 00314 return _spwf.send(socket->spwf_id, data, size, socket->internal_id); 00315 } 00316 00317 nsapi_size_or_error_t SpwfSAInterface::socket_recv(void *handle, void *data, unsigned size) 00318 { 00319 SYNC_HANDLER; 00320 00321 return _socket_recv(handle, data, size, false); 00322 } 00323 00324 nsapi_size_or_error_t SpwfSAInterface::_socket_recv(void *handle, void *data, unsigned size, bool datagram) 00325 { 00326 spwf_socket_t *socket = (spwf_socket_t*)handle; 00327 00328 CHECK_NOT_CONNECTED_ERR(); 00329 00330 if(!_socket_has_connected(socket)) { 00331 return NSAPI_ERROR_WOULD_BLOCK; 00332 } else if(socket->no_more_data) { 00333 return 0; 00334 } 00335 00336 _spwf.setTimeout(SPWF_RECV_TIMEOUT); 00337 00338 int32_t recv = _spwf.recv(socket->spwf_id, (char*)data, (uint32_t)size, datagram); 00339 00340 MBED_ASSERT(!_spwf._is_event_callback_blocked()); 00341 MBED_ASSERT((recv != 0) || (size == 0)); 00342 00343 if (recv < 0) { 00344 if(!_socket_is_still_connected(socket)) { 00345 socket->no_more_data = true; 00346 return 0; 00347 } 00348 00349 return NSAPI_ERROR_WOULD_BLOCK; 00350 } 00351 00352 return recv; 00353 } 00354 00355 nsapi_size_or_error_t SpwfSAInterface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) 00356 { 00357 spwf_socket_t *socket = (spwf_socket_t*)handle; 00358 SYNC_HANDLER; 00359 00360 CHECK_NOT_CONNECTED_ERR(); 00361 00362 if ((_socket_has_connected(socket)) && (socket->addr != addr)) { 00363 _spwf.setTimeout(SPWF_CLOSE_TIMEOUT); 00364 if (!_spwf.close(socket->spwf_id)) { 00365 return NSAPI_ERROR_DEVICE_ERROR; 00366 } 00367 _internal_ids[socket->spwf_id] = SPWFSA_SOCKET_COUNT; 00368 socket->spwf_id = SPWFSA_SOCKET_COUNT; 00369 } 00370 00371 _spwf.setTimeout(SPWF_CONN_SND_TIMEOUT); 00372 if (!_socket_has_connected(socket)) { 00373 nsapi_error_t err = socket_connect(socket, addr); 00374 if (err < 0) { 00375 return err; 00376 } 00377 } 00378 00379 return socket_send(socket, data, size); 00380 } 00381 00382 nsapi_size_or_error_t SpwfSAInterface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) 00383 { 00384 spwf_socket_t *socket = (spwf_socket_t*)handle; 00385 nsapi_error_t ret; 00386 SYNC_HANDLER; 00387 00388 ret = _socket_recv(socket, data, size, true); 00389 if (ret >= 0 && addr) { 00390 *addr = socket->addr; 00391 } 00392 00393 return ret; 00394 } 00395 00396 void SpwfSAInterface::socket_attach(void *handle, void (*callback)(void *), void *data) 00397 { 00398 spwf_socket_t *socket = (spwf_socket_t*)handle; 00399 SYNC_HANDLER; 00400 00401 if(!_socket_is_open(socket)) return; // might happen e.g. after module hard fault or voluntary disconnection 00402 00403 _cbs[socket->internal_id].callback = callback; 00404 _cbs[socket->internal_id].data = data; 00405 } 00406 00407 void SpwfSAInterface::event(void) { 00408 for (int internal_id = 0; internal_id < SPWFSA_SOCKET_COUNT; internal_id++) { 00409 if (_cbs[internal_id].callback && (_ids[internal_id].internal_id != SPWFSA_SOCKET_COUNT)) { 00410 _cbs[internal_id].callback(_cbs[internal_id].data); 00411 } 00412 } 00413 } 00414 00415 nsapi_error_t SpwfSAInterface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) 00416 { 00417 SYNC_HANDLER; 00418 00419 if((ssid == NULL) || (strlen(ssid) == 0)) { 00420 return NSAPI_ERROR_PARAMETER; 00421 } 00422 00423 if((pass != NULL) && (strlen(pass) > 0)) { 00424 if(strlen(pass) < sizeof(ap_pass)) { 00425 if(security == NSAPI_SECURITY_NONE) { 00426 return NSAPI_ERROR_PARAMETER; 00427 } 00428 } else { 00429 return NSAPI_ERROR_PARAMETER; 00430 } 00431 } else if(security != NSAPI_SECURITY_NONE) { 00432 return NSAPI_ERROR_PARAMETER; 00433 } 00434 00435 reset_credentials(); 00436 00437 ap_sec = security; 00438 strncpy(ap_ssid, ssid, sizeof(ap_ssid) - 1); 00439 strncpy(ap_pass, pass, sizeof(ap_pass) - 1); 00440 00441 return NSAPI_ERROR_OK; 00442 } 00443 00444 nsapi_error_t SpwfSAInterface::set_channel(uint8_t channel) 00445 { 00446 return NSAPI_ERROR_UNSUPPORTED; 00447 } 00448 00449 int8_t SpwfSAInterface::get_rssi(void) 00450 { 00451 SYNC_HANDLER; 00452 00453 if(!_connected_to_network) return 0; 00454 00455 _spwf.setTimeout(SPWF_MISC_TIMEOUT); 00456 return _spwf.getRssi(); 00457 } 00458 00459 nsapi_size_or_error_t SpwfSAInterface::scan(WiFiAccessPoint *res, unsigned count) 00460 { 00461 SYNC_HANDLER; 00462 00463 nsapi_size_or_error_t ret; 00464 00465 //initialize the device before scanning 00466 if(!_isInitialized) 00467 { 00468 if(init() != NSAPI_ERROR_OK) return NSAPI_ERROR_DEVICE_ERROR; 00469 } 00470 00471 _spwf.setTimeout(SPWF_SCAN_TIMEOUT); 00472 00473 { 00474 BlockExecuter netsock_wa_obj(Callback<void()>(&_spwf, &SPWFSAxx::_unblock_event_callback), 00475 Callback<void()>(&_spwf, &SPWFSAxx::_block_event_callback)); /* disable calling (external) callback in IRQ context */ 00476 00477 /* block asynchronous indications */ 00478 if(!_spwf._winds_off()) { 00479 MBED_ASSERT(_spwf._call_event_callback_blocked == 1); 00480 00481 return NSAPI_ERROR_DEVICE_ERROR; 00482 } 00483 00484 ret = _spwf.scan(res, count); 00485 00486 /* unblock asynchronous indications */ 00487 _spwf._winds_on(); 00488 } 00489 00490 MBED_ASSERT(!_spwf._is_event_callback_blocked()); 00491 00492 //de-initialize the device after scanning 00493 if(!_isInitialized) 00494 { 00495 nsapi_error_t err = disconnect(); 00496 if(err != NSAPI_ERROR_OK) return err; 00497 } 00498 00499 return ret; 00500 }
Generated on Tue Jul 12 2022 17:09:10 by
1.7.2