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
SPWFSA01.cpp
00001 /* SPWFInterface Example 00002 * Copyright (c) 2015 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 #include "SPWFSA01.h" 00018 #include "mbed_debug.h" 00019 #include "stdint.h" 00020 00021 #define SPWFSA01_CONNECT_TIMEOUT 15000 00022 #define SPWFSA01_SEND_TIMEOUT 5000 00023 #define SPWFSA01_RECV_TIMEOUT 1500//some commands like AT&F/W takes some time to get the result back! 00024 #define SPWFSA01_MISC_TIMEOUT 500 00025 #define SPWFSA01_SOCKQ_TIMEOUT 3000 00026 00027 #define EPOCH_TIME 1453727657//Human time (GMT): Mon, 25 Jan 2016 13:14:17 GMT 00028 00029 SPWFSA01::SPWFSA01(PinName tx, PinName rx, PinName reset, PinName wakeup, bool debug) 00030 : _serial(tx, rx, 1024), _parser(_serial,"\r\n", 2048), 00031 _wakeup(wakeup, PIN_OUTPUT, PullNone, 0), 00032 _reset(reset, PIN_OUTPUT, PullNone, 1), 00033 dbg_on(debug) 00034 { 00035 _serial.baud(115200); // LICIO FIXME increase the speed 00036 _parser.debugOn(debug); 00037 } 00038 00039 bool SPWFSA01::startup(int mode) 00040 { 00041 _parser.setTimeout(SPWFSA01_MISC_TIMEOUT); 00042 /*Test module before reset*/ 00043 waitSPWFReady(); 00044 /*Reset module*/ 00045 reset(); 00046 00047 /*set local echo to 0*/ 00048 if(!(_parser.send("AT+S.SCFG=localecho1,%d\r", 0) && _parser.recv("OK"))) 00049 { 00050 debug_if(dbg_on, "SPWF> error local echo set\r\n"); 00051 return false; 00052 } 00053 /*reset factory settings*/ 00054 if(!(_parser.send("AT&F") && _parser.recv("OK"))) 00055 { 00056 debug_if(dbg_on, "SPWF> error AT&F\r\n"); 00057 return false; 00058 } 00059 00060 /*set Wi-Fi mode and rate to b/g*/ 00061 if(!(_parser.send("AT+S.SCFG=wifi_ht_mode,%d\r", 0) && _parser.recv("OK"))) 00062 { 00063 debug_if(dbg_on, "SPWF> error setting ht_mode\r\n"); 00064 return false; 00065 } 00066 00067 //if(!(_parser.send("AT+S.SCFG=wifi_opr_rate_mask,0x003FFFCF\r") && _parser.recv("OK"))) 00068 if(!(_parser.send("AT+S.SCFG=wifi_opr_rate_mask,0x00000001\r") && _parser.recv("OK")))// set most effective speed for such kind of device 00069 { 00070 debug_if(dbg_on, "SPWF> error setting operational rates\r\n"); 00071 return false; 00072 } 00073 00074 if(!(_parser.send("AT+S.SCFG=wifi_bas_rate_mask,0x0000000F\r") && _parser.recv("OK")))// set most effective speed for such kind of device 00075 { 00076 debug_if(dbg_on, "SPWF> error setting basic rates\r\n"); 00077 return false; 00078 } 00079 00080 if(!(_parser.send("AT+S.SCFG=wifi_powersave,0\r") && _parser.recv("OK")))// set most effective speed for such kind of device 00081 { 00082 debug_if(dbg_on, "SPWF> error setting power save mode\r\n"); 00083 return false; 00084 } 00085 00086 if(!(_parser.send("AT+S.SCFG=sleep_enabled,0\r") && _parser.recv("OK")))// set most effective speed for such kind of device 00087 { 00088 debug_if(dbg_on, "SPWF> error setting sleep mode\r\n"); 00089 return false; 00090 } 00091 00092 if(!(_parser.send("AT+S.SCFG=wifi_tx_power,18\r") && _parser.recv("OK")))// set most effective speed for such kind of device 00093 { 00094 debug_if(dbg_on, "SPWF> error setting transmit power\r\n"); 00095 return false; 00096 } 00097 00098 if(!(_parser.send("AT+S.SCFG=ip_use_dhcp,1\r") && _parser.recv("OK")))// set most effective speed for such kind of device 00099 { 00100 debug_if(dbg_on, "SPWF> error setting dhcp on\r\n"); 00101 return false; 00102 } 00103 00104 if(!(_parser.send("AT+S.SCFG=ip_dhcp_timeout,20\r") && _parser.recv("OK")))// set most effective speed for such kind of device 00105 { 00106 debug_if(dbg_on, "SPWF> error setting dhcp timeout\r\n"); 00107 return false; 00108 } 00109 00110 /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/ 00111 if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", mode) && _parser.recv("OK"))) 00112 { 00113 debug_if(dbg_on, "SPWF> error wifi mode set\r\n"); 00114 return false; 00115 } 00116 00117 /* save current setting in flash */ 00118 if(!(_parser.send("AT&W") && _parser.recv("OK"))) 00119 { 00120 debug_if(dbg_on, "SPWF> error AT&W\r\n"); 00121 return false; 00122 } 00123 00124 /*reset again and send AT command and check for result (AT->OK)*/ 00125 reset(); 00126 00127 return true; 00128 } 00129 00130 bool SPWFSA01::hw_reset(void) 00131 { 00132 if (_reset.is_connected()) { 00133 /* reset the pin PC12 */ 00134 _reset.write(0); 00135 wait_ms(200); 00136 _reset.write(1); 00137 wait_ms(100); 00138 return 1; 00139 } else { return 0; } 00140 } 00141 00142 bool SPWFSA01::reset(void) 00143 { 00144 if(!_parser.send("AT+CFUN=1")) return false; 00145 while(1) { 00146 if (_parser.recv("+WIND:32:WiFi Hardware Started\r")) { 00147 return true; 00148 } 00149 } 00150 } 00151 00152 void SPWFSA01::waitSPWFReady(void) 00153 { 00154 //wait_ms(200); 00155 while(1) 00156 if(_parser.send("AT") && _parser.recv("OK")) 00157 //till we get OK from AT command 00158 //printf("\r\nwaiting for reset to complete..\n"); 00159 return; 00160 00161 } 00162 00163 /* Security Mode 00164 None = 0, 00165 WEP = 1, 00166 WPA_Personal = 2, 00167 */ 00168 bool SPWFSA01::connect(const char *ap, const char *passPhrase, int securityMode) 00169 { 00170 uint32_t n1, n2, n3, n4; 00171 00172 _parser.setTimeout(SPWFSA01_CONNECT_TIMEOUT); 00173 //AT+S.SCFG=wifi_wpa_psk_text,%s\r 00174 if(!(_parser.send("AT+S.SCFG=wifi_wpa_psk_text,%s", passPhrase) && _parser.recv("OK"))) 00175 { 00176 debug_if(dbg_on, "SPWF> error pass set\r\n"); 00177 return false; 00178 } 00179 //AT+S.SSIDTXT=%s\r 00180 if(!(_parser.send("AT+S.SSIDTXT=%s", ap) && _parser.recv("OK"))) 00181 { 00182 debug_if(dbg_on, "SPWF> error ssid set\r\n"); 00183 return false; 00184 } 00185 //AT+S.SCFG=wifi_priv_mode,%d\r 00186 if(!(_parser.send("AT+S.SCFG=wifi_priv_mode,%d", securityMode) && _parser.recv("OK"))) 00187 { 00188 debug_if(dbg_on, "SPWF> error security mode set\r\n"); 00189 return false; 00190 } 00191 //"AT+S.SCFG=wifi_mode,%d\r" 00192 /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/ 00193 if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", 1) && _parser.recv("OK"))) 00194 { 00195 debug_if(dbg_on, "SPWF> error wifi mode set\r\n"); 00196 return false; 00197 } 00198 //AT&W 00199 /* save current setting in flash */ 00200 if(!(_parser.send("AT&W") && _parser.recv("OK"))) 00201 { 00202 debug_if(dbg_on, "SPWF> error AT&W\r\n"); 00203 return false; 00204 } 00205 //reset module 00206 reset(); 00207 00208 while(1) 00209 if((_parser.recv("+WIND:24:WiFi Up:%u.%u.%u.%u",&n1, &n2, &n3, &n4))) 00210 { 00211 break; 00212 } 00213 00214 return true; 00215 } 00216 00217 bool SPWFSA01::disconnect(void) 00218 { 00219 //"AT+S.SCFG=wifi_mode,%d\r" 00220 /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/ 00221 if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", 0) && _parser.recv("OK"))) 00222 { 00223 debug_if(dbg_on, "SPWF> error wifi mode set\r\n"); 00224 return false; 00225 } 00226 //AT&W 00227 /* save current setting in flash */ 00228 if(!(_parser.send("AT&W") && _parser.recv("OK"))) 00229 { 00230 debug_if(dbg_on, "SPWF> error AT&W\r\n"); 00231 return false; 00232 } 00233 //reset module 00234 reset(); 00235 return true; 00236 } 00237 00238 bool SPWFSA01::dhcp(int mode) 00239 { 00240 //only 3 valid modes 00241 //0->off(ip_addr must be set by user), 1->on(auto set by AP), 2->on&customize(miniAP ip_addr can be set by user) 00242 if(mode < 0 || mode > 2) { 00243 return false; 00244 } 00245 00246 return _parser.send("AT+S.SCFG=ip_use_dhcp,%d\r", mode) 00247 && _parser.recv("OK"); 00248 } 00249 00250 00251 const char *SPWFSA01::getIPAddress(void) 00252 { 00253 uint32_t n1, n2, n3, n4; 00254 00255 if (!(_parser.send("AT+S.STS=ip_ipaddr") 00256 && _parser.recv("# ip_ipaddr = %u.%u.%u.%u", &n1, &n2, &n3, &n4) 00257 && _parser.recv("OK"))) { 00258 debug_if(dbg_on, "SPWF> getIPAddress error\r\n"); 00259 return 0; 00260 } 00261 00262 sprintf((char*)_ip_buffer,"%u.%u.%u.%u", n1, n2, n3, n4); 00263 00264 return _ip_buffer; 00265 } 00266 00267 const char *SPWFSA01::getMACAddress(void) 00268 { 00269 uint32_t n1, n2, n3, n4, n5, n6; 00270 00271 if (!(_parser.send("AT+S.GCFG=nv_wifi_macaddr") 00272 && _parser.recv("# nv_wifi_macaddr = %x:%x:%x:%x:%x:%x", &n1, &n2, &n3, &n4, &n5, &n6) 00273 && _parser.recv("OK"))) { 00274 debug_if(dbg_on, "SPWF> getMACAddress error\r\n"); 00275 return 0; 00276 } 00277 00278 sprintf((char*)_mac_buffer,"%02X:%02X:%02X:%02X:%02X:%02X", n1, n2, n3, n4, n5, n6); 00279 00280 return _mac_buffer; 00281 } 00282 00283 bool SPWFSA01::isConnected(void) 00284 { 00285 return getIPAddress() != 0; 00286 } 00287 00288 bool SPWFSA01::open(const char *type, int* id, const char* addr, int port) 00289 { 00290 Timer timer; 00291 timer.start(); 00292 socket_closed = 0; 00293 00294 if(!_parser.send("AT+S.SOCKON=%s,%d,%s,ind", addr, port, type)) 00295 { 00296 debug_if(dbg_on, "SPWF> error opening socket\r\n"); 00297 return false; 00298 } 00299 00300 while(1) 00301 { 00302 if( _parser.recv(" ID: %d", id) 00303 && _parser.recv("OK")) 00304 break; 00305 00306 if (timer.read_ms() > SPWFSA01_CONNECT_TIMEOUT) { 00307 return false; 00308 } 00309 00310 //TODO:implement time-out functionality in case of no response 00311 //if(timeout) return false; 00312 //TODO: deal with errors like "ERROR: Failed to resolve name" 00313 //TODO: deal with errors like "ERROR: Data mode not available" 00314 } 00315 00316 return true; 00317 } 00318 00319 bool SPWFSA01::send(int id, const void *data, uint32_t amount) 00320 { 00321 char _buf[18]; 00322 _parser.setTimeout(SPWFSA01_SEND_TIMEOUT); 00323 00324 sprintf((char*)_buf,"AT+S.SOCKW=%d,%d\r", id, amount); 00325 00326 //May take a second try if device is busy 00327 for (unsigned i = 0; i < 2; i++) { 00328 if (_parser.write((char*)_buf, strlen(_buf)) >=0 00329 && _parser.write((char*)data, (int)amount) >= 0 00330 && _parser.recv("OK")) { 00331 return true; 00332 } 00333 } 00334 return false; 00335 } 00336 00337 00338 int32_t SPWFSA01::recv(int id, void *data, uint32_t amount) 00339 { 00340 uint32_t recv_amount=0; 00341 int wind_id; 00342 00343 if (socket_closed) { 00344 socket_closed = 0; 00345 return -3; 00346 } 00347 if(!(_parser.send("AT+S.SOCKQ=%d", id) //send a query (will be required for secure sockets) 00348 && _parser.recv(" DATALEN: %u", &recv_amount) 00349 && _parser.recv("OK"))) { 00350 return -2; 00351 } 00352 if (recv_amount==0) { return -1; } 00353 if(recv_amount > amount) 00354 recv_amount = amount; 00355 00356 int par_timeout = _parser.getTimeout(); 00357 _parser.setTimeout(0); 00358 00359 while(_parser.recv("+WIND:%d:", &wind_id)) { 00360 // printf("Wind received: %d\n\r", wind_id); 00361 if (wind_id == 58) { 00362 socket_closed = 1; 00363 _parser.flush(); 00364 } 00365 } 00366 _parser.setTimeout(par_timeout); 00367 00368 _parser.flush(); 00369 if(!(_parser.send("AT+S.SOCKR=%d,%d", id, recv_amount))){ 00370 return -2; 00371 } 00372 if(!((_parser.read((char*)data, recv_amount) >0) 00373 && _parser.recv("OK"))) { 00374 return -2; 00375 } 00376 return recv_amount; 00377 } 00378 00379 bool SPWFSA01::close(int id) 00380 { 00381 uint32_t recv_amount=0; 00382 void * data = NULL; 00383 00384 _parser.setTimeout(SPWFSA01_MISC_TIMEOUT); 00385 _parser.flush(); 00386 /* socket flush */ 00387 if(!(_parser.send("AT+S.SOCKQ=%d", id) //send a query (will be required for secure sockets) 00388 && _parser.recv(" DATALEN: %u", &recv_amount) 00389 && _parser.recv("OK"))) { 00390 return -2; 00391 } 00392 if (recv_amount>0) { 00393 data = malloc (recv_amount+4); 00394 if(!(_parser.send("AT+S.SOCKR=%d,%d", id, recv_amount))) { 00395 free (data); 00396 return -2; 00397 } 00398 // printf ("--->>>Close flushing recv_amount: %d \n\r",recv_amount); 00399 if(!((_parser.read((char*)data, recv_amount) >0) 00400 && _parser.recv("OK"))) { 00401 free (data); 00402 return -2; 00403 } 00404 free (data); 00405 } 00406 00407 //May take a second try if device is busy or error is returned 00408 for (unsigned i = 0; i < 2; i++) { 00409 if (_parser.send("AT+S.SOCKC=%d", id) 00410 && _parser.recv("OK")) { 00411 socket_closed = 1; 00412 return true; 00413 } 00414 else 00415 { 00416 if(_parser.recv("ERROR: Pending data")) { 00417 debug_if(dbg_on, "SPWF> ERROR!!!!\r\n"); 00418 return false; 00419 } 00420 } 00421 //TODO: Deal with "ERROR: Pending data" (Closing a socket with pending data) 00422 } 00423 return false; 00424 } 00425 00426 00427 bool SPWFSA01::readable() 00428 { 00429 return _serial.readable(); 00430 } 00431 00432 bool SPWFSA01::writeable() 00433 { 00434 return _serial.writeable(); 00435 } 00436 00437 int SPWFSA01::setSocketClientSecurity(uint8_t* tls_mode, uint8_t* root_ca_server, uint8_t* client_cert, uint8_t* client_key, uint8_t* client_domain, uint32_t tls_epoch_time) 00438 { 00439 int err = 0; 00440 unsigned long epoch_time; 00441 00442 if(!(_parser.send("AT+S.TLSCERT2=clean,all\r", 0) && _parser.recv("OK"))) 00443 { 00444 debug_if(dbg_on, "SPWF> TLSCERT2 cleared\r\n"); 00445 return -1; 00446 } 00447 00448 if(tls_epoch_time==0) 00449 epoch_time = EPOCH_TIME; 00450 else 00451 epoch_time = tls_epoch_time; 00452 00453 if(!(_parser.send("AT+S.SETTIME=%lu\r", (unsigned long)epoch_time) && _parser.recv("OK"))) 00454 { 00455 debug_if(dbg_on, "SPWF> time is set to %d\r\n", epoch_time); 00456 return -1; 00457 } 00458 00459 /*AT+S.TLSCERT=f_ca,<size><CR><data>*/ 00460 if(!(_parser.send("AT+S.TLSCERT=f_ca,%d\r%s\r", strlen((const char *)root_ca_server) - 1, root_ca_server) && _parser.recv("OK"))) 00461 { 00462 debug_if(dbg_on, "SPWF> error TLSCERT=f_ca set\r\n"); 00463 return -1; 00464 } 00465 00466 /*AT+S.TLSCERT=f_cert,<size><CR><data>*/ 00467 if(tls_mode[0]=='m') 00468 { 00469 if(!(_parser.send("AT+S.TLSCERT=f_cert,%d\r%s", strlen((const char *)client_cert) - 1, client_cert) && _parser.recv("OK"))) 00470 { 00471 debug_if(dbg_on, "SPWF> error TLSCERT=f_cert set\r\n"); 00472 return -1; 00473 } 00474 00475 /*AT+S.TLSCERT=f_key,<size><CR><data>*/ 00476 if(!(_parser.send("AT+S.TLSCERT=f_key,%d\r%s", strlen((const char *)client_key) - 1, client_key) && _parser.recv("OK"))) 00477 { 00478 debug_if(dbg_on, "SPWF> error TLSCERT=f_key set\r\n"); 00479 return -1; 00480 } 00481 } 00482 00483 /*AT+S.TLSDOMAIN=f_domain,<server domain>*/ 00484 if(!(_parser.send("AT+S.TLSDOMAIN=f_domain,%s\r", client_domain) && _parser.recv("OK"))) 00485 { 00486 debug_if(dbg_on, "SPWF> error TLSDOMAIN=f_domain set\r\n"); 00487 return -1; 00488 } 00489 00490 return err; 00491 } 00492
Generated on Wed Jul 13 2022 20:28:49 by 1.7.2