ST / X_NUCLEO_IDW01M1

Dependents:   SpwfInterface_NSAPI_Tests HelloWorld_IDW01M1

Fork of X_NUCLEO_IDW01M1 by ST Expansion SW Team

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPWFInterface.cpp Source File

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