Lauri Pirttiaho / X_NUCLEO_IDW01M1v2-lapi-1

Dependencies:   SPWF01SA-lapi-1

Dependents:   x-nucleo-iks01a1-test x-nucleo-iks01a1-test

Fork of X_NUCLEO_IDW01M1v2 by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SpwfInterface.cpp Source File

SpwfInterface.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    SpwfInterface.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 "SpwfInterface.h"
00037 #include <string.h>
00038  
00039 // Various timeouts for different SPWF operations
00040 #define SPWF_CONNECT_TIMEOUT 20000
00041 #define SPWF_SEND_TIMEOUT    500
00042 #define SPWF_RECV_TIMEOUT    500
00043 #define SPWF_MISC_TIMEOUT    15000
00044 
00045 /** spwf_socket class
00046  *  Implementation of SPWF socket structure
00047  */
00048 struct spwf_socket {
00049     int id;
00050     int server_port;
00051     nsapi_protocol_t proto;
00052     bool connected;
00053 };
00054 
00055 
00056 /**
00057 * @brief  SpwfSAInterface constructor         
00058 * @param  tx: Pin USART TX  
00059 *         rx: Pin USART RX
00060 *         rst: reset pin for Spwf module
00061 *         wkup: reset pin for Spwf module
00062 *         rts: Pin USART RTS
00063 *         debug : not used
00064 * @retval none
00065 */
00066 SpwfSAInterface::SpwfSAInterface(PinName tx, PinName rx, bool debug)
00067     : _spwf(tx, rx, debug), _ssid(0), _pass(0), _channel(0)
00068 {
00069     memset(_ids, 0, sizeof(_ids));
00070     isInitialized = false;
00071     isListening = false;
00072 }
00073 
00074 /**
00075 * @brief  SpwfSAInterface destructor         
00076 * @param  none
00077 * @retval none
00078 */
00079 SpwfSAInterface::~SpwfSAInterface()
00080 {
00081 }
00082 
00083 /**
00084 * @brief  Get the RSSI of the last packet         
00085 * @param  none
00086 * @retval RSSI of the last packet (dBm)
00087 */
00088 int8_t SpwfSAInterface::get_rssi()
00089 {
00090     return _spwf.getRSSI();
00091 }
00092 
00093 /**
00094 * @brief  init function
00095           initializes SPWF FW and module         
00096 * @param  none
00097 * @retval error value
00098 */
00099 int SpwfSAInterface::init(void) 
00100 {
00101     _spwf.setTimeout(SPWF_MISC_TIMEOUT);
00102     if(_spwf.startup(0)) {
00103         isInitialized=true;
00104         return NSAPI_ERROR_OK;
00105     }
00106     else return NSAPI_ERROR_DEVICE_ERROR;
00107 }
00108 
00109 nsapi_error_t SpwfSAInterface::set_credentials(
00110         const char *ssid, const char *pass, nsapi_security_t security) {
00111     _ssid = ssid; // TODO! Copy of the string preferred!
00112     _pass = pass;
00113     _security = security;
00114     return NSAPI_ERROR_OK;
00115     
00116 }
00117 
00118 /**
00119 * @brief  network connect
00120           connects to Access Point
00121 * @param  ap: Access Point (AP) Name String  
00122 *         pass_phrase: Password String for AP
00123 *         security: type of NSAPI security supported
00124 *         channel: the WiFi channel number
00125 * @retval NSAPI Error Type
00126 */
00127 nsapi_error_t SpwfSAInterface::connect(const char *ap, 
00128                              const char *pass_phrase, 
00129                              nsapi_security_t security,
00130                              uint8_t channel)
00131 {    
00132     int mode;
00133     
00134     //initialize the device before connecting
00135     if(!isInitialized)
00136     {
00137         if (init() != NSAPI_ERROR_OK)
00138             return NSAPI_ERROR_DEVICE_ERROR;
00139     }
00140 
00141     _spwf.setTimeout(SPWF_CONNECT_TIMEOUT);   
00142     
00143     switch(security)
00144     {
00145         case NSAPI_SECURITY_NONE:
00146             mode = 0;
00147             pass_phrase = NULL;
00148             break;
00149         case NSAPI_SECURITY_WEP:
00150             mode = 1;
00151             break;
00152         case NSAPI_SECURITY_WPA:
00153         case NSAPI_SECURITY_WPA2:
00154             mode = 2;
00155             break;
00156         default:
00157             mode = 2;
00158             break;
00159     }
00160     if (_spwf.connect((char*)ap, (char*)pass_phrase, mode, channel)) {
00161         return NSAPI_ERROR_NO_CONNECTION;
00162     } else {
00163         return NSAPI_ERROR_OK;
00164     }
00165 }
00166 
00167 /**
00168 * @brief  network disconnect
00169           disconnects from Access Point
00170 * @param  none
00171 * @retval NSAPI Error Type
00172 */
00173 int SpwfSAInterface::disconnect()
00174 {    
00175     return (_spwf.disconnect());
00176 }
00177 
00178 /** 
00179 * @brief  Get the local IP address
00180 * @param  none
00181 * @retval Null-terminated representation of the local IP address
00182 *         or null if not yet connected
00183 */
00184 const char *SpwfSAInterface::get_ip_address()
00185 {
00186     return _spwf.getIPAddress();
00187 }
00188 
00189 /** 
00190 * @brief  Get the MAC address
00191 * @param  none
00192 * @retval Null-terminated representation of the MAC address
00193 *         or null if not yet connected
00194 */
00195 const char *SpwfSAInterface::get_mac_address()
00196 {
00197     return _spwf.getMACAddress();
00198 }
00199 
00200 /**
00201 * @brief  open a socket handle
00202 * @param  handle: Pointer to handle
00203 *         proto: TCP/UDP protocol
00204 * @retval NSAPI Error Type
00205 */
00206 int SpwfSAInterface::socket_open(void **handle, nsapi_protocol_t proto)
00207 {
00208     int id = -1;    
00209 
00210     struct spwf_socket *socket = new struct spwf_socket;
00211     if (!socket) {
00212         return NSAPI_ERROR_NO_SOCKET;
00213     }
00214 
00215     socket->id = id;
00216     socket->server_port = id;
00217     socket->proto = proto;
00218     socket->connected = false;
00219     *handle = socket;
00220     return 0;
00221 }
00222 
00223 /**
00224 * @brief  connect to a remote socket
00225 * @param  handle: Pointer to socket handle
00226 *         addr: Address to connect to
00227 * @retval NSAPI Error Type
00228 */
00229 int SpwfSAInterface::socket_connect(void *handle, const SocketAddress &addr)
00230 {
00231     int sock_id = 99;
00232     struct spwf_socket *socket = (struct spwf_socket *)handle;
00233     
00234     const char *proto = (socket->proto == NSAPI_UDP) ? "u" : "t";//"s" for secure socket?
00235 
00236     if (!_spwf.open(proto, &sock_id, addr.get_ip_address(), addr.get_port())) {;//sock ID is allocated NOW
00237         return NSAPI_ERROR_DEVICE_ERROR;
00238     }
00239     
00240     //TODO: Maintain a socket table to map socket ID to host & port
00241     //TODO: lookup on client table to see if already socket is allocated to same host/port
00242     //multimap <char *, vector <uint16_t> > ::iterator i = c_table.find((char*)ip);
00243       
00244     if(sock_id <= SPWFSA_SOCKET_COUNT)
00245     {
00246         socket->id = sock_id;//the socket ID of this Socket instance
00247         _ids[socket->id] = true;
00248         socket->connected = true;
00249     }
00250     else 
00251         return NSAPI_ERROR_NO_SOCKET;
00252     
00253     return 0;
00254 }
00255 
00256 /**
00257 * @brief  bind to a port number and address
00258 * @param  handle: Pointer to socket handle
00259 *         proto: address to bind to
00260 * @retval NSAPI Error Type
00261 */
00262 int SpwfSAInterface::socket_bind(void *handle, const SocketAddress &address)
00263 {
00264     struct spwf_socket *socket = (struct spwf_socket *)handle;    
00265     socket->server_port = address.get_port();
00266     return 0;
00267 }
00268 
00269 /**
00270 * @brief  start listening on a port and address
00271 * @param  handle: Pointer to handle
00272 *         backlog: not used (always value is 1)
00273 * @retval NSAPI Error Type
00274 */
00275 int SpwfSAInterface::socket_listen(void *handle, int backlog)
00276 {      
00277     return NSAPI_ERROR_UNSUPPORTED;
00278 }
00279 
00280 /**
00281 * @brief  accept connections from remote sockets
00282 * @param  handle: Pointer to handle of client socket (connecting)
00283 *         proto: handle of server socket which will accept connections
00284 * @retval NSAPI Error Type
00285 */
00286 nsapi_error_t SpwfSAInterface::socket_accept(nsapi_socket_t server,
00287             nsapi_socket_t *handle, SocketAddress *address)
00288 {    
00289     return NSAPI_ERROR_UNSUPPORTED;
00290 }
00291 
00292 /**
00293 * @brief  close a socket
00294 * @param  handle: Pointer to handle
00295 * @retval NSAPI Error Type
00296 */
00297 int SpwfSAInterface::socket_close(void *handle)
00298 {
00299     struct spwf_socket *socket = (struct spwf_socket *)handle;
00300     int err = 0;
00301     _spwf.setTimeout(SPWF_MISC_TIMEOUT);
00302     
00303     if(socket->id!=-1)
00304     {
00305         if (_spwf.close(socket->id)) {
00306             if(socket->id==SERVER_SOCKET_NO)      
00307                 isListening = false;
00308             else
00309                 _ids[socket->id] = false;            
00310         }
00311         else err = NSAPI_ERROR_DEVICE_ERROR;
00312     }
00313 
00314     delete socket;
00315     return err;
00316 }
00317 
00318 /**
00319 * @brief  write to a socket
00320 * @param  handle: Pointer to handle
00321 *         data: pointer to data
00322 *         size: size of data
00323 * @retval no of bytes sent
00324 */
00325 int SpwfSAInterface::socket_send(void *handle, const void *data, unsigned size)
00326 {    
00327     struct spwf_socket *socket = (struct spwf_socket *)handle;
00328     //int err;
00329     
00330     /*if(socket->id==SERVER_SOCKET_NO)
00331         {
00332             if(socket->server_port==-1 || !isListening) 
00333                 return NSAPI_ERROR_NO_SOCKET; //server socket not bound or not listening        
00334 
00335             err = _spwf.socket_server_write((uint16_t)size, (char*)data);
00336         }
00337     else
00338         {
00339             err = _spwf.send(socket->id, (char*)data, (uint32_t)size);
00340         }*/
00341     if (!_spwf.send(socket->id, (char*)data, (uint32_t)size)) {
00342         return NSAPI_ERROR_DEVICE_ERROR;
00343     }
00344  
00345     return size;
00346 }
00347 
00348 /**
00349 * @brief  receive data on a socket
00350 * @param  handle: Pointer to handle
00351 *         data: pointer to data
00352 *         size: size of data
00353 * @retval no of bytes read
00354 */
00355 int SpwfSAInterface::socket_recv(void *handle, void *data, unsigned size)
00356 {
00357     struct spwf_socket *socket = (struct spwf_socket *)handle;
00358     int32_t recv;
00359     
00360     _spwf.setTimeout(SPWF_RECV_TIMEOUT);
00361     
00362     //CHECK:Receive for both Client and Server Sockets same?
00363     recv = _spwf.recv(socket->id, (char*)data, (uint32_t)size);    
00364     if (recv < 0) {
00365         //wait_ms(1);//delay of 1ms <for F4>??
00366         //printf(".");
00367         if (recv == -1) return NSAPI_ERROR_WOULD_BLOCK;//send this if we want to block call (else timeout will happen)
00368         else return NSAPI_ERROR_DEVICE_ERROR;
00369     }
00370 
00371     return recv;
00372     
00373 }
00374 
00375 /**
00376 * @brief  send data to a udp socket
00377 * @param  handle: Pointer to handle
00378 *         addr: address of udp socket
00379 *         data: pointer to data
00380 *         size: size of data
00381 * @retval no of bytes sent
00382 */
00383 int SpwfSAInterface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
00384 {
00385     struct spwf_socket *socket = (struct spwf_socket *)handle;
00386     if (!socket->connected) {
00387         int err = socket_connect(socket, addr);
00388         if (err < 0) {
00389             return err;
00390         }
00391     }
00392     
00393     return socket_send(socket, data, size);
00394 }
00395 
00396 /**
00397 * @brief  receive data on a udp socket
00398 * @param  handle: Pointer to handle
00399 *         addr: address of udp socket
00400 *         data: pointer to data
00401 *         size: size of data
00402 * @retval no of bytes read
00403 */
00404 int SpwfSAInterface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
00405 {
00406     struct spwf_socket *socket = (struct spwf_socket *)handle;    
00407     return socket_recv(socket, data, size);
00408 }
00409 
00410 /**
00411 * @brief  attach function/callback to the socket
00412 *         Not used
00413 * @param  handle: Pointer to handle
00414 *         callback: callback function pointer
00415 *         data: pointer to data
00416 * @retval none
00417 */
00418 void SpwfSAInterface::socket_attach(void *handle, void (*callback)(void *), void *data)
00419 {
00420     //No implementation yet
00421 }
00422 
00423 /**
00424 * @brief  utility debug function for printing to serial terminal
00425 * @param  string: Pointer to data
00426 * @retval none
00427 */
00428 void SpwfSAInterface::debug(const char * string)
00429 {
00430     //_spwf.debug_print(string);
00431 }