wifi test
Dependencies: X_NUCLEO_IKS01A2 mbed-http
Diff: easy-connect/wizfi310-driver/WizFi310/WizFi310.cpp
- Revision:
- 0:24d3eb812fd4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easy-connect/wizfi310-driver/WizFi310/WizFi310.cpp Wed Sep 05 14:28:24 2018 +0000
@@ -0,0 +1,506 @@
+/*
+ * 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));
+}
+