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
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 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 }
Generated on Tue Jul 12 2022 13:15:48 by
