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