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.
Dependencies: X_NUCLEO_IKS01A2 mbed-http
WizFi310.cpp
00001 /* 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 /** 00018 ****************************************************************************** 00019 * @file WizFi310.cpp 00020 * @author Gateway Team 00021 * @brief Implementation file of the WizFi310 WiFi Device 00022 ****************************************************************************** 00023 * @attention 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, WIZnet 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 2017 WIZnet Co.,Ltd.</center></h2> 00033 ****************************************************************************** 00034 */ 00035 00036 #include "WizFi310.h" 00037 #define WIZFI310_DEFAULT_BAUD_RATE 115200 00038 00039 #define AT_CMD_PARSER_DEFAULT_TIMEOUT 500 00040 #define AT_CMD_PARSER_INIT_TIMEOUT 1000 00041 #define AT_CMD_PARSER_RECV_TIMEOUT 20000 00042 00043 using namespace mbed; 00044 WizFi310::WizFi310(PinName tx, PinName rx, bool debug) 00045 : _serial(tx, rx, WIZFI310_DEFAULT_BAUD_RATE), 00046 _parser(&_serial), 00047 _packets(0), 00048 _packets_end(&_packets) 00049 { 00050 _serial.set_baud( WIZFI310_DEFAULT_BAUD_RATE ); 00051 _parser.debug_on(debug); 00052 _parser.set_delimiter("\r\n"); 00053 00054 setTimeout(AT_CMD_PARSER_INIT_TIMEOUT); 00055 for(int i=0; i<10; i++) 00056 { 00057 if( _parser.send("AT") && _parser.recv("[OK]") ) 00058 { 00059 _parser.send("AT+MECHO=0"); 00060 _parser.recv("[OK]"); 00061 _parser.send("AT+MPROF=S"); 00062 _parser.recv("[OK]"); 00063 _parser.send("AT+MRESET"); 00064 _parser.recv("[OK]"); 00065 break; 00066 } 00067 } 00068 00069 _parser.recv("WizFi310 Version %s (WIZnet Co.Ltd)", _firmware_version); 00070 } 00071 00072 const char* WizFi310::get_firmware_version() 00073 { 00074 if( strlen(_firmware_version) != 0 ) 00075 { 00076 return _firmware_version; 00077 } 00078 00079 _parser.send("AT+MINFO"); 00080 if( _parser.recv("%s/WizFi310 Rev", _firmware_version) ) 00081 { 00082 return _firmware_version; 00083 } 00084 00085 return 0; 00086 } 00087 00088 bool WizFi310::startup(int mode) 00089 { 00090 if( mode != 0 && mode != 1 ) 00091 { 00092 return false; 00093 } 00094 _op_mode = mode; 00095 00096 _parser.oob("{", callback(this, &WizFi310::_packet_handler)); 00097 //_parser.oob("\n{", callback(this, &WizFi310::_packet_handler)); 00098 return true; 00099 } 00100 00101 bool WizFi310::reset(void) 00102 { 00103 for (int i=0; i<2; i++) 00104 { 00105 if(_parser.send("AT+MRESET") 00106 && _parser.recv("[OK]")) 00107 { 00108 return true; 00109 } 00110 } 00111 00112 return false; 00113 } 00114 00115 bool WizFi310::dhcp(bool enabled) 00116 { 00117 _dhcp = enabled; 00118 return _dhcp; 00119 } 00120 00121 bool WizFi310::connect(const char *ap, const char *passPhrase, const char *sec) 00122 { 00123 if ( !(_parser.send("AT+WSET=0,%s", ap) && _parser.recv("[OK]")) ) 00124 { 00125 return false; 00126 } 00127 00128 //if ( !(_parser.send("AT+WSEC=0,%s,%s", sec, passPhrase) && _parser.recv("[OK]")) ) 00129 if ( !(_parser.send("AT+WSEC=0,,%s", passPhrase) && _parser.recv("[OK]")) ) 00130 { 00131 return false; 00132 } 00133 00134 if (_dhcp) 00135 { 00136 if ( !(_parser.send("AT+WNET=1") && _parser.recv("[OK]")) ) 00137 { 00138 return false; 00139 } 00140 } 00141 else 00142 { 00143 if ( !(_parser.send("AT+WNET=0,%s,%s,%s",_ip_buffer,_netmask_buffer,_gateway_buffer) 00144 && _parser.recv("[OK]")) ) 00145 { 00146 return false; 00147 } 00148 } 00149 00150 if ( !(_parser.send("AT+WJOIN") && _parser.recv("[Link-Up Event]") 00151 && _parser.recv(" IP Addr : %[^\n]\r\n",_ip_buffer) 00152 && _parser.recv(" Gateway : %[^\n]\r\n",_gateway_buffer) 00153 && _parser.recv("[OK]")) ) 00154 { 00155 return false; 00156 } 00157 00158 return true; 00159 } 00160 00161 bool WizFi310::disconnect(void) 00162 { 00163 return _parser.send("AT+WLEAVE") && _parser.recv("[OK]"); 00164 } 00165 00166 const char *WizFi310::getIPAddress(void) 00167 { 00168 if (!(_parser.send("AT+WSTATUS") && _parser.recv("IF/SSID/IP-Addr/Gateway/MAC/TxPower(dBm)/RSSI(-dBm)") 00169 && _parser.recv("%*[^/]/%*[^/]/%15[^/]/",_ip_buffer) 00170 && _parser.recv("[OK]")) ) 00171 { 00172 return 0; 00173 } 00174 00175 return _ip_buffer; 00176 } 00177 00178 const char *WizFi310::getMACAddress(void) 00179 { 00180 if (!(_parser.send("AT+MMAC=?") 00181 && _parser.recv("%[^\n]\r\n",_mac_buffer) 00182 && _parser.recv("[OK]"))) { 00183 return 0; 00184 } 00185 00186 return _mac_buffer; 00187 } 00188 00189 const char *WizFi310::getGateway() 00190 { 00191 return _gateway_buffer; 00192 } 00193 00194 const char *WizFi310::getNetmask() 00195 { 00196 return _netmask_buffer; 00197 } 00198 00199 int8_t WizFi310::getRSSI() 00200 { 00201 char rssi[3]; 00202 00203 if (!(_parser.send("AT+WSTATUS") && _parser.recv("IF/SSID/IP-Addr/Gateway/MAC/TxPower(dBm)/RSSI(-dBm)") 00204 //&& _parser.recv("%*[^/]/%*[^/]/%*[^/]/%*[^/]/%*[^/]/%*[^/]/%[^\n]\r\n",&rssi) 00205 && _parser.recv("%*[^/]/%*[^/]/%*[^/]/%*[^/]/%*[^/]//%[^\n]\r\n",rssi) 00206 && _parser.recv("[OK]")) ) 00207 { 00208 return 0; 00209 } 00210 00211 return atoi(rssi); 00212 } 00213 00214 bool WizFi310::isConnected(void) 00215 { 00216 return getIPAddress() != 0; 00217 } 00218 00219 int WizFi310::scan(WiFiAccessPoint *res, unsigned limit) 00220 { 00221 unsigned int cnt = 0; 00222 nsapi_wifi_ap_t ap; 00223 00224 // Scan Time out : 50ms 00225 if (!(_parser.send("AT+WSCAN=,,,50") 00226 && _parser.recv("Index/SSID/BSSID/RSSI(-dBm)/MaxDataRate(Mbps)/Security/RadioBand(GHz)/Channel"))) 00227 { 00228 return NSAPI_ERROR_DEVICE_ERROR; 00229 } 00230 00231 while (recv_ap(&ap)) { 00232 if (cnt < limit) 00233 { 00234 res[cnt] = WiFiAccessPoint(ap); 00235 } 00236 cnt++; 00237 if (limit != 0 && cnt >= limit) 00238 { 00239 break; 00240 } 00241 } 00242 00243 return cnt; 00244 } 00245 00246 bool WizFi310::open(const char *type, int id, const char* addr, int port) 00247 { 00248 int created_sock_id; 00249 00250 //IDs only 0-7 00251 if(id > 7) { 00252 return false; 00253 } 00254 00255 if( !(_parser.send("AT+SCON=O,%s,%s,%d,,0",type,addr,port) && _parser.recv("[OK]") 00256 && _parser.recv("[CONNECT %d]",&created_sock_id))) { 00257 return false; 00258 } 00259 00260 if( created_sock_id != id ) { 00261 close(created_sock_id); 00262 return false; 00263 } 00264 00265 return true; 00266 } 00267 00268 bool WizFi310::dns_lookup(const char* name, char* ip) 00269 { 00270 return (_parser.send("AT+FDNS=%s,5000", name) && _parser.recv("%[^\n]\r\n",ip) && _parser.recv("[OK]")); 00271 } 00272 00273 bool WizFi310::send(int id, const void *data, uint32_t amount) 00274 { 00275 char str_result[20]; 00276 00277 if(id > 8) { 00278 return false; 00279 } 00280 00281 sprintf(str_result,"[%d,,,%d]",id,(int)amount); 00282 00283 // Using _parser.printf because MCU can't send CR LF 00284 if( _parser.printf("AT+SSEND=%d,,,%d\r",id, (int)amount) 00285 && _parser.recv(str_result) 00286 && _parser.write((char*)data, (int)amount) >= 0 00287 && _parser.recv("[OK]") ){ 00288 return true; 00289 } 00290 00291 return false; 00292 } 00293 00294 void WizFi310::_packet_handler() 00295 { 00296 int id; 00297 char ip_addr[16]; 00298 int port; 00299 uint32_t amount; 00300 00301 // parse out the packet 00302 _parser.set_timeout(AT_CMD_PARSER_RECV_TIMEOUT); 00303 if (!_parser.recv("%d,%[^,],%d,%d}",&id, ip_addr,&port, &amount) ) { 00304 setTimeout(_timeout_ms); 00305 return; 00306 } 00307 00308 struct packet *packet = new struct packet; 00309 if (!packet) { 00310 return; 00311 } 00312 00313 packet->id = id; 00314 packet->len = amount; 00315 packet->next = 0; 00316 packet->data = (char*)malloc(amount); 00317 00318 00319 if (!(_parser.read((char*)packet->data, amount))) { 00320 free(packet); 00321 setTimeout(_timeout_ms); 00322 return; 00323 } 00324 setTimeout(_timeout_ms); 00325 00326 *_packets_end = packet; 00327 _packets_end = &packet->next; 00328 } 00329 00330 int32_t WizFi310::recv(int id, void *data, uint32_t amount) 00331 { 00332 while (true) { 00333 // check if any packets are ready for us 00334 for (struct packet **p = &_packets; *p; p = &(*p)->next) { 00335 if ((*p)->id == id) { 00336 struct packet *q = *p; 00337 00338 if (q->len <= amount) { 00339 memcpy(data,q->data, q->len); 00340 00341 if (_packets_end == &(*p)->next) { 00342 _packets_end = p; 00343 } 00344 *p = (*p)->next; 00345 00346 uint32_t len = q->len; 00347 free(q); 00348 return len; 00349 } else { // return only partial packet 00350 memcpy(data, q->data, amount); 00351 00352 q->len -= amount; 00353 memmove(q->data, (uint8_t*)(q->data) + amount, q->len); 00354 return amount; 00355 } 00356 } 00357 } 00358 00359 // check for inbound packets 00360 if (!_parser.process_oob()) { 00361 return -1; 00362 } 00363 } 00364 } 00365 00366 bool WizFi310::close(int id) 00367 { 00368 char sock_event_msg[15]; 00369 00370 if(id > 7) { 00371 return false; 00372 } 00373 00374 if (_parser.send("AT+SMGMT=%d", id) && _parser.recv(sock_event_msg) && _parser.recv("[OK]") ) 00375 { 00376 return true; 00377 } 00378 00379 return false; 00380 } 00381 00382 void WizFi310::setTimeout(uint32_t timeout_ms) 00383 { 00384 _parser.set_timeout(timeout_ms); 00385 _timeout_ms = timeout_ms; 00386 } 00387 00388 bool WizFi310::readable() 00389 { 00390 return _serial.FileHandle::readable(); 00391 } 00392 00393 bool WizFi310::writeable() 00394 { 00395 return _serial.FileHandle::writable(); 00396 } 00397 00398 void WizFi310::attach(Callback<void()> func) 00399 { 00400 _serial.sigio(func); 00401 } 00402 00403 bool WizFi310::recv_ap(nsapi_wifi_ap_t *ap) 00404 { 00405 char scan_result[100]; 00406 char sec[10]; 00407 char bssid[32]; 00408 char* idx_ptr; 00409 char* bssid_ptr; 00410 00411 _parser.recv("%s\r\n",scan_result); 00412 if( strcmp(scan_result,"[OK]") == 0 ) 00413 { 00414 return false; 00415 } 00416 00417 idx_ptr = strtok((char*)scan_result, "/"); // index 00418 00419 idx_ptr = strtok( NULL, "/" ); // ssid 00420 strncpy(ap->ssid,idx_ptr,strlen(idx_ptr)); 00421 ap->ssid[strlen(idx_ptr)] = '\0'; 00422 00423 idx_ptr = strtok( NULL, "/" ); // bssid 00424 strncpy(bssid,idx_ptr,strlen(idx_ptr)); 00425 bssid[strlen(idx_ptr)] = '\0'; 00426 00427 idx_ptr = strtok( NULL, "/" ); // RSSI 00428 ap->rssi = atoi(idx_ptr); 00429 00430 //idx_ptr = strtok( NULL, "/" ); // DataRate 00431 00432 idx_ptr = strtok( NULL, "/" ); // Security 00433 strncpy(sec,idx_ptr,strlen(idx_ptr)); 00434 sec[strlen(idx_ptr)] = '\0'; 00435 ap->security = str2sec(sec); 00436 00437 idx_ptr = strtok( NULL, "/" ); // RadioBand 00438 00439 idx_ptr = strtok( NULL, "/" ); // Channel 00440 ap->channel = atoi(idx_ptr); 00441 00442 // Set BSSID 00443 bssid_ptr = strtok( (char*)bssid, ":"); 00444 ap->bssid[0] = hex_str_to_int(bssid_ptr); 00445 00446 for(int i=1; i<6; i++) 00447 { 00448 bssid_ptr = strtok( NULL, ":"); 00449 ap->bssid[i] = hex_str_to_int(bssid_ptr); 00450 } 00451 00452 return true; 00453 } 00454 00455 nsapi_security_t WizFi310::str2sec(const char *str_sec) 00456 { 00457 if( strcmp(str_sec,"Open") == 0 ) 00458 { 00459 return NSAPI_SECURITY_NONE; 00460 } 00461 else if( strcmp(str_sec,"WEP") == 0 ) 00462 { 00463 return NSAPI_SECURITY_WEP; 00464 } 00465 else if( strcmp(str_sec,"WPA") == 0 ) 00466 { 00467 return NSAPI_SECURITY_WPA; 00468 } 00469 else if( strcmp(str_sec,"WPA2") == 0 ) 00470 { 00471 return NSAPI_SECURITY_WPA2; 00472 } 00473 else if( strcmp(str_sec,"WPAWPA2") == 0 ) 00474 { 00475 return NSAPI_SECURITY_WPA_WPA2; 00476 } 00477 00478 return NSAPI_SECURITY_UNKNOWN; 00479 } 00480 00481 int WizFi310::hex_str_to_int(const char* hex_str) 00482 { 00483 int n = 0; 00484 uint32_t value = 0; 00485 int shift = 7; 00486 while (hex_str[n] != '\0' && n < 8) 00487 { 00488 if ( hex_str[n] > 0x21 && hex_str[n] < 0x40 ) 00489 { 00490 value |= (hex_str[n] & 0x0f) << (shift << 2); 00491 } 00492 else if ( (hex_str[n] >= 'a' && hex_str[n] <= 'f') || (hex_str[n] >= 'A' && hex_str[n] <= 'F') ) 00493 { 00494 value |= ((hex_str[n] & 0x0f) + 9) << (shift << 2); 00495 } 00496 else 00497 { 00498 break; 00499 } 00500 n++; 00501 shift--; 00502 } 00503 00504 return (value >> ((shift + 1) << 2)); 00505 } 00506
Generated on Tue Jul 12 2022 17:09:10 by
1.7.2