Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: SpwfInterface_NSAPI_Tests HelloWorld_IDW01M1
Fork of X_NUCLEO_IDW01M1 by
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>© 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 }
Generated on Tue Jul 12 2022 16:20:36 by
1.7.2

X-NUCLEO-IDW01M1 Wi-Fi expansion board