Advantech / Mbed OS pelion-example-common
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SpwfSAInterface.cpp Source File

SpwfSAInterface.cpp

Go to the documentation of this file.
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>&copy; 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