X-NUCLEO-IDW01M1 Wi-Fi expansion board mbed OS 2 ("Classic") library. mbed OS 5 library also available (see below).

Dependencies:   SPWF01SA

Dependents:   SpwfInterface_NSAPI_Testsv2 Nucleo_read_a0_thingspace Nucleo_read_a0_thingspace_mems Cayenne-X-NUCLEO-IDW01M1 ... more

Fork of X_NUCLEO_IDW01M1v2 by ST Expansion SW Team

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