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/
Diff: GSwifi.cpp
- Revision:
- 37:e61ea8267415
- Parent:
- 36:a70b11e1560f
- Child:
- 38:dfc31d58fa1d
diff -r a70b11e1560f -r e61ea8267415 GSwifi.cpp --- a/GSwifi.cpp Mon Jun 24 07:36:48 2013 +0000 +++ b/GSwifi.cpp Wed Jun 26 02:39:59 2013 +0000 @@ -24,7 +24,8 @@ #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) { +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); @@ -50,7 +51,8 @@ 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) { +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); @@ -153,25 +155,34 @@ return -1; } -int GSwifi::waitCts (int ms) { +int GSwifi::acquireUart (int ms) { Timer timeout; if (! _rts) return 0; - if (LPC_UART1->MSR & (1<<4)) return 0; +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) timeout.start(); while (timeout.read_ms() < ms) { // CTS check - if (LPC_UART1->MSR & (1<<4)) { + if (_uart->MSR & (1<<4)) { timeout.stop(); + _uart->MCR &= ~(1<<6); // RTS off + _uart->MCR &= ~(1<<1); return 0; } } timeout.stop(); DBG("cts timeout\r\n"); +#endif return -1; } +void GSwifi::releaseUart () { +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) + _uart->MCR |= (1<<6); // RTSEN +#endif +} + // uart interrupt void GSwifi::isr_recv () { static int len, mode; @@ -264,8 +275,10 @@ len = 0; break; } - tmp[len] = dat; - len ++; + if (len < sizeof(tmp) - 1) { + tmp[len] = dat; + len ++; + } } else if (mode == 2) { // port @@ -276,8 +289,10 @@ len = 0; break; } - tmp[len] = dat; - len ++; + if (len < sizeof(tmp) - 1) { + tmp[len] = dat; + len ++; + } } else if (_escape) { // esc @@ -303,13 +318,15 @@ _escape = 1; } else { // data - _gs_sock[_cid].data->queue(dat); - len ++; + if (_gs_sock[_cid].data != NULL) { + _gs_sock[_cid].data->queue(dat); + len ++; - if (len < GS_DATA_SIZE && _gs_sock[_cid].data->isFull()) { + 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()); + } } } } @@ -338,8 +355,10 @@ len = 0; break; } - tmp[len] = dat; - len ++; + if (len < sizeof(tmp) - 1) { + tmp[len] = dat; + len ++; + } } else if (mode == 2) { // port @@ -350,8 +369,10 @@ len = 0; break; } - tmp[len] = dat; - len ++; + if (len < sizeof(tmp) - 1) { + tmp[len] = dat; + len ++; + } } else if (mode == 3) { // length @@ -367,14 +388,14 @@ if (mode == 4) { // data if (_gs_sock[_cid].data != NULL) { - _gs_sock[_cid].data->queue(dat); - } - len --; + _gs_sock[_cid].data->queue(dat); + len --; - if (len && _gs_sock[_cid].data->isFull()) { + 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); @@ -394,15 +415,222 @@ } } +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 ) { + DBG("disassociate\r\n"); + _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; + + 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 = (char*)malloc(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 = (char*)malloc(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].connect && _gs_sock[i].received) { + if (_gs_sock[i].data && ! _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 (_reconnect && ! _connect) { + if (_reconnect_count == 0 || (_reconnect_count < _reconnect && _reconnect_time < time(NULL))) { + _reconnect_count ++; + DBG("reconnect %d/%d\r\n", _reconnect_count, _reconnect); + if (reconnect() == 0) { + _reconnect_count = 0; + } + _reconnect_time = time(NULL) + GS_RECONTIME; + } + } +} + int GSwifi::command (const char *cmd, GSRESPONCE res, int timeout) { int i; - if (waitCts()) return -1; + if (acquireUart()) return -1; if (cmd == NULL) { // dummy CR+LF _gs_putc('\r'); _gs_putc('\n'); + releaseUart(); wait_ms(100); _buf_cmd.flush(); return 0; @@ -414,6 +642,7 @@ } _gs_putc('\r'); _gs_putc('\n'); + releaseUart(); DBG("command: %s\r\n", cmd); if (strlen(cmd) == 0) return 0; @@ -788,6 +1017,46 @@ return 0; } +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::setBaud (int baud) { + char cmd[GS_CMD_SIZE]; + + if (_status != GSSTAT_READY || acquireUart()) return -1; + + _baud = baud; + sprintf(cmd, "ATB=%d\r\n", _baud); + _gs_puts(cmd); + releaseUart(); + wait_ms(100); + _gs.baud(_baud); + _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); +} + +#ifndef GS_LIB_TINY int GSwifi::setRFPower (int power) { char cmd[GS_CMD_SIZE]; @@ -874,21 +1143,6 @@ 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]; @@ -938,212 +1192,6 @@ 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 ) { - DBG("disassociate\r\n"); - _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; - - 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 = (char*)malloc(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 = (char*)malloc(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].connect && _gs_sock[i].received) { - if (_gs_sock[i].data && ! _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 (_reconnect && ! _connect) { - if (_reconnect_count == 0 || (_reconnect_count < _reconnect && _reconnect_time < time(NULL))) { - _reconnect_count ++; - DBG("reconnect %d/%d\r\n", _reconnect_count, _reconnect); - if (reconnect() == 0) { - _reconnect_count = 0; - } - _reconnect_time = time(NULL) + GS_RECONTIME; - } - } -} - int GSwifi::certAdd (const char *name, const char *cert, int len) { int i; char cmd[GS_CMD_SIZE]; @@ -1170,30 +1218,7 @@ sprintf(cmd, "AT+WEBPROV=%s,%s", user, pass); return command(cmd, GSRES_NORMAL); } - -int GSwifi::setBaud (int baud) { - char cmd[GS_CMD_SIZE]; - - if (_status != GSSTAT_READY || waitCts()) return -1; - - _baud = baud; - sprintf(cmd, "ATB=%d\r\n", _baud); - _gs_puts(cmd); - wait_ms(100); - _gs.baud(_baud); - _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); -} - +#endif int GSwifi::from_hex (int ch) { return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; @@ -1224,7 +1249,7 @@ if (i >= 10 && i <= 15) { return i - 10 + 'A'; } - return 0; + return '0'; }