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.
Dependents: GSwifi_httpd GSwifi_websocket GSwifi_tcpclient GSwifi_tcpserver ... more
Fork of GSwifi by
GSwifi.cpp
- Committer:
- gsfan
- Date:
- 2012-08-22
- Revision:
- 9:3b819ba34c6c
- Parent:
- 8:bce9e7e51a0d
- Child:
- 10:698c5e96b5b1
File content as of revision 9:3b819ba34c6c:
/**
* 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_UART->RBR
#define _gs_putc(c) while(!(LPC_UART->LSR & (1<<5))); LPC_UART->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) : _gs(p_tx, p_rx), _buf_cmd(GS_CMD_SIZE) {
_connect = false;
_status = GSSTAT_READY;
_escape = 0;
_gs_mode = GSMODE_COMMAND;
_gs.baud(GS_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) : _gs(p_tx, p_rx), _buf_cmd(GS_CMD_SIZE) {
_connect = false;
_status = GSSTAT_READY;
_escape = 0;
_gs_mode = GSMODE_COMMAND;
_gs.baud(GS_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());
}

GainSpan Wi-Fi GS1011