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.
OLD
GSwifi.cpp
- Committer:
- gsfan
- Date:
- 2012-09-04
- Revision:
- 11:983f4e832a3e
- Parent:
- 10:698c5e96b5b1
- Child:
- 12:63e714550791
File content as of revision 11:983f4e832a3e:
/**
* Gainspan wi-fi module library for mbed
* Copyright (c) 2012 gsfan
* Released under the MIT License: http://mbed.org/license/mit
*/
/** @file
* @brief Gainspan wi-fi module library for mbed
* GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
* module configuration: ATB=115200
*/
#include "dbg.h"
#include "mbed.h"
#include "GSwifi.h"
#ifdef GS_UART_DIRECT
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#define _gs_getc() LPC_UART1->RBR
#define _gs_putc(c) while(!(LPC_UART1->LSR & (1<<5))); LPC_UART1->THR = c
#elif defined(TARGET_LPC11U24)
#define _gs_getc() LPC_USART->RBR
#define _gs_putc(c) while(!(LPC_USART->LSR & (1<<5))); LPC_USART->THR = c
#endif
#else
#define _gs_getc() _gs.getc()
#define _gs_putc(c) _gs.putc(c)
#endif
GSwifi::GSwifi (PinName p_tx, PinName p_rx, int baud) : _gs(p_tx, p_rx), _buf_cmd(GS_CMD_SIZE) {
_connect = false;
_status = GSSTAT_READY;
_escape = 0;
_gs_mode = GSMODE_COMMAND;
_gs.baud(baud);
_gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
_rts = false;
}
GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts, int baud) : _gs(p_tx, p_rx), _buf_cmd(GS_CMD_SIZE) {
_connect = false;
_status = GSSTAT_READY;
_escape = 0;
_gs_mode = GSMODE_COMMAND;
_gs.baud(baud);
_gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
if (p_cts == p12) { // CTS input (P0_17)
LPC_UART1->MCR |= (1<<7); // CTSEN
LPC_PINCON->PINSEL1 &= ~(3 << 2);
LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS
}
if (p_rts == P0_22) { // RTS output (P0_22)
LPC_UART1->MCR |= (1<<6); // RTSEN
LPC_PINCON->PINSEL1 &= ~(3 << 12);
LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS
_rts = true;
} else {
_rts = false;
}
#elif defined(TARGET_LPC11U24)
if (p_cts == p21) { // CTS input (P0_7)
LPC_USART->MCR = (1<<7); // CTSEN
LPC_IOCON->PIO0_7 &= ~0x07;
LPC_IOCON->PIO0_7 |= 0x01; // UART CTS
}
if (p_rts == p22) { // RTS output (P0_17)
LPC_USART->MCR = (1<<6); // RTSEN
LPC_IOCON->PIO0_17 &= ~0x07;
LPC_IOCON->PIO0_17 |= 0x01; // UART RTS
_rts = true;
} else {
_rts = false;
}
#endif
}
// uart interrupt
void GSwifi::isr_recv () {
static int len, mode;
static char tmp[20];
char flg, dat;
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
flg = LPC_UART1->LSR;
#elif defined(TARGET_LPC11U24)
flg = LPC_USART->LSR;
#endif
dat = _gs_getc();
if (flg & ((1 << 7)|(1 << 3)|(1 << 4))) return;
// DBG("%02x ", dat);
switch (_gs_mode) {
case GSMODE_COMMAND: // command responce
if (_escape) {
// esc
switch (dat) {
case 'O':
DBG("ok\r\n");
_gs_ok = 1;
break;
case 'F':
DBG("failure\r\n");
_gs_failure = 1;
break;
case 'S':
DBG("GSMODE_DATA_RX\r\n");
_gs_mode = GSMODE_DATA_RX;
mode = 0;
break;
case 'u':
DBG("GSMODE_DATA_RXUDP\r\n");
_gs_mode = GSMODE_DATA_RXUDP;
mode = 0;
break;
case 'Z':
case 'H':
DBG("GSMODE_DATA_RX_BULK\r\n");
_gs_mode = GSMODE_DATA_RX_BULK;
mode = 0;
break;
case 'y':
DBG("GSMODE_DATA_RXUDP_BULK\r\n");
_gs_mode = GSMODE_DATA_RXUDP_BULK;
mode = 0;
break;
default:
DBG("unknown [ESC] %02x\r\n", dat);
break;
}
_escape = 0;
} else {
if (dat == 0x1b) {
_escape = 1;
} else
if (dat != '\r') {
// command
_buf_cmd.put(dat);
if (dat == '\n') _gs_enter ++;
}
}
break;
case GSMODE_DATA_RX:
case GSMODE_DATA_RXUDP:
if (mode == 0) {
// cid
_cid = x2i(dat);
_gs_sock[_cid].received = 0;
mode ++;
if (_gs_mode == GSMODE_DATA_RX) {
mode = 3;
}
len = 0;
} else
if (mode == 1) {
// ip
if ((dat < '0' || dat > '9') && dat != '.') {
int ip1, ip2, ip3, ip4;
tmp[len] = 0;
sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
_from.setIp(IpAddr(ip1, ip2, ip3, ip4));
mode ++;
len = 0;
break;
}
tmp[len] = dat;
len ++;
} else
if (mode == 2) {
// port
if (dat < '0' || dat > '9') {
tmp[len] = 0;
_from.setPort(atoi(tmp));
mode ++;
len = 0;
break;
}
tmp[len] = dat;
len ++;
} else
if (_escape) {
// esc
switch (dat) {
case 'E':
DBG("recv ascii %d\r\n", _cid);
_gs_sock[_cid].received = 1;
_gs_mode = GSMODE_COMMAND;
// recv interrupt
if (_gs_sock[_cid].protocol == GSPROT_HTTPGET && _gs_sock[_cid].onGsReceive != NULL) {
_gs_sock[_cid].onGsReceive(_cid, _gs_sock[_cid].data->use());
_gs_sock[_cid].received = 0;
}
break;
default:
DBG("unknown <ESC> %02x\r\n", dat);
break;
}
_escape = 0;
} else {
if (dat == 0x1b) {
_escape = 1;
} else {
// data
_gs_sock[_cid].data->put(dat);
len ++;
}
}
break;
case GSMODE_DATA_RX_BULK:
case GSMODE_DATA_RXUDP_BULK:
// DBG("%c", dat);
if (mode == 0) {
// cid
_cid = x2i(dat);
_gs_sock[_cid].received = 0;
mode ++;
if (_gs_mode == GSMODE_DATA_RX_BULK) {
mode = 3;
}
len = 0;
} else
if (mode == 1) {
// ip
if ((dat < '0' || dat > '9') && dat != '.') {
int ip1, ip2, ip3, ip4;
tmp[len] = 0;
sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
_from.setIp(IpAddr(ip1, ip2, ip3, ip4));
mode ++;
len = 0;
break;
}
tmp[len] = dat;
len ++;
} else
if (mode == 2) {
// port
if (dat < '0' || dat > '9') {
tmp[len] = 0;
_from.setPort(atoi(tmp));
mode ++;
len = 0;
break;
}
tmp[len] = dat;
len ++;
} else
if (mode == 3) {
// length
tmp[len] = dat;
len ++;
if (len >= 4) {
tmp[len] = 0;
len = atoi(tmp);
mode ++;
break;
}
} else
if (mode == 4) {
// data
if (_gs_sock[_cid].data != NULL) {
_gs_sock[_cid].data->put(dat);
}
len --;
if (len == 0) {
DBG("recv binary %d\r\n", _cid);
_gs_sock[_cid].received = 1;
_escape = 0;
_gs_mode = GSMODE_COMMAND;
// recv interrupt
if (_gs_sock[_cid].protocol == GSPROT_HTTPGET && _gs_sock[_cid].onGsReceive != NULL) {
_gs_sock[_cid].onGsReceive(_cid, _gs_sock[_cid].data->use());
_gs_sock[_cid].received = 0;
}
}
}
break;
}
}
int GSwifi::command (char *cmd, GSRESPONCE res, int timeout) {
int i;
if (! cmd) {
// dummy CR+LF
_gs.printf("\r\n");
wait_ms(100);
while (_gs.readable()) {
i = _gs_getc(); // dummy read
}
return 0;
}
_buf_cmd.clear();
_gs_ok = 0;
_gs_failure = 0;
_gs_enter = 0;
for (i = 0; i < strlen(cmd); i ++) {
_gs_putc(cmd[i]);
}
_gs_putc('\r');
_gs_putc('\n');
DBG("command: %s\r\n", cmd);
if (strlen(cmd) == 0) return 0;
wait_ms(50);
if (timeout) {
return cmdResponse(res, timeout);
} else {
return 0;
}
}
int GSwifi::cmdResponse (GSRESPONCE res, int ms) {
int i, n = 0, flg = 0;
char buf[GS_CMD_SIZE];
Timer timeout;
timeout.start();
for (;;) {
// recv response
i = 0;
while (i < sizeof(buf)) {
if (_buf_cmd.use()) {
_buf_cmd.get(&buf[i]);
if (buf[i] == '\n') {
break;
}
i ++;
}
if (timeout.read_ms() > ms) {
timeout.stop();
DBG("timeout\r\n");
return -1;
}
}
_gs_enter = 0;
if (i == 0) continue;
buf[i] = 0;
DBG("response: %s\r\n", buf);
timeout.stop();
if (strcmp(buf, "OK") == 0) {
_gs_ok = 1;
} else
if (strncmp(buf, "ERROR", 5) == 0) {
_gs_failure = 1;
}
switch(res) {
case GSRES_NORMAL:
flg = 1;
break;
case GSRES_WPS:
if (n == 0 && strncmp(buf, "SSID", 4) == 0) {
n ++;
} else
if (n == 1 && strncmp(buf, "CHANNEL", 7) == 0) {
n ++;
} else
if (n == 2 && strncmp(buf, "PASSPHRASE", 10) == 0) {
n ++;
flg = 1;
}
break;
case GSRES_CONNECT:
if (strncmp(buf, "CONNECT", 7) == 0) {
_cid = x2i(buf[8]);
flg = 1;
}
break;
case GSRES_DHCP:
if (n == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) {
n ++;
} else
if (n == 1) {
int ip1, ip2, ip3, ip4;
char *tmp = buf + 1;
sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
_ipaddr = IpAddr(ip1, ip2, ip3, ip4);
tmp = strstr(tmp, ":") + 2;
sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
_netmask = IpAddr(ip1, ip2, ip3, ip4);
tmp = strstr(tmp, ":") + 2;
sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
_gateway = IpAddr(ip1, ip2, ip3, ip4);
n ++;
flg = 1;
}
break;
case GSRES_MACADDRESS:
if (buf[2] == ':' && buf[5] == ':') {
int mac1, mac2, mac3, mac4, mac5, mac6;
sscanf(buf, "%x:%x:%x:%x:%x:%x", &mac1, &mac2, &mac3, &mac4, &mac5, &mac6);
_mac[0] = mac1;
_mac[1] = mac2;
_mac[2] = mac3;
_mac[3] = mac4;
_mac[4] = mac5;
_mac[5] = mac6;
flg = 1;
}
break;
case GSRES_DNSLOOKUP:
if (strncmp(buf, "IP:", 3) == 0) {
int ip1, ip2, ip3, ip4;
sscanf(&buf[3], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
_resolv = IpAddr(ip1, ip2, ip3, ip4);
flg = 1;
}
break;
case GSRES_HTTP:
if (buf[0] >= '0' && buf[0] <= 'F') {
_cid = x2i(buf[0]);
flg = 1;
}
break;
case GSRES_RSSI:
if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) {
_rssi = atoi(buf);
flg = 1;
}
break;
case GSRES_TIME:
if (buf[0] >= '0' && buf[0] <= '9') {
int year, month, day, hour, min, sec;
struct tm t;
sscanf(buf, "%d/%d/%d,%d:%d:%d", &day, &month, &year, &hour, &min, &sec);
t.tm_sec = sec;
t.tm_min = min;
t.tm_hour = hour;
t.tm_mday = day;
t.tm_mon = month - 1;
t.tm_year = year - 1900;
_time = mktime(&t);
flg = 1;
}
break;
}
if ((flg && _gs_ok) || _gs_failure) break;
timeout.reset();
timeout.start();
}
if (_gs_failure || flg == 0) {
return -1;
} else {
return 0;
}
}
int GSwifi::connect (GSSECURITY sec, char *ssid, char *pass, int dhcp) {
int r;
char cmd[GS_CMD_SIZE];
if (_connect || _status != GSSTAT_READY) return -1;
command(NULL, GSRES_NORMAL);
if (command("ATE0", GSRES_NORMAL)) return -1;
if (_rts) {
command("AT&K0", GSRES_NORMAL);
command("AT&R1", GSRES_NORMAL);
}
command("AT+NMAC=?", GSRES_MACADDRESS);
#ifdef GS_BULK
command("AT+BDATA=1", GSRES_NORMAL);
#endif
disconnect();
command("AT+WM=0", GSRES_NORMAL); // infrastructure
wait_ms(100);
if (dhcp) {
command("AT+NDHCP=1", GSRES_NORMAL);
} else {
command("AT+NDHCP=0", GSRES_NORMAL);
}
switch (sec) {
case GSSEC_NONE:
command("AT+WAUTH=0", GSRES_NORMAL);
sprintf(cmd, "AT+WA=%s", ssid);
r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
break;
case GSSEC_OPEN:
case GSSEC_WEP:
sprintf(cmd, "AT+WAUTH=%d", sec);
command(cmd, GSRES_NORMAL);
sprintf(cmd, "AT+WWEP1=%s", pass);
command(cmd, GSRES_NORMAL);
wait_ms(100);
sprintf(cmd, "AT+WA=%s", ssid);
r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
break;
case GSSEC_WPA_PSK:
case GSSEC_WPA2_PSK:
command("AT+WAUTH=0", GSRES_NORMAL);
// sprintf(cmd, "AT+WWPA=%s", pass);
// command(cmd, GSRES_NORMAL);
sprintf(cmd, "AT+WPAPSK=%s,%s", ssid, pass);
command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
wait_ms(100);
sprintf(cmd, "AT+WA=%s", ssid);
r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
break;
case GSSEC_WPS_BUTTON:
command("AT+WAUTH=0", GSRES_NORMAL);
r = command("AT+WWPS=1", GSRES_WPS, GS_TIMEOUT2);
if (r) break;
if (dhcp) {
r = command("AT+NDHCP=1", GSRES_DHCP, GS_TIMEOUT2);
}
break;
default:
DBG("Can't use security\r\n");
r = -1;
break;
}
if (r == 0) _connect = true;
return r;
}
int GSwifi::adhock (GSSECURITY sec, char *ssid, char *pass, IpAddr ipaddr, IpAddr netmask) {
int r;
char cmd[GS_CMD_SIZE];
if (_connect || _status != GSSTAT_READY) return -1;
command(NULL, GSRES_NORMAL);
if (command("ATE0", GSRES_NORMAL)) return -1;
if (_rts) {
command("AT&K0", GSRES_NORMAL);
command("AT&R1", GSRES_NORMAL);
}
disconnect();
command("AT+NMAC=?", GSRES_MACADDRESS);
#ifdef GS_BULK
command("AT+BDATA=1", GSRES_NORMAL);
#endif
command("AT+WM=1", GSRES_NORMAL); // adhock
wait_ms(100);
command("AT+NDHCP=0", GSRES_NORMAL);
setAddress(ipaddr, netmask, ipaddr, ipaddr);
switch (sec) {
case GSSEC_NONE:
command("AT+WAUTH=0", GSRES_NORMAL);
sprintf(cmd, "AT+WA=%s", ssid);
r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
break;
case GSSEC_OPEN:
case GSSEC_WEP:
sprintf(cmd, "AT+WAUTH=%d", sec);
command(cmd, GSRES_NORMAL);
sprintf(cmd, "AT+WWEP1=%s", pass);
command(cmd, GSRES_NORMAL);
wait_ms(100);
sprintf(cmd, "AT+WA=%s", ssid);
r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
break;
default:
DBG("Can't use security\r\n");
r = -1;
break;
}
if (r == 0) _connect = true;
return r;
}
int GSwifi::limitedap (GSSECURITY sec, char *ssid, char *pass, IpAddr ipaddr, IpAddr netmask) {
int r;
char cmd[GS_CMD_SIZE];
if (_connect || _status != GSSTAT_READY) return -1;
command(NULL, GSRES_NORMAL);
if (command("ATE0", GSRES_NORMAL)) return -1;
if (_rts) {
command("AT&K0", GSRES_NORMAL);
command("AT&R1", GSRES_NORMAL);
}
disconnect();
command("AT+NMAC=?", GSRES_MACADDRESS);
#ifdef GS_BULK
command("AT+BDATA=1", GSRES_NORMAL);
#endif
command("AT+WM=2", GSRES_NORMAL); // limited ap
wait_ms(1000);
command("AT+NDHCP=0", GSRES_NORMAL);
setAddress(ipaddr, netmask, ipaddr, ipaddr);
if (command("AT+DHCPSRVR=1", GSRES_NORMAL)) return -1;
if (command("AT+DNS=1,setup", GSRES_NORMAL)) return -1;
switch (sec) {
case GSSEC_NONE:
command("AT+WAUTH=0", GSRES_NORMAL);
sprintf(cmd, "AT+WA=%s", ssid);
r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
break;
case GSSEC_OPEN:
case GSSEC_WEP:
sprintf(cmd, "AT+WAUTH=%d", sec);
command(cmd, GSRES_NORMAL);
sprintf(cmd, "AT+WWEP1=%s", pass);
command(cmd, GSRES_NORMAL);
wait_ms(100);
sprintf(cmd, "AT+WA=%s", ssid);
r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
break;
default:
DBG("Can't use security\r\n");
r = -1;
break;
}
if (r == 0) _connect = true;
return r;
}
int GSwifi::disconnect () {
int i;
_connect = false;
for (i = 0; i < 16; i ++) {
_gs_sock[i].connect = false;
}
command("AT+NCLOSEALL", GSRES_NORMAL);
command("AT+WD", GSRES_NORMAL);
command("AT+NDHCP=0", GSRES_NORMAL);
wait_ms(100);
return 0;
}
int GSwifi::setAddress () {
if (command("AT+NDHCP=1", GSRES_DHCP), GS_TIMEOUT2) return -1;
if (_ipaddr.isNull()) return -1;
return 0;
}
int GSwifi::setAddress (IpAddr ipaddr, IpAddr netmask, IpAddr gateway, IpAddr nameserver) {
int r;
char cmd[GS_CMD_SIZE];
command("AT+NDHCP=0", GSRES_NORMAL);
wait_ms(100);
sprintf(cmd, "AT+NSET=%d.%d.%d.%d,%d.%d.%d.%d,%d.%d.%d.%d",
ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3],
netmask[0], netmask[1], netmask[2], netmask[3],
gateway[0], gateway[1], gateway[2], gateway[3]);
r = command(cmd, GSRES_NORMAL);
if (r) return -1;
_ipaddr = ipaddr;
_netmask = netmask;
_gateway = gateway;
if (ipaddr != nameserver) {
sprintf(cmd, "AT+DNSSET=%d.%d.%d.%d",
nameserver[0], nameserver[1], nameserver[2], nameserver[3]);
r = command(cmd, GSRES_NORMAL);
}
return r;
}
int GSwifi::getAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) {
ipaddr = _ipaddr;
netmask = _netmask;
gateway = _gateway;
nameserver = _nameserver;
return 0;
}
int GSwifi::getHostByName (const char* name, IpAddr &addr) {
char cmd[GS_CMD_SIZE];
if (! _connect || _status != GSSTAT_READY) return -1;
sprintf(cmd, "AT+DNSLOOKUP=%s", name);
if (command(cmd, GSRES_DNSLOOKUP)) return -1;
addr = _resolv;
return 0;
}
int GSwifi::getHostByName (Host &host) {
char cmd[GS_CMD_SIZE];
if (! _connect || _status != GSSTAT_READY) return -1;
sprintf(cmd, "AT+DNSLOOKUP=%s", host.getName());
if (command(cmd, GSRES_DNSLOOKUP)) return -1;
host.setIp(_resolv);
return 0;
}
int GSwifi::setRFPower (int power) {
char cmd[GS_CMD_SIZE];
if (power < 0 || power > 7) return -1;
sprintf(cmd, "AT+WP=%d", power);
return command(cmd, GSRES_NORMAL);
}
int GSwifi::powerSave (int active, int save) {
char cmd[GS_CMD_SIZE];
if (_status != GSSTAT_READY) return -1;
sprintf(cmd, "AT+WRXACTIVE=%d", active);
command(cmd, GSRES_NORMAL);
sprintf(cmd, "AT+WRXPS=%d", save);
return command(cmd, GSRES_NORMAL);
}
int GSwifi::standby (int msec) {
char cmd[GS_CMD_SIZE];
if (_status != GSSTAT_READY && _status != GSSTAT_WAKEUP) return -1;
if (_status != GSSTAT_WAKEUP) {
command("AT+WRXACTIVE=0", GSRES_NORMAL);
command("AT+STORENWCONN", GSRES_NORMAL);
} else {
command("ATE0", GSRES_NORMAL);
if (_rts) {
command("AT&K0", GSRES_NORMAL);
command("AT&R1", GSRES_NORMAL);
}
}
_status = GSSTAT_STANDBY;
sprintf(cmd, "AT+PSSTBY=%d,0,0,0", msec); // go standby
return command(cmd, GSRES_NORMAL, 0);
}
int GSwifi::wakeup () {
if (_status == GSSTAT_WAKEUP) {
_status = GSSTAT_READY;
command("ATE0", GSRES_NORMAL);
if (_rts) {
command("AT&K0", GSRES_NORMAL);
command("AT&R1", GSRES_NORMAL);
}
#ifdef GS_BULK
command("AT+BDATA=1", GSRES_NORMAL);
#endif
command("AT+RESTORENWCONN", GSRES_NORMAL);
wait_ms(100);
return command("AT+WRXACTIVE=1", GSRES_NORMAL);
} else
if (_status == GSSTAT_DEEPSLEEP) {
_status = GSSTAT_READY;
return command("AT", GSRES_NORMAL);
}
return -1;
}
int GSwifi::deepSleep () {
if (_status != GSSTAT_READY) return -1;
_status = GSSTAT_DEEPSLEEP;
return command("AT+PSDPSLEEP", GSRES_NORMAL, 0); // go deep sleep
}
bool GSwifi::isConnected () {
return _connect;
}
GSSTATUS GSwifi::getStatus () {
return _status;
}
int GSwifi::getRssi () {
if (command("AT+WRSSI=?", GSRES_RSSI)) {
return 0;
}
return _rssi;
}
int GSwifi::ntpdate (Host host, int sec) {
char cmd[GS_CMD_SIZE];
if (! _connect || _status != GSSTAT_READY) return -1;
if (host.getIp().isNull()) {
if (getHostByName(host)) {
if (getHostByName(host)) return -1;
}
}
if (sec) {
sprintf(cmd, "AT+NTIMESYNC=1,%d.%d.%d.%d,%d,1,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3],
GS_TIMEOUT / 1000, sec);
} else {
sprintf(cmd, "AT+NTIMESYNC=1,%d.%d.%d.%d,%d,0", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3],
GS_TIMEOUT / 1000);
}
return command(cmd, GSRES_NORMAL);
}
int GSwifi::setTime (time_t time) {
char cmd[GS_CMD_SIZE];
struct tm *t;
if (_status != GSSTAT_READY) return -1;
t = localtime(&time);
sprintf(cmd, "AT+SETTIME=%d/%d/%d,%d:%d:%d", t->tm_mday, t->tm_mon + 1, t->tm_year + 1900, t->tm_hour, t->tm_min, t->tm_sec);
return command(cmd, GSRES_NORMAL);
}
time_t GSwifi::getTime () {
if (command("AT+GETTIME=?", GSRES_TIME)) {
return 0;
}
return _time;
}
int GSwifi::gpioOut (int port, int out) {
char cmd[GS_CMD_SIZE];
if (_status != GSSTAT_READY) return -1;
sprintf(cmd, "AT+DGPIO=%d,%d", port, out);
return command(cmd, GSRES_NORMAL);
}
void GSwifi::poll() {
int i;
if (_gs_enter) {
// received "\n"
int i;
char buf[GS_CMD_SIZE];
wait_ms(10);
_gs_enter --;
i = 0;
while (_buf_cmd.use() && i < sizeof(buf)) {
_buf_cmd.get(&buf[i]);
if (buf[i] == '\n') {
if (i == 0) continue;
break;
}
i ++;
}
buf[i] = 0;
DBG("poll: %s\r\n", buf);
if (strncmp(buf, "CONNECT", 7) == 0 && buf[8] >= '0' && buf[8] <= 'F') {
i = x2i(buf[8]);
if (_gs_sock[i].type == GSTYPE_SERVER) {
int acid, ip1, ip2, ip3, ip4;
char *tmp = buf + 12;
acid = x2i(buf[10]);
newSock(acid, _gs_sock[i].type, _gs_sock[i].protocol, _gs_sock[i].onGsReceive);
_gs_sock[acid].lcid = i;
sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
_gs_sock[acid].host.setIp(IpAddr(ip1, ip2, ip3, ip4));
tmp = strstr(tmp, " ") + 1;
_gs_sock[acid].host.setPort(atoi(tmp));
}
} else
if (strncmp(buf, "DISCONNECT", 10) == 0) {
_gs_sock[x2i(buf[11])].connect = false;
} else
if (strncmp(buf, "DISASSOCIATED", 13) == 0 ||
strncmp(buf, "Disassociated", 13) == 0 ||
strncmp(buf, "UnExpected", 10) == 0) {
_connect = false;
for (i = 0; i < 16; i ++) {
_gs_sock[i].connect = false;
}
} else
if (strncmp(buf, "Out of StandBy-Timer", 20) == 0 ||
strncmp(buf, "Out of StandBy-Alarm", 20) == 0) {
if (_status == GSSTAT_STANDBY) {
_status = GSSTAT_WAKEUP;
}
} else
if (strncmp(buf, "Out of Deep Sleep", 17) == 0 ) {
if (_status == GSSTAT_DEEPSLEEP) {
_status = GSSTAT_READY;
}
} else
if (strncmp(buf, "Out of", 6) == 0) {
}
DBG("status: %d\r\n", _status);
}
for (i = 0; i < 16; i ++) {
// if (_gs_sock[i].connect && _gs_sock[i].received) {
if (_gs_sock[i].received && _gs_sock[i].data->use()) {
// recv interrupt
_gs_sock[i].received = 0;
if (_gs_sock[i].onGsReceive != NULL)
_gs_sock[i].onGsReceive(i, _gs_sock[i].data->use());
}
}
}
void GSwifi::newSock (int cid, GSTYPE type, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
_gs_sock[cid].type = type;
_gs_sock[cid].protocol = pro;
_gs_sock[cid].connect = true;
if (_gs_sock[cid].data == NULL) {
_gs_sock[cid].data = new RingBuffer(GS_DATA_SIZE);
} else {
_gs_sock[cid].data->clear();
}
_gs_sock[cid].lcid = 0;
_gs_sock[cid].received = 0;
_gs_sock[cid].onGsReceive = ponGsReceive;
}
int GSwifi::open (Host &host, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
char cmd[GS_CMD_SIZE];
if (! _connect || _status != GSSTAT_READY) return -1;
if (host.getIp().isNull() || host.getPort() == 0) {
return -1;
}
if (pro == GSPROT_UDP) {
sprintf(cmd, "AT+NCUDP=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
} else {
sprintf(cmd, "AT+NCTCP=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
}
if (command(cmd, GSRES_CONNECT)) return -1;
newSock(_cid, GSTYPE_CLIENT, pro, ponGsReceive);
return _cid;
}
int GSwifi::listen (int port, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
char cmd[GS_CMD_SIZE];
if (! _connect || _status != GSSTAT_READY) return -1;
if (port == 0) {
return -1;
}
if (pro == GSPROT_UDP) {
sprintf(cmd, "AT+NSUDP=%d", port);
} else {
sprintf(cmd, "AT+NSTCP=%d", port);
}
if (command(cmd, GSRES_CONNECT)) return -1;
newSock(_cid, GSTYPE_SERVER, pro, ponGsReceive);
return _cid;
}
int GSwifi::close (int cid) {
char cmd[GS_CMD_SIZE];
if (! _gs_sock[cid].connect) return -1;
_gs_sock[cid].connect = false;
delete _gs_sock[cid].data;
_gs_sock[cid].data = NULL;
sprintf(cmd, "AT+NCLOSE=%X", cid);
return command(cmd, GSRES_NORMAL);
}
int GSwifi::send (int cid, char *buf, int len) {
int i;
Timer timeout;
if (! _gs_sock[cid].connect) return -1;
if ((_gs_sock[cid].protocol == GSPROT_TCP) ||
(_gs_sock[cid].protocol == GSPROT_UDP && _gs_sock[cid].type == GSTYPE_CLIENT)) {
// TCP Client, TCP Server, UDP Client
_gs_ok = 0;
_gs_failure = 0;
#ifdef GS_BULK
_gs.printf("\x1bZ%X%04d", cid, len);
for (i = 0; i < len; i ++) {
_gs_putc(buf[i]);
DBG("%c", buf[i]);
}
#else
_gs.printf("\x1bS%X", cid);
for (i = 0; i < len; i ++) {
if (buf[i] >= 0x20 && buf[i] < 0x7f) {
_gs_putc(buf[i]);
DBG("%c", buf[i]);
}
}
_gs_putc(0x1b);
_gs_putc('E');
#endif
} else {
return -1;
}
timeout.start();
while (!_gs_ok && !_gs_failure && timeout.read_ms() < GS_TIMEOUT);
return _gs_ok == 1 ? 0 : -1;
}
int GSwifi::send (int cid, char *buf, int len, Host &host) {
int i;
Timer timeout;
if (! _gs_sock[cid].connect) return -1;
if ((_gs_sock[cid].protocol == GSPROT_UDP && _gs_sock[cid].type == GSTYPE_SERVER)) {
// UDP Server
_gs_ok = 0;
_gs_failure = 0;
#ifdef GS_BULK
_gs.printf("\x1bY%X", cid);
_gs.printf("%d.%d.%d.%d:%d:", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
_gs.printf("%04d", len);
for (i = 0; i < len; i ++) {
_gs_putc(buf[i]);
DBG("%c", buf[i]);
}
#else
_gs.printf("\x1bU%X", cid);
_gs.printf("%d.%d.%d.%d:%d:", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
for (i = 0; i < len; i ++) {
if (buf[i] >= 0x20 && buf[i] < 0x7f) {
_gs_putc(buf[i]);
DBG("%c", buf[i]);
}
}
_gs_putc(0x1b);
_gs_putc('E');
#endif
} else {
return -1;
}
timeout.start();
while (!_gs_ok && !_gs_failure && timeout.read_ms() < GS_TIMEOUT);
return _gs_ok == 1 ? 0 : -1;
}
int GSwifi::recv (int cid, char *buf, int len) {
int r;
Timer timeout;
if (_gs_sock[cid].data == NULL) return 0;
timeout.start();
while (_gs_sock[cid].data->use() == 0) {
if (timeout.read_ms() > GS_TIMEOUT) return 0;
}
timeout.stop();
r = _gs_sock[cid].data->get(buf, len);
return r;
}
int GSwifi::recv (int cid, char *buf, int len, Host &host) {
int r;
Timer timeout;
if (_gs_sock[cid].data == NULL) return 0;
timeout.start();
while (_gs_sock[cid].data->use() == 0) {
if (timeout.read_ms() > GS_TIMEOUT) return 0;
}
timeout.stop();
r = _gs_sock[cid].data->get(buf, len);
host = _from;
return r;
}
bool GSwifi::isConnected (int cid) {
return _gs_sock[cid].connect;
}
int GSwifi::httpGet (Host &host, char *uri, int ssl, onGsReceiveFunc ponGsReceive) {
char cmd[GS_CMD_SIZE];
if (! _connect || _status != GSSTAT_READY) return -1;
if (host.getIp().isNull()) {
if (getHostByName(host)) {
if (getHostByName(host)) return -1;
}
}
if (host.getPort() == 0) {
if (ssl) {
host.setPort(443);
} else {
host.setPort(80);
}
}
command("AT+HTTPCONF=3,close", GSRES_NORMAL); // Connection:
sprintf(cmd, "AT+HTTPCONF=11,%s", host.getName()); // Host:
command(cmd, GSRES_NORMAL);
sprintf(cmd, "AT+HTTPOPEN=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
if (ssl) {
strcat(cmd, ",1");
}
if (command(cmd, GSRES_HTTP)) return -1;
newSock(_cid, GSTYPE_CLIENT, GSPROT_HTTPGET, ponGsReceive);
sprintf(cmd, "AT+HTTPSEND=%d,1,%d,%s", _cid, GS_TIMEOUT / 1000, uri); // Get:
command(cmd, GSRES_NORMAL);
return _cid;
}
int GSwifi::certAdd (char *name, char *cert, int len) {
int i;
char cmd[GS_CMD_SIZE];
if (! _connect || _status != GSSTAT_READY) return -1;
sprintf(cmd, "AT+TCERTADD=%s,1,%d,1", name, len); // Hex, ram
command(cmd, GSRES_NORMAL);
_gs_putc(0x1b);
_gs_putc('W');
for (i = 0; i < len; i ++) {
_gs_putc(cert[i]);
}
return cmdResponse(GSRES_NORMAL, GS_TIMEOUT);
}
int GSwifi::x2i (char c) {
if (c >= '0' && c <= '9') {
return c - '0';
} else
if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
} else
if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
return 0;
}
char GSwifi::i2x (int i) {
if (i >= 0 && i <= 9) {
return i + '0';
} else
if (i >= 10 && i <= 15) {
return i - 10 + 'A';
}
return 0;
}
// for test
void GSwifi::test () {
/*
command(NULL, GSRES_NORMAL);
wait_ms(100);
command("AT+NCLOSEALL", GSRES_NORMAL);
_connect = true;
*/
command("AT+WRXACTIVE=1", GSRES_NORMAL);
}
int GSwifi::getc() {
char c;
if (_buf_cmd.use()) {
_buf_cmd.get(&c);
}
/*
} else
if (_gs_sock[0].data != NULL) {
_gs_sock[0].data->get(&c);
}
*/
return c;
}
void GSwifi::putc(char c) {
_gs_putc(c);
}
int GSwifi::readable() {
return _buf_cmd.use();
// return _buf_cmd.use() || (_gs_sock[0].data != NULL && _gs_sock[0].data->use());
}