wifi test
Dependencies: X_NUCLEO_IKS01A2 mbed-http
easy-connect/wizfi310-driver/WizFi310/WizFi310.cpp
- Committer:
- JMF
- Date:
- 2018-09-05
- Revision:
- 0:24d3eb812fd4
File content as of revision 0:24d3eb812fd4:
/* * Copyright (c) 2015 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** ****************************************************************************** * @file WizFi310.cpp * @author Gateway Team * @brief Implementation file of the WizFi310 WiFi Device ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, WIZnet SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * <h2><center>© COPYRIGHT 2017 WIZnet Co.,Ltd.</center></h2> ****************************************************************************** */ #include "WizFi310.h" #define WIZFI310_DEFAULT_BAUD_RATE 115200 #define AT_CMD_PARSER_DEFAULT_TIMEOUT 500 #define AT_CMD_PARSER_INIT_TIMEOUT 1000 #define AT_CMD_PARSER_RECV_TIMEOUT 20000 using namespace mbed; WizFi310::WizFi310(PinName tx, PinName rx, bool debug) : _serial(tx, rx, WIZFI310_DEFAULT_BAUD_RATE), _parser(&_serial), _packets(0), _packets_end(&_packets) { _serial.set_baud( WIZFI310_DEFAULT_BAUD_RATE ); _parser.debug_on(debug); _parser.set_delimiter("\r\n"); setTimeout(AT_CMD_PARSER_INIT_TIMEOUT); for(int i=0; i<10; i++) { if( _parser.send("AT") && _parser.recv("[OK]") ) { _parser.send("AT+MECHO=0"); _parser.recv("[OK]"); _parser.send("AT+MPROF=S"); _parser.recv("[OK]"); _parser.send("AT+MRESET"); _parser.recv("[OK]"); break; } } _parser.recv("WizFi310 Version %s (WIZnet Co.Ltd)", _firmware_version); } const char* WizFi310::get_firmware_version() { if( strlen(_firmware_version) != 0 ) { return _firmware_version; } _parser.send("AT+MINFO"); if( _parser.recv("%s/WizFi310 Rev", _firmware_version) ) { return _firmware_version; } return 0; } bool WizFi310::startup(int mode) { if( mode != 0 && mode != 1 ) { return false; } _op_mode = mode; _parser.oob("{", callback(this, &WizFi310::_packet_handler)); //_parser.oob("\n{", callback(this, &WizFi310::_packet_handler)); return true; } bool WizFi310::reset(void) { for (int i=0; i<2; i++) { if(_parser.send("AT+MRESET") && _parser.recv("[OK]")) { return true; } } return false; } bool WizFi310::dhcp(bool enabled) { _dhcp = enabled; return _dhcp; } bool WizFi310::connect(const char *ap, const char *passPhrase, const char *sec) { if ( !(_parser.send("AT+WSET=0,%s", ap) && _parser.recv("[OK]")) ) { return false; } //if ( !(_parser.send("AT+WSEC=0,%s,%s", sec, passPhrase) && _parser.recv("[OK]")) ) if ( !(_parser.send("AT+WSEC=0,,%s", passPhrase) && _parser.recv("[OK]")) ) { return false; } if (_dhcp) { if ( !(_parser.send("AT+WNET=1") && _parser.recv("[OK]")) ) { return false; } } else { if ( !(_parser.send("AT+WNET=0,%s,%s,%s",_ip_buffer,_netmask_buffer,_gateway_buffer) && _parser.recv("[OK]")) ) { return false; } } if ( !(_parser.send("AT+WJOIN") && _parser.recv("[Link-Up Event]") && _parser.recv(" IP Addr : %[^\n]\r\n",_ip_buffer) && _parser.recv(" Gateway : %[^\n]\r\n",_gateway_buffer) && _parser.recv("[OK]")) ) { return false; } return true; } bool WizFi310::disconnect(void) { return _parser.send("AT+WLEAVE") && _parser.recv("[OK]"); } const char *WizFi310::getIPAddress(void) { if (!(_parser.send("AT+WSTATUS") && _parser.recv("IF/SSID/IP-Addr/Gateway/MAC/TxPower(dBm)/RSSI(-dBm)") && _parser.recv("%*[^/]/%*[^/]/%15[^/]/",_ip_buffer) && _parser.recv("[OK]")) ) { return 0; } return _ip_buffer; } const char *WizFi310::getMACAddress(void) { if (!(_parser.send("AT+MMAC=?") && _parser.recv("%[^\n]\r\n",_mac_buffer) && _parser.recv("[OK]"))) { return 0; } return _mac_buffer; } const char *WizFi310::getGateway() { return _gateway_buffer; } const char *WizFi310::getNetmask() { return _netmask_buffer; } int8_t WizFi310::getRSSI() { char rssi[3]; if (!(_parser.send("AT+WSTATUS") && _parser.recv("IF/SSID/IP-Addr/Gateway/MAC/TxPower(dBm)/RSSI(-dBm)") //&& _parser.recv("%*[^/]/%*[^/]/%*[^/]/%*[^/]/%*[^/]/%*[^/]/%[^\n]\r\n",&rssi) && _parser.recv("%*[^/]/%*[^/]/%*[^/]/%*[^/]/%*[^/]//%[^\n]\r\n",rssi) && _parser.recv("[OK]")) ) { return 0; } return atoi(rssi); } bool WizFi310::isConnected(void) { return getIPAddress() != 0; } int WizFi310::scan(WiFiAccessPoint *res, unsigned limit) { unsigned int cnt = 0; nsapi_wifi_ap_t ap; // Scan Time out : 50ms if (!(_parser.send("AT+WSCAN=,,,50") && _parser.recv("Index/SSID/BSSID/RSSI(-dBm)/MaxDataRate(Mbps)/Security/RadioBand(GHz)/Channel"))) { return NSAPI_ERROR_DEVICE_ERROR; } while (recv_ap(&ap)) { if (cnt < limit) { res[cnt] = WiFiAccessPoint(ap); } cnt++; if (limit != 0 && cnt >= limit) { break; } } return cnt; } bool WizFi310::open(const char *type, int id, const char* addr, int port) { int created_sock_id; //IDs only 0-7 if(id > 7) { return false; } if( !(_parser.send("AT+SCON=O,%s,%s,%d,,0",type,addr,port) && _parser.recv("[OK]") && _parser.recv("[CONNECT %d]",&created_sock_id))) { return false; } if( created_sock_id != id ) { close(created_sock_id); return false; } return true; } bool WizFi310::dns_lookup(const char* name, char* ip) { return (_parser.send("AT+FDNS=%s,5000", name) && _parser.recv("%[^\n]\r\n",ip) && _parser.recv("[OK]")); } bool WizFi310::send(int id, const void *data, uint32_t amount) { char str_result[20]; if(id > 8) { return false; } sprintf(str_result,"[%d,,,%d]",id,(int)amount); // Using _parser.printf because MCU can't send CR LF if( _parser.printf("AT+SSEND=%d,,,%d\r",id, (int)amount) && _parser.recv(str_result) && _parser.write((char*)data, (int)amount) >= 0 && _parser.recv("[OK]") ){ return true; } return false; } void WizFi310::_packet_handler() { int id; char ip_addr[16]; int port; uint32_t amount; // parse out the packet _parser.set_timeout(AT_CMD_PARSER_RECV_TIMEOUT); if (!_parser.recv("%d,%[^,],%d,%d}",&id, ip_addr,&port, &amount) ) { setTimeout(_timeout_ms); return; } struct packet *packet = new struct packet; if (!packet) { return; } packet->id = id; packet->len = amount; packet->next = 0; packet->data = (char*)malloc(amount); if (!(_parser.read((char*)packet->data, amount))) { free(packet); setTimeout(_timeout_ms); return; } setTimeout(_timeout_ms); *_packets_end = packet; _packets_end = &packet->next; } int32_t WizFi310::recv(int id, void *data, uint32_t amount) { while (true) { // check if any packets are ready for us for (struct packet **p = &_packets; *p; p = &(*p)->next) { if ((*p)->id == id) { struct packet *q = *p; if (q->len <= amount) { memcpy(data,q->data, q->len); if (_packets_end == &(*p)->next) { _packets_end = p; } *p = (*p)->next; uint32_t len = q->len; free(q); return len; } else { // return only partial packet memcpy(data, q->data, amount); q->len -= amount; memmove(q->data, (uint8_t*)(q->data) + amount, q->len); return amount; } } } // check for inbound packets if (!_parser.process_oob()) { return -1; } } } bool WizFi310::close(int id) { char sock_event_msg[15]; if(id > 7) { return false; } if (_parser.send("AT+SMGMT=%d", id) && _parser.recv(sock_event_msg) && _parser.recv("[OK]") ) { return true; } return false; } void WizFi310::setTimeout(uint32_t timeout_ms) { _parser.set_timeout(timeout_ms); _timeout_ms = timeout_ms; } bool WizFi310::readable() { return _serial.FileHandle::readable(); } bool WizFi310::writeable() { return _serial.FileHandle::writable(); } void WizFi310::attach(Callback<void()> func) { _serial.sigio(func); } bool WizFi310::recv_ap(nsapi_wifi_ap_t *ap) { char scan_result[100]; char sec[10]; char bssid[32]; char* idx_ptr; char* bssid_ptr; _parser.recv("%s\r\n",scan_result); if( strcmp(scan_result,"[OK]") == 0 ) { return false; } idx_ptr = strtok((char*)scan_result, "/"); // index idx_ptr = strtok( NULL, "/" ); // ssid strncpy(ap->ssid,idx_ptr,strlen(idx_ptr)); ap->ssid[strlen(idx_ptr)] = '\0'; idx_ptr = strtok( NULL, "/" ); // bssid strncpy(bssid,idx_ptr,strlen(idx_ptr)); bssid[strlen(idx_ptr)] = '\0'; idx_ptr = strtok( NULL, "/" ); // RSSI ap->rssi = atoi(idx_ptr); //idx_ptr = strtok( NULL, "/" ); // DataRate idx_ptr = strtok( NULL, "/" ); // Security strncpy(sec,idx_ptr,strlen(idx_ptr)); sec[strlen(idx_ptr)] = '\0'; ap->security = str2sec(sec); idx_ptr = strtok( NULL, "/" ); // RadioBand idx_ptr = strtok( NULL, "/" ); // Channel ap->channel = atoi(idx_ptr); // Set BSSID bssid_ptr = strtok( (char*)bssid, ":"); ap->bssid[0] = hex_str_to_int(bssid_ptr); for(int i=1; i<6; i++) { bssid_ptr = strtok( NULL, ":"); ap->bssid[i] = hex_str_to_int(bssid_ptr); } return true; } nsapi_security_t WizFi310::str2sec(const char *str_sec) { if( strcmp(str_sec,"Open") == 0 ) { return NSAPI_SECURITY_NONE; } else if( strcmp(str_sec,"WEP") == 0 ) { return NSAPI_SECURITY_WEP; } else if( strcmp(str_sec,"WPA") == 0 ) { return NSAPI_SECURITY_WPA; } else if( strcmp(str_sec,"WPA2") == 0 ) { return NSAPI_SECURITY_WPA2; } else if( strcmp(str_sec,"WPAWPA2") == 0 ) { return NSAPI_SECURITY_WPA_WPA2; } return NSAPI_SECURITY_UNKNOWN; } int WizFi310::hex_str_to_int(const char* hex_str) { int n = 0; uint32_t value = 0; int shift = 7; while (hex_str[n] != '\0' && n < 8) { if ( hex_str[n] > 0x21 && hex_str[n] < 0x40 ) { value |= (hex_str[n] & 0x0f) << (shift << 2); } else if ( (hex_str[n] >= 'a' && hex_str[n] <= 'f') || (hex_str[n] >= 'A' && hex_str[n] <= 'F') ) { value |= ((hex_str[n] & 0x0f) + 9) << (shift << 2); } else { break; } n++; shift--; } return (value >> ((shift + 1) << 2)); }