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));
}