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