OLD
OLD
GSwifi.cpp
- Committer:
- gsfan
- Date:
- 2012-08-21
- Revision:
- 8:bce9e7e51a0d
- Parent:
- 7:b75b7fc144ff
- Child:
- 9:3b819ba34c6c
File content as of revision 8:bce9e7e51a0d:
/** * 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 (strncmp(buf, "00:", 3) == 0) { 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()); }