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