Example of AWS IoT connection and Web Dashboard thru STM32 Nucleo evaluation board and mbed OS.

Dependencies:   X_NUCLEO_IKS01A1 mbed FP MQTTPacket DnsQuery ATParser

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