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: X_NUCLEO_IDW01M1_AP_Test
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 int result = _spwf.init(); 00092 return result; 00093 } 00094 00095 /** 00096 * @brief Setup as an access point 00097 * @param ap: SSID to set the access point up with (1-32 characters) 00098 * @param pass_phrase: Password/key of the access point to set up (currently only Open AP is supported, this param is ignored) 00099 * @param security: type of NSAPI security supported (currently only Open AP is supported) 00100 * @param channelNum: Channel for the AP to operate on 1-14 (depending on region) 00101 * @retval NSAPI Error Type 00102 */ 00103 int SpwfSAInterface::start_access_point( 00104 const char *ap, 00105 const char *pass_phrase, 00106 nsapi_security_t security, 00107 int channel_num, 00108 unsigned int data_rates) 00109 { 00110 WiFi_Priv_Mode mode = convert_security(security); 00111 00112 // Check for valid channel_num 00113 if (channel_num < 1 || channel_num > 14) 00114 { 00115 #if DEBUG_PRINT 00116 printf("channel_num must be between 1 and 14\n"); 00117 #endif 00118 return NSAPI_ERROR_PARAMETER; 00119 } 00120 00121 // Verify that the access point is between 1-32 00122 if ((NULL == ap && mode != None) || strlen(ap) < 1 || strlen(ap) > 32) 00123 { 00124 #if DEBUG_PRINT 00125 printf("ap length must be between 1 and 32\n"); 00126 #endif 00127 return NSAPI_ERROR_PARAMETER; 00128 } 00129 00130 //initialize the device before starting the AP 00131 if(!isInitialized) 00132 { 00133 if(init()==0) 00134 isInitialized=true; 00135 else return NSAPI_ERROR_DEVICE_ERROR; 00136 } 00137 00138 _spwf.setTimeout(SPWF_CONNECT_TIMEOUT); 00139 00140 switch (mode) 00141 { 00142 // case WEP: 00143 // { 00144 // break; 00145 // } 00146 // case WPA_Personal: 00147 // { 00148 // break; 00149 // } 00150 default: 00151 { 00152 #if DEBUG_PRINT 00153 printf("Assuming open wifi access point\n"); 00154 #endif 00155 mode = None; 00156 pass_phrase = NULL; 00157 } 00158 } 00159 return (_spwf.start_access_point((char*)ap, (char*)pass_phrase, mode, channel_num, data_rates)); 00160 } 00161 00162 WiFi_Priv_Mode SpwfSAInterface::convert_security(int security) 00163 { 00164 switch(security) 00165 { 00166 case NSAPI_SECURITY_NONE: 00167 return (WiFi_Priv_Mode) None; 00168 case NSAPI_SECURITY_WEP: 00169 return (WiFi_Priv_Mode) WEP; 00170 case NSAPI_SECURITY_WPA: 00171 case NSAPI_SECURITY_WPA2: 00172 return (WiFi_Priv_Mode) WPA_Personal; 00173 default: 00174 return (WiFi_Priv_Mode) WPA_Personal; 00175 } 00176 } 00177 00178 /** 00179 * @brief network connect 00180 connects to Access Point 00181 * @param ap: Access Point (AP) Name String 00182 * pass_phrase: Password String for AP 00183 * security: type of NSAPI security supported 00184 * @retval NSAPI Error Type 00185 */ 00186 int SpwfSAInterface::connect( 00187 const char *ap, 00188 const char *pass_phrase, 00189 nsapi_security_t security) 00190 { 00191 WiFi_Priv_Mode mode; 00192 00193 //initialize the device before connecting 00194 if(!isInitialized) 00195 { 00196 if(init()==0) 00197 isInitialized=true; 00198 else return NSAPI_ERROR_DEVICE_ERROR; 00199 } 00200 00201 _spwf.setTimeout(SPWF_CONNECT_TIMEOUT); 00202 00203 mode = convert_security(security); 00204 if ((WiFi_Priv_Mode) None == mode) 00205 { 00206 pass_phrase = NULL; 00207 } 00208 00209 return (_spwf.connect((char*)ap, (char*)pass_phrase, mode)); 00210 } 00211 00212 /** 00213 * @brief network disconnect 00214 disconnects from Access Point 00215 * @param none 00216 * @retval NSAPI Error Type 00217 */ 00218 int SpwfSAInterface::disconnect() 00219 { 00220 return (_spwf.disconnect()); 00221 } 00222 00223 /** 00224 * @brief Get the local IP address 00225 * @param none 00226 * @retval Null-terminated representation of the local IP address 00227 * or null if not yet connected 00228 */ 00229 const char *SpwfSAInterface::get_ip_address() 00230 { 00231 return _spwf.getIPAddress(); 00232 } 00233 00234 /** 00235 * @brief Get the MAC address 00236 * @param none 00237 * @retval Null-terminated representation of the MAC address 00238 * or null if not yet connected 00239 */ 00240 const char *SpwfSAInterface::get_mac_address() 00241 { 00242 return _spwf.getMACAddress(); 00243 } 00244 00245 /** 00246 * @brief open a socket handle 00247 * @param handle: Pointer to handle 00248 * proto: TCP/UDP protocol 00249 * @retval NSAPI Error Type 00250 */ 00251 int SpwfSAInterface::socket_open(void **handle, nsapi_protocol_t proto) 00252 { 00253 int id = -1; 00254 00255 struct spwf_socket *socket = new struct spwf_socket; 00256 if (!socket) { 00257 return NSAPI_ERROR_NO_SOCKET; 00258 } 00259 00260 socket->id = id; 00261 socket->server_port = id; 00262 socket->proto = proto; 00263 socket->connected = false; 00264 *handle = socket; 00265 return 0; 00266 } 00267 00268 /** 00269 * @brief connect to a remote socket 00270 * @param handle: Pointer to socket handle 00271 * addr: Address to connect to 00272 * @retval NSAPI Error Type 00273 */ 00274 int SpwfSAInterface::socket_connect(void *handle, const SocketAddress &addr) 00275 { 00276 uint8_t sock_id = 99; 00277 struct spwf_socket *socket = (struct spwf_socket *)handle; 00278 00279 const char *proto = (socket->proto == NSAPI_UDP) ? "u" : "t";//"s" for secure socket? 00280 00281 _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 00282 00283 //TODO: Maintain a socket table to map socket ID to host & port 00284 //TODO: lookup on client table to see if already socket is allocated to same host/port 00285 //multimap <char *, vector <uint16_t> > ::iterator i = c_table.find((char*)ip); 00286 00287 if(sock_id <= SPWFSA_SOCKET_COUNT) 00288 { 00289 socket->id = sock_id;//the socket ID of this Socket instance 00290 _ids[socket->id] = true; 00291 socket->connected = true; 00292 } 00293 else 00294 return NSAPI_ERROR_NO_SOCKET; 00295 00296 return 0; 00297 } 00298 00299 /** 00300 * @brief bind to a port number and address 00301 * @param handle: Pointer to socket handle 00302 * proto: address to bind to 00303 * @retval NSAPI Error Type 00304 */ 00305 int SpwfSAInterface::socket_bind(void *handle, const SocketAddress &address) 00306 { 00307 struct spwf_socket *socket = (struct spwf_socket *)handle; 00308 socket->server_port = address.get_port(); 00309 return 0; 00310 } 00311 00312 /** 00313 * @brief start listening on a port and address 00314 * @param handle: Pointer to handle 00315 * backlog: not used (always value is 1) 00316 * @retval NSAPI Error Type 00317 */ 00318 int SpwfSAInterface::socket_listen(void *handle, int backlog) 00319 { 00320 struct spwf_socket *socket = (struct spwf_socket *)handle; 00321 int err; 00322 00323 if(socket->server_port==-1 || isListening) 00324 return NSAPI_ERROR_NO_SOCKET; //server socket not bound or already listening 00325 00326 const char *proto = (socket->proto == NSAPI_UDP) ? "u" : "t"; 00327 00328 err = _spwf.socket_server_open((uint32_t)socket->server_port, (uint8_t *)proto); 00329 if(err==0) 00330 { 00331 socket->id = SERVER_SOCKET_NO;//Special socket ID number for Server Socket 00332 isListening = true; 00333 } 00334 else 00335 return NSAPI_ERROR_DEVICE_ERROR; 00336 00337 return err; 00338 } 00339 00340 /** 00341 * @brief accept connections from remote sockets 00342 * @param handle: Pointer to handle of client socket (connecting) 00343 * proto: handle of server socket which will accept connections 00344 * @retval NSAPI Error Type 00345 */ 00346 int SpwfSAInterface::socket_accept(void **handle, void *server) 00347 { 00348 struct spwf_socket *server_socket = (struct spwf_socket *)server; 00349 00350 if(server_socket->server_port==-1 || !isListening) 00351 return NSAPI_ERROR_NO_SOCKET; //server socket not bound or not listening 00352 00353 if(_spwf.get_wait_for_incoming_client()) 00354 { 00355 server_socket->connected = true; 00356 struct spwf_socket *socket = new struct spwf_socket;//create new network socket 00357 if (!socket) { 00358 return NSAPI_ERROR_NO_SOCKET; 00359 } 00360 00361 memset(socket, 0, sizeof (struct spwf_socket)); 00362 00363 socket->id = server_socket->id; 00364 socket->server_port = server_socket->server_port; 00365 socket->proto = server_socket->proto; 00366 socket->connected = true; 00367 00368 *handle = socket; 00369 socket = 0; 00370 _spwf.set_wait_for_incoming_client(false); 00371 wait_ms(50);//CHECK:TODO:Why do we need this? 00372 return 0; 00373 } 00374 return NSAPI_ERROR_WOULD_BLOCK; 00375 } 00376 00377 /** 00378 * @brief close a socket 00379 * @param handle: Pointer to handle 00380 * @retval NSAPI Error Type 00381 */ 00382 int SpwfSAInterface::socket_close(void *handle) 00383 { 00384 struct spwf_socket *socket = (struct spwf_socket *)handle; 00385 int err = 0; 00386 _spwf.setTimeout(SPWF_MISC_TIMEOUT); 00387 00388 if(socket->id!=-1) 00389 { 00390 if(socket->id==SERVER_SOCKET_NO) 00391 { 00392 if (_spwf.socket_server_close()==-1) { 00393 err = NSAPI_ERROR_DEVICE_ERROR; 00394 } 00395 isListening = false; 00396 } 00397 else 00398 { 00399 if (_spwf.socket_client_close(socket->id)==-1) { 00400 err = NSAPI_ERROR_DEVICE_ERROR; 00401 } 00402 _ids[socket->id] = false; 00403 } 00404 } 00405 00406 delete socket; 00407 return err; 00408 } 00409 00410 /** 00411 * @brief write to a socket 00412 * @param handle: Pointer to handle 00413 * data: pointer to data 00414 * size: size of data 00415 * @retval no of bytes sent 00416 */ 00417 int SpwfSAInterface::socket_send(void *handle, const void *data, unsigned size) 00418 { 00419 struct spwf_socket *socket = (struct spwf_socket *)handle; 00420 int err; 00421 00422 if(socket->id==SERVER_SOCKET_NO) 00423 { 00424 if(socket->server_port==-1 || !isListening) 00425 return NSAPI_ERROR_NO_SOCKET; //server socket not bound or not listening 00426 00427 err = _spwf.socket_server_write((uint16_t)size, (char*)data); 00428 } 00429 else 00430 { 00431 err = _spwf.socket_client_write((uint8_t)socket->id, (uint16_t)size, (char*)data); 00432 } 00433 00434 return err; 00435 } 00436 00437 /** 00438 * @brief receive data on a socket 00439 * @param handle: Pointer to handle 00440 * data: pointer to data 00441 * size: size of data 00442 * @retval no of bytes read 00443 */ 00444 int SpwfSAInterface::socket_recv(void *handle, void *data, unsigned size) 00445 { 00446 struct spwf_socket *socket = (struct spwf_socket *)handle; 00447 int32_t recv; 00448 00449 _spwf.setTimeout(SPWF_RECV_TIMEOUT); 00450 00451 //CHECK:Receive for both Client and Server Sockets same? 00452 recv = _spwf.socket_client_recv((uint8_t)socket->id, (uint16_t)size, (char*)data); 00453 if (recv < 0) { 00454 return NSAPI_ERROR_WOULD_BLOCK; 00455 } 00456 return recv; 00457 00458 } 00459 00460 /** 00461 * @brief send data to a udp socket 00462 * @param handle: Pointer to handle 00463 * addr: address of udp socket 00464 * data: pointer to data 00465 * size: size of data 00466 * @retval no of bytes sent 00467 */ 00468 int SpwfSAInterface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) 00469 { 00470 struct spwf_socket *socket = (struct spwf_socket *)handle; 00471 if (!socket->connected) { 00472 int err = socket_connect(socket, addr); 00473 if (err < 0) { 00474 return err; 00475 } 00476 } 00477 00478 return socket_send(socket, data, size); 00479 } 00480 00481 /** 00482 * @brief receive data on a udp socket 00483 * @param handle: Pointer to handle 00484 * addr: address of udp socket 00485 * data: pointer to data 00486 * size: size of data 00487 * @retval no of bytes read 00488 */ 00489 int SpwfSAInterface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) 00490 { 00491 struct spwf_socket *socket = (struct spwf_socket *)handle; 00492 return socket_recv(socket, data, size); 00493 } 00494 00495 /** 00496 * @brief attach function/callback to the socket 00497 * Not used 00498 * @param handle: Pointer to handle 00499 * callback: callback function pointer 00500 * data: pointer to data 00501 * @retval none 00502 */ 00503 void SpwfSAInterface::socket_attach(void *handle, void (*callback)(void *), void *data) 00504 { 00505 //No implementation yet 00506 } 00507 00508 /** 00509 * @brief utility debug function for printing to serial terminal 00510 * @param string: Pointer to data 00511 * @retval none 00512 */ 00513 void SpwfSAInterface::debug(const char * string) 00514 { 00515 _spwf.debug_print(string); 00516 }
Generated on Tue Jul 12 2022 12:20:21 by
1.7.2
