GainSpan Wi-Fi library see: http://mbed.org/users/gsfan/notebook/gainspan_wifi/
Dependents: GSwifi_httpd GSwifi_websocket GSwifi_tcpclient GSwifi_tcpserver ... more
Fork of GSwifi by
GainSpan Wi-Fi library
The GS1011 is an ultra low power 802.11b wireless module from GainSpan.
see: http://mbed.org/users/gsfan/notebook/gainspan_wifi/
ゲインスパン Wi-Fi モジュール ライブラリ
ゲインスパン社の低電力 Wi-Fiモジュール(無線LAN) GS1011 シリーズ用のライブラリです。
解説: http://mbed.org/users/gsfan/notebook/gainspan_wifi/
GSwifi.cpp
- Committer:
- gsfan
- Date:
- 2013-03-29
- Revision:
- 34:f5f40c92af00
- Parent:
- 33:b5a5a1e6325f
- Child:
- 35:515ec79792d3
File content as of revision 34:f5f40c92af00:
/* Copyright (C) 2013 gsfan, MIT License * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software * and associated documentation files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** @file * @brief Gainspan wi-fi module library for mbed * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc. */ #include "mbed.h" #include "GSwifi.h" GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_reset, PinName p_alarm, int baud) : _gs(p_tx, p_rx), _reset(p_reset), _buf_cmd(GS_CMD_SIZE) { if (p_alarm != NC) { _alarm = new DigitalInOut(p_alarm); _alarm->output(); // low _alarm->write(0); } else { _alarm = NULL; } _reset.output(); // low _reset = 0; _gs.baud(baud); _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq); _rts = false; wait_ms(500); reset(); } GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts, PinName p_reset, PinName p_alarm, int baud) : _gs(p_tx, p_rx), _reset(p_reset), _buf_cmd(GS_CMD_SIZE) { if (p_alarm != NC) { _alarm = new DigitalInOut(p_alarm); _alarm->output(); // low _alarm->write(0); } else { _alarm = NULL; } _reset.output(); // low _reset = 0; _gs.baud(baud); _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq); _rts = false; #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; } #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; } #endif wait_ms(500); reset(); } void GSwifi::reset () { if (_alarm != NULL) { _alarm->output(); // low _alarm->write(0); wait_ms(10); _alarm->input(); // high _alarm->mode(PullUp); wait_ms(10); } _reset.output(); // low _reset = 0; _connect = false; _status = GSSTAT_READY; _escape = 0; resetResponse(GSRES_NONE); _gs_mode = GSMODE_COMMAND; _ssid = NULL; _pass = NULL; _reconnect = 0; _reconnect_count = 0; _buf_cmd.flush(); wait_ms(100); _reset.input(); // high _reset.mode(PullUp); wait_ms(500); } // uart interrupt void GSwifi::isr_recv () { static int len, mode; static char tmp[20]; char dat; dat = _gs_getc(); #ifdef DEBUG_VIEW if (dat >= 0x20 && dat < 0x7f) { DBG("%c_", dat); } else { DBG("%02x_", dat); } #endif switch (_gs_mode) { case GSMODE_COMMAND: // command responce if (_escape) { // esc switch (dat) { case 'O': DBG("ok\r\n"); _gs_ok = true; break; case 'F': DBG("failure\r\n"); _gs_failure = true; 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 == '\n') { // end of line parseResponse(); } else if (dat != '\r') { // command _buf_cmd.queue(dat); } } break; case GSMODE_DATA_RX: case GSMODE_DATA_RXUDP: if (mode == 0) { // cid _cid = x2i(dat); _gs_sock[_cid].received = false; 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 = true; _gs_mode = GSMODE_COMMAND; if (_gs_sock[_cid].protocol == GSPROT_HTTPGET) { // recv interrupt if (_gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available()) == 0) _gs_sock[_cid].received = false; } break; default: DBG("unknown <ESC> %02x\r\n", dat); break; } _escape = 0; } else { if (dat == 0x1b) { _escape = 1; } else { // data _gs_sock[_cid].data->queue(dat); len ++; if (len < GS_DATA_SIZE && _gs_sock[_cid].data->isFull()) { // buffer full // recv interrupt _gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available()); } } } break; case GSMODE_DATA_RX_BULK: case GSMODE_DATA_RXUDP_BULK: if (mode == 0) { // cid _cid = x2i(dat); _gs_sock[_cid].received = false; 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->queue(dat); } len --; if (len && _gs_sock[_cid].data->isFull()) { // buffer full // recv interrupt _gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available()); } if (len == 0) { DBG("recv binary %d\r\n", _cid); _gs_sock[_cid].received = true; _escape = 0; _gs_mode = GSMODE_COMMAND; if (_gs_sock[_cid].protocol == GSPROT_HTTPGET) { // recv interrupt if (_gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available()) == 0) _gs_sock[_cid].received = false; } } } break; } } int GSwifi::command (const char *cmd, GSRESPONCE res, int timeout) { int i; if (cmd == NULL) { // dummy CR+LF _gs.printf("\r\n"); wait_ms(100); _buf_cmd.flush(); return 0; } resetResponse(res); 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; return waitResponse(timeout); } void GSwifi::resetResponse (GSRESPONCE res) { _gs_ok = false; _gs_failure = false; _gs_flg = 0; _gs_res = res; } int GSwifi::waitResponse (int ms) { Timer timeout; if (! ms) return 0; timeout.start(); for (;;) { if (timeout.read_ms() > ms) { DBG("timeout\r\n"); break; } if (_gs_ok && (_gs_flg == -1 || _gs_res == GSRES_NONE)) { timeout.stop(); _gs_res = GSRES_NONE; return 0; } if (_gs_failure) break; } timeout.stop(); _gs_res = GSRES_NONE; return -1; } int GSwifi::connect (GSSECURITY sec, const char *ssid, const char *pass, int dhcp, int reconnect) { 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&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 && sec != GSSEC_WPS_BUTTON) { command("AT+NDHCP=1", GSRES_NORMAL); } else { command("AT+NDHCP=0", GSRES_NORMAL); } switch (sec) { case GSSEC_NONE: case GSSEC_OPEN: case GSSEC_WEP: sprintf(cmd, "AT+WAUTH=%d", sec); command(cmd, GSRES_NORMAL); if (sec != GSSEC_NONE) { 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); if (r) { DBG("retry\r\n"); wait_ms(1000); r = command(cmd, GSRES_DHCP, GS_TIMEOUT2); } break; case GSSEC_WPA_PSK: case GSSEC_WPA_ENT: case GSSEC_WPA2_PSK: case GSSEC_WPA2_ENT: command("AT+WAUTH=0", GSRES_NORMAL); // sprintf(cmd, "AT+WWPA=%s", pass); 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); if (r) { DBG("retry\r\n"); wait_ms(1000); 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; case GSSEC_WPS_PIN: command("AT+WAUTH=0", GSRES_NORMAL); sprintf(cmd, "AT+WWPS=2,%s", pass); r = command(cmd, 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 && !dhcp) { sprintf(cmd, "AT+DNSSET=%d.%d.%d.%d", _gateway[0], _gateway[1], _gateway[2], _gateway[3]); command(cmd, GSRES_NORMAL); } if (r == 0) { _connect = true; _reconnect = reconnect; _reconnect_count = 0; _sec = sec; if (ssid) { if (!_ssid) _ssid = new char[strlen(ssid) + 1]; strcpy(_ssid, ssid); } if (pass) { if (!_pass) _pass = new char[strlen(pass) + 1]; strcpy(_pass, pass); } } return r; } int GSwifi::adhock (GSSECURITY sec, const char *ssid, const 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&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: case GSSEC_OPEN: case GSSEC_WEP: sprintf(cmd, "AT+WAUTH=%d", sec); command(cmd, GSRES_NORMAL); if (sec != GSSEC_NONE) { 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, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask, char *dns) { 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&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(100); command("AT+NDHCP=0", GSRES_NORMAL); setAddress(ipaddr, netmask, ipaddr, ipaddr); if (command("AT+DHCPSRVR=1", GSRES_NORMAL)) return -1; if (dns) { sprintf(cmd, "AT+DNS=1,%s", dns); } else { strcpy(cmd, "AT+DNS=1," GS_DNSNAME); } if (command(cmd, GSRES_NORMAL)) return -1; switch (sec) { case GSSEC_NONE: case GSSEC_OPEN: case GSSEC_WEP: sprintf(cmd, "AT+WAUTH=%d", sec); command(cmd, GSRES_NORMAL); if (sec != GSSEC_NONE) { 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::reconnect () { int r; char cmd[GS_CMD_SIZE]; if (_connect || _status != GSSTAT_READY) return -1; if (!_ssid) return -1; switch (_sec) { case GSSEC_WPS_BUTTON: case GSSEC_WPS_PIN: sprintf(cmd, "AT+WPAPSK=%s,%s", _ssid, _pass); command(cmd, GSRES_NORMAL, GS_TIMEOUT2); wait_ms(100); case GSSEC_NONE: case GSSEC_OPEN: case GSSEC_WEP: case GSSEC_WPA_PSK: case GSSEC_WPA_ENT: case GSSEC_WPA2_PSK: case GSSEC_WPA2_ENT: sprintf(cmd, "AT+WA=%s", _ssid); r = command(cmd, GSRES_DHCP, GS_TIMEOUT2); break; default: DBG("Can't use security\r\n"); r = -1; break; } return r; } 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::getMacAddress (char *mac) { memcpy(mac, _mac, 6); 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) { int i; char cmd[GS_CMD_SIZE]; if (_status != GSSTAT_READY && _status != GSSTAT_WAKEUP) return -1; if (_status == GSSTAT_READY) { command("AT+WRXACTIVE=0", GSRES_NORMAL); command("AT+STORENWCONN", GSRES_NORMAL); } else { command("ATE0", GSRES_NORMAL); if (_rts) { command("AT&R1", GSRES_NORMAL); } } for (i = 0; i < 16; i ++) { _gs_sock[i].connect = false; } _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_STANDBY && _alarm != NULL) { Timer timeout; _alarm->output(); // low _alarm->write(0); timeout.start(); while (_status != GSSTAT_WAKEUP && timeout.read() < GS_TIMEOUT) { poll(); } timeout.stop(); _alarm->input(); // high _alarm->mode(PullUp); } if (_status == GSSTAT_WAKEUP) { _status = GSSTAT_READY; command("ATE0", GSRES_NORMAL); if (_rts) { 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; } GSwifi::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::parseResponse () { int i; char buf[GS_CMD_SIZE]; while (! _buf_cmd.isEmpty()) { // received "\n" i = 0; while ((! _buf_cmd.isEmpty()) && i < sizeof(buf)) { _buf_cmd.dequeue(&buf[i]); if (buf[i] == '\n') { break; } i ++; } if (i == 0) continue; buf[i] = 0; DBG("parseResponse: %s\r\n", buf); parseCmdResponse(buf); if (strncmp(buf, "CONNECT ", 8) == 0 && buf[8] >= '0' && buf[8] <= 'F' && buf[9] != 0) { int cid = x2i(buf[8]); if (_gs_sock[cid].type == GSTYPE_SERVER) { // fork (server socket) int acid, ip1, ip2, ip3, ip4; char *tmp = buf + 12; acid = x2i(buf[10]); DBG("connect %d -> %d\r\n", cid, acid); newSock(acid, _gs_sock[cid].type, _gs_sock[cid].protocol); _gs_sock[acid].onGsReceive = _gs_sock[cid].onGsReceive; _gs_sock[acid].lcid = cid; 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)); _gs_sock[acid].onGsReceive.call(acid, 0); // event connected } } else if (strncmp(buf, "DISCONNECT ", 11) == 0) { int cid = x2i(buf[11]); DBG("disconnect %d\r\n", cid); _gs_sock[cid].connect = false; _gs_sock[cid].onGsReceive.call(cid, -1); // event disconnected } else if (strncmp(buf, "DISASSOCIATED", 13) == 0 || strncmp(buf, "Disassociated", 13) == 0 || strncmp(buf, "Disassociation Event", 20) == 0 || strncmp(buf, "UnExpected Warm Boot", 20) == 0 || strncmp(buf, "APP Reset-APP SW Reset", 22) == 0 || strncmp(buf, "APP Reset-Wlan Except", 21) == 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; // } } DBG("status: %d\r\n", _status); } } void GSwifi::parseCmdResponse (char *buf) { if (_gs_res == GSRES_NONE) return; DBG("cmd\r\n"); if (strcmp(buf, "OK") == 0) { _gs_ok = true; } else if (strncmp(buf, "ERROR", 5) == 0) { _gs_failure = true; } switch(_gs_res) { case GSRES_NORMAL: _gs_flg = -1; break; case GSRES_WPS: if (_gs_flg == 0 && strncmp(buf, "SSID=", 5) == 0) { if (!_ssid) _ssid = new char[strlen(&buf[5]) + 1]; strcpy(_ssid, &buf[5]); _gs_flg ++; } else if (_gs_flg == 1 && strncmp(buf, "CHANNEL=", 8) == 0) { _gs_flg ++; } else if (_gs_flg == 2 && strncmp(buf, "PASSPHRASE=", 11) == 0) { if (!_pass) _pass = new char[strlen(&buf[11]) + 1]; strcpy(_pass, &buf[11]); _gs_flg = -1; } break; case GSRES_CONNECT: if (strncmp(buf, "CONNECT ", 8) == 0 && buf[9] == 0) { _cid = x2i(buf[8]); _gs_flg = -1; } break; case GSRES_DHCP: if (_gs_flg == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) { _gs_flg ++; } else if (_gs_flg == 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); _gs_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; _gs_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); _gs_flg = -1; } break; case GSRES_HTTP: if (buf[0] >= '0' && buf[0] <= 'F' && buf[1] == 0) { _cid = x2i(buf[0]); _gs_flg = -1; } break; case GSRES_RSSI: if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) { _rssi = atoi(buf); _gs_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); _gs_flg = -1; } break; } return; } void GSwifi::poll () { int i, j; for (i = 0; i < 16; i ++) { if (_gs_sock[i].received && (! _gs_sock[i].data->isEmpty())) { // recv interrupt _gs_sock[i].received = false; for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) { if (! _gs_sock[i].connect || _gs_sock[i].data->isEmpty()) break; _gs_sock[i].onGsReceive.call(i, _gs_sock[i].data->available()); } } } if ((!_connect) && _reconnect_count < _reconnect && _ssid) { // re-connrct _reconnect_count ++; DBG("re-connect %d\r\n", _reconnect_count); if (reconnect() == 0) { _connect = true; _reconnect_count = 0; } } } int GSwifi::certAdd (const char *name, const 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); resetResponse(GSRES_NORMAL); _gs_putc(0x1b); _gs_putc('W'); for (i = 0; i < len; i ++) { _gs_putc(cert[i]); } return waitResponse(GS_TIMEOUT); } int GSwifi::provisioning (char *user, char *pass) { char cmd[GS_CMD_SIZE]; if (_status != GSSTAT_READY) return -1; sprintf(cmd, "AT+WEBPROV=%s,%s", user, pass); return command(cmd, GSRES_NORMAL); } int GSwifi::setBaud (int baud) { if (_status != GSSTAT_READY) return -1; _gs.printf("ATB=%d\r\n", baud); _gs.baud(baud); wait_ms(100); _buf_cmd.flush(); return 0; } int GSwifi::setRegion (int reg) { char cmd[GS_CMD_SIZE]; if (_status != GSSTAT_READY) return -1; sprintf(cmd, "AT+WREGDOMAIN=%d", reg); return command(cmd, GSRES_NORMAL); } int GSwifi::from_hex (int ch) { return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; } int GSwifi::to_hex (int code) { static char hex[] = "0123456789abcdef"; return hex[code & 15]; } 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; } #ifdef DEBUG // for test void GSwifi::dump () { int i; DBG("GS mode=%d, escape=%d, cid=%d\r\n", _gs_mode, _escape, _cid); for (i = 0; i < 16; i ++) { DBG("%d: connect=%d, type=%d, protocol=%d, len=%d\r\n", i, _gs_sock[i].connect, _gs_sock[i].type, _gs_sock[i].protocol, _gs_sock[i].data->available()); if (_gs_sock[i].protocol == GSPROT_HTTPD) { DBG(" mode=%d, type=%d, len=%d\r\n", i, _httpd[i].mode, _httpd[i].type, _httpd[i].len); } } } 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.isEmpty()) { _buf_cmd.dequeue(&c); } /* } else if (_gs_sock[0].data != NULL) { _gs_sock[0].data->dequeue(&c); } */ return c; } void GSwifi::putc(char c) { _gs_putc(c); } int GSwifi::readable() { return ! _buf_cmd.isEmpty(); // return _buf_cmd.use() || (_gs_sock[0].data != NULL && _gs_sock[0].data->use()); } #endif