GSwifiInterface library (interface for GainSpan Wi-Fi GS1011 modules) Please see https://mbed.org/users/gsfan/notebook/GSwifiInterface/
Dependents: GSwifiInterface_HelloWorld GSwifiInterface_HelloServo GSwifiInterface_UDPEchoServer GSwifiInterface_UDPEchoClient ... more
Fork of WiflyInterface by
GainSpan Wi-Fi library
The GS1011/GS2100 is an ultra low power 802.11b wireless module from GainSpan.
mbed RTOS supported.
- about this library: http://mbed.org/users/gsfan/notebook/GSwifiInterface/
- about Wi-Fi module: http://mbed.org/users/gsfan/notebook/gainspan_wifi/
ゲインスパン Wi-Fi モジュール ライブラリ
ゲインスパン社の低電力 Wi-Fiモジュール(無線LAN) GS1011/GS2100 シリーズ用のライブラリです。
mbed RTOS に対応しています。(mbed2.0)
- このライブラリについて: http://mbed.org/users/gsfan/notebook/gainspan_wifi/
- Wi-FIモジュールについて: http://mbed.org/users/gsfan/notebook/gainspan_wifi/
- UARTコマンド、SPIデータインターフェースに対応しました。(2019/09)
Revision 5:78943b3945b5, committed 2013-01-27
- Comitter:
- gsfan
- Date:
- Sun Jan 27 14:31:19 2013 +0000
- Parent:
- 4:0bcec6272784
- Child:
- 6:6a6396b56405
- Commit message:
- 1st build
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifi/CBuffer.h Sun Jan 27 14:31:19 2013 +0000 @@ -0,0 +1,75 @@ +/* Copyright (C) 2012 mbed.org, 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. + */ + +#ifndef CIRCBUFFER_H_ +#define CIRCBUFFER_H_ + +template <class T> +class CircBuffer { +public: + CircBuffer(int length) { + write = 0; + read = 0; + size = length + 1; + buf = (T *)malloc(size * sizeof(T)); + }; + + bool isFull() { + return (((write + 1) % size) == read); + }; + + bool isEmpty() { + return (read == write); + }; + + void queue(T k) { + if (isFull()) { + read++; + read %= size; + } + buf[write++] = k; + write %= size; + } + + void flush() { + read = 0; + write = 0; + } + + + uint32_t available() { + return (write >= read) ? write - read : size - read + write; + }; + + bool dequeue(T * c) { + bool empty = isEmpty(); + if (!empty) { + *c = buf[read++]; + read %= size; + } + return(!empty); + }; + +private: + volatile uint32_t write; + volatile uint32_t read; + uint32_t size; + T * buf; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifi/GSwifi.cpp Sun Jan 27 14:31:19 2013 +0000 @@ -0,0 +1,669 @@ +/* Copyright (C) 2012 mbed.org, 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. + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ + +#include "mbed.h" +#include "GSwifi.h" +#include <string> +#include <algorithm> + +GSwifi * GSwifi::_inst; + +GSwifi::GSwifi( PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, const char * ssid, const char * phrase, Security sec): + _uart(tx, rx), _reset(reset), _buf_gswifi(CFG_CMD_SIZE) +{ + memset(&_state, 0, sizeof(_state)); + memset(&_con, 0, sizeof(_con)); + _state.sec = sec; + _state.acid = -1; + + // change all ' ' in '$' in the ssid and the passphrase + strncpy(_ssid, ssid, sizeof(_ssid)); + for (int i = 0; i < strlen(ssid); i++) { + if (_ssid[i] == ' ') + _ssid[i] = '$'; + } + strncpy(_phrase, phrase, sizeof(_phrase)); + for (int i = 0; i < strlen(phrase); i++) { + if (_phrase[i] == ' ') + _phrase[i] = '$'; + } + + _inst = this; + _state.mode = MODE_COMMAND; + +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) + if (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 (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 (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 (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.baud(CFG_UART_BAUD); + _uart.attach(this, &GSwifi::handler_rx); + this->reset(); +} + +bool GSwifi::join() +{ + bool r; + char cmd[CFG_CMD_SIZE]; + + send("\r\n", 2); + if (sendCommand("ATE0") == false) return -1; + if (_rts) { + sendCommand("AT&K0"); + sendCommand("AT&R1"); + } + + disconnect(); + sendCommand("AT+WREGDOMAIN=" CFG_WREGDOMAIN); + sendCommand("AT+BDATA=1"); + sendCommand("AT+WM=0"); // infrastructure + wait_ms(100); + if (_state.dhcp && _state.sec != SEC_WPS_BUTTON) { + sendCommand("AT+NDHCP=1"); + } else { + sendCommand("AT+NDHCP=0"); + } + + switch (_state.sec) { + case SEC_NONE: + case SEC_OPEN: + case SEC_WEP: + sprintf(cmd, "AT+WAUTH=%d", _ssid); + sendCommand(cmd); + if (_state.sec != SEC_NONE) { + sprintf(cmd, "AT+WWEP1=%s", _phrase); + sendCommand(cmd); + wait_ms(100); + } + sprintf(cmd, "AT+WA=%s", _ssid); + for (int i= 0; i < MAX_TRY_JOIN; i++) { + r = sendCommand(cmd, RES_DHCP, CFG_TIMEOUT2); + if (r) break; + } + break; + case SEC_WPA_PSK: + case SEC_WPA2_PSK: + sendCommand("AT+WAUTH=0"); + sprintf(cmd, "AT+WPAPSK=%s,%s", _ssid, _phrase); + sendCommand(cmd, RES_NORMAL, CFG_TIMEOUT2); + wait_ms(100); + sprintf(cmd, "AT+WA=%s", _ssid); + for (int i= 0; i < MAX_TRY_JOIN; i++) { + r = sendCommand(cmd, RES_DHCP, CFG_TIMEOUT2); + if (r) break; + } + break; + case SEC_WPS_BUTTON: + sendCommand("AT+WAUTH=0"); + for (int i= 0; i < MAX_TRY_JOIN; i++) { + r = sendCommand("AT+WWPS=1", RES_WPS, CFG_TIMEOUT2); + if (r) break; + } + if (r && _state.dhcp) { + r = sendCommand("AT+NDHCP=1", RES_DHCP, CFG_TIMEOUT2); + } + break; + default: + DBG("Can't use security\r\n"); + r = false; + break; + } + + if (r) { + if (!_state.dhcp) { + sprintf(cmd, "AT+NSET=%s,%s,%s", _ip, _netmask, _gateway); + sendCommand(cmd); + sprintf(cmd, "AT+DNSSET=%s", _nameserver); + sendCommand(cmd); + } + + _state.associated = true; + INFO("ssid: %s\r\nphrase: %s\r\nsecurity: %d", _ssid, _phrase, _state.sec); + } + + return r; +} + + +bool GSwifi::gethostbyname(const char * host, char * ip) +{ + int i, flg = 0; + char cmd[CFG_CMD_SIZE]; + + for (i = 0; i < strlen(host); i ++) { + if ((host[i] < '0' || host[i] > '9') && host[i] != '.') { + flg = 1; + break; + } + } + if (!flg) { + strncpy(ip, host, 16); + return true; + } + + sprintf(cmd, "AT+DNSLOOKUP=%s", host); + if (sendCommand(cmd, RES_DNSLOOKUP)) { + strncpy(ip, _resolv, 16); + return true; + } + + return false; +} + + +void GSwifi::flush(int cid) +{ + if (cid < 0) { + return _buf_gswifi.flush(); + } else { + if (_con[cid].buf == NULL) + _con[cid].buf = new CircBuffer<char>(CFG_DATA_SIZE); + return _con[cid].buf->flush(); + } +} + +bool GSwifi::sendCommand(const char * cmd, Response res, int timeout) +{ + DBG("command: %s",cmd); + + send(cmd, strlen(cmd)); + if (send("\r\n", 2, res, timeout) == -1) { + ERR("sendCommand: cannot %s", cmd); + return false; + } + return true; +} + + +bool GSwifi::disconnect() +{ + // if already disconnected, return + if (!_state.associated) + return true; + + for (int i = 0; i < 16; i ++) { + if (_con[i].buf) + _con[i].buf->flush(); + } + sendCommand("AT+NCLOSEALL"); + sendCommand("AT+WD"); + sendCommand("AT+NDHCP=0"); + wait_ms(100); + + _state.associated = false; + return true; + +} + +bool GSwifi::is_connected(int cid) +{ + return _con[cid].connected; +} + + +void GSwifi::reset() +{ + _reset = 0; + wait_ms(100); + _reset = 1; + wait_ms(500); +} + + +int GSwifi::putc(char c) +{ + while (!_uart.writeable()); + return _uart.putc(c); +} + + +int GSwifi::readable(int cid) +{ + if (cid < 0) { + return _buf_gswifi.available(); + } else { + return _con[cid].buf->available(); + } +} + +int GSwifi::writeable() +{ + return _uart.writeable(); +} + +char GSwifi::getc(int cid) +{ + char c; + if (cid < 0) { + while (!_buf_gswifi.available()); + _buf_gswifi.dequeue(&c); + } else { + while (!_con[cid].buf->available()); + _con[cid].buf->dequeue(&c); + } + return c; +} + +void GSwifi::handler_rx(void) +{ + static int len, flg; + static char tmp[20]; + char dat; + + while (_uart.readable()) { + + dat = _uart.getc(); + + switch (_state.mode) { + case MODE_COMMAND: // command responce + if (_state.escape) { + // esc + switch (dat) { + case 'O': + DBG("ok"); + _state.retres = RES_OK; + _state.cmdres = RES_OK; + break; + case 'F': + DBG("failure"); + _state.retres = RES_FAILURE; + _state.cmdres = RES_FAILURE; + break; + case 'Z': + case 'H': + DBG("GSMODE_DATA_RX"); + _state.mode = MODE_DATA_RX; + flg = 0; + break; + case 'y': + DBG("GSMODE_DATA_RXUDP"); + _state.mode = MODE_DATA_RXUDP; + flg = 0; + break; + case 'S': + case 'u': + default: + WARN("unknown [ESC] %02x", dat); + break; + } + _state.escape = 0; + } else { + if (dat == 0x1b) { + _state.escape = 1; + } else + if (dat == '\n') { + parseResponse(); + } else + if (dat != '\r') { + // command + _buf_gswifi.queue(dat); + } + } + break; + + case MODE_DATA_RX: + case MODE_DATA_RXUDP: + switch (flg) { + case 0: + // CID + _state.cid = x2i(dat); + flg ++; + if (_state.mode == MODE_DATA_RX) { + flg = 3; + } + len = 0; + break; + case 1: + // IP (UDP) + if ((dat >= '0' && dat <= '9') || dat == '.') { + tmp[len] = dat; + len ++; + } else + if (len < sizeof(tmp) - 1) { + tmp[len] = 0; + strncpy(_con[_state.cid].ip, tmp, sizeof(_con[_state.cid].ip)); + flg ++; + len = 0; + } + break; + case 2: + // port + if (dat >= '0' && dat <= '9') { + tmp[len] = dat; + len ++; + } else { + tmp[len] = 0; + _con[_state.cid].port = atoi(tmp); + flg ++; + len = 0; + } + break; + case 3: + // length + tmp[len] = dat; + len ++; + if (len >= 4) { + tmp[len] = 0; + len = atoi(tmp); + flg ++; + } + break; + case 4: + // data + if (_con[_state.cid].buf != NULL) { + _con[_state.cid].buf->queue(dat); + } + len --; + + if (len == 0 || _con[_state.cid].buf->isFull()) { + DBG("recv binary %d", _state.cid); + _state.escape = 0; + _state.mode = MODE_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; + } + + break; + } + + } // while +} + +void GSwifi::parseResponse () { + int i; + char buf[CFG_CMD_SIZE]; + + while (_buf_gswifi.available()) { + i = 0; + while (_buf_gswifi.available() && i < sizeof(buf)) { + _buf_gswifi.dequeue(&buf[i]); + if (buf[i] == '\n') { + break; + } + i ++; + } + if (i == 0) continue; + buf[i] = 0; + DBG("parseResponse: %s", buf); + + if (_state.cmdres != RES_NULL) { + parseCmdResponse(buf); + DBG("parseCmdResponse %d %d", _state.cmdres, _state.retres); + } + + if (strncmp(buf, "CONNECT ", 8) == 0 && buf[8] >= '0' && buf[8] <= 'F' && buf[9] != 0) { + int cid; + char *tmp, *tmp2; + cid = x2i(buf[8]); + _state.acid = x2i(buf[10]); + tmp = buf + 12; + tmp2 = strstr(tmp, " "); + tmp2[0] = 0; + strncpy(_con[_state.acid].ip, tmp, sizeof(_con[_state.acid].ip)); + tmp = tmp2 + 1; + _con[_state.acid].port = atoi(tmp); + _con[_state.acid].parent = cid; + if (_con[_state.acid].buf == NULL) + _con[_state.acid].buf = new CircBuffer<char>(CFG_DATA_SIZE); + _con[_state.acid].buf->flush(); + _con[_state.acid].connected = true; + DBG("connect %d -> %d", cid, _state.acid); + } else + if (strncmp(buf, "DISCONNECT ", 11) == 0) { + int cid; + cid = x2i(buf[11]); + DBG("disconnect %d", cid); + _con[cid].connected = false; + } 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) { + _state.associated = false; + for (i = 0; i < 16; i ++) { + _con[i].connected = false; + } + } else + if (strncmp(buf, "Out of StandBy-Timer", 20) == 0 || + strncmp(buf, "Out of StandBy-Alarm", 20) == 0) { + _state.status = STAT_WAKEUP; + } else + if (strncmp(buf, "Out of Deep Sleep", 17) == 0 ) { + _state.status = STAT_READY; + } else + if (strncmp(buf, "Out of", 6) == 0) { + } + } +} + +void GSwifi::parseCmdResponse (char *buf) { + + if (strcmp(buf, "OK") == 0) { + _state.retres = RES_OK; + } else + if (strncmp(buf, "ERROR", 5) == 0) { + _state.retres = RES_FAILURE; + } + + switch(_state.cmdres) { + case RES_NORMAL: + _state.cmdres = RES_OK; + break; + case RES_WPS: + if (_state.n == 0 && strncmp(buf, "SSID", 4) == 0) { + _state.n ++; + } else + if (_state.n == 1 && strncmp(buf, "CHANNEL", 7) == 0) { + _state.n ++; + } else + if (_state.n == 2 && strncmp(buf, "PASSPHRASE", 10) == 0) { + _state.n ++; + _state.cmdres = RES_OK; + } + break; + case RES_CONNECT: + if (strncmp(buf, "CONNECT ", 8) == 0 && buf[9] == 0) { + _state.cid = x2i(buf[8]); + _state.cmdres = RES_OK; + if (_con[_state.cid].buf == NULL) + _con[_state.cid].buf = new CircBuffer<char>(CFG_DATA_SIZE); + _con[_state.cid].buf->flush(); + _con[_state.cid].connected = true; + INFO("connect: %d", _state.cid); + } + break; + case RES_DHCP: + if (_state.n == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) { + _state.n ++; + } else + if (_state.n == 1) { + char *tmp, *tmp2; + tmp = buf + 1; + tmp2 = strstr(tmp, ":"); + tmp2[0] = 0; + strncpy(_ip, tmp, sizeof(_ip)); + tmp = tmp2 + 2; + tmp2 = strstr(tmp, ":"); + tmp2[0] = 0; + strncpy(_netmask, tmp, sizeof(_netmask)); + tmp = tmp2 + 2; + strncpy(_gateway, tmp, sizeof(_gateway)); + _state.n ++; + _state.cmdres = RES_OK; + INFO("ip: %s\r\nnetmask: %s\r\ngateway: %s", _ip, _netmask, _gateway); + } + break; + case RES_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; +*/ + _state.cmdres = RES_OK; + } + break; + case RES_DNSLOOKUP: + if (strncmp(buf, "IP:", 3) == 0) { + strncpy(_resolv, &buf[3], sizeof(_resolv)); + _state.cmdres = RES_OK; + INFO("resolv: %s", _resolv); + } + break; + case RES_HTTP: + if (buf[0] >= '0' && buf[0] <= 'F') { + _state.cid = x2i(buf[0]); + _state.cmdres = RES_OK; + INFO("http: %d", _state.cid); + } + break; + case RES_RSSI: + if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) { + _rssi = atoi(buf); + _state.cmdres = RES_OK; + INFO("rssi: %d", _rssi); + } + break; + case RES_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); + _state.cmdres = RES_OK; + } + break; + } +} + +int GSwifi::send(const char * str, int len, Response res, int timeout) +{ + Timer tmr; + int result = 0; + + if (res == RES_NULL) { + for (int i = 0; i < len; i++) + result = (putc(str[i]) == str[i]) ? result + 1 : result; + } else { + _state.cmdres = res; + _state.retres = RES_NULL; + + tmr.start(); + for (int i = 0; i < len; i++) + result = (putc(str[i]) == str[i]) ? result + 1 : result; + + while (1) { + if (tmr.read_ms() > timeout || _state.retres == RES_FAILURE) { + result = -1; + break; + } + if (_state.retres == RES_OK && _state.cmdres != res) break; + } + } + + _state.cmdres = RES_NULL; + _state.retres = RES_NULL; + return result; +} + +bool GSwifi::readRemote(int cid, char **ip, int *port) { + *ip = _con[cid].ip; + *port = _con[cid].port; + return true; +} + +int GSwifi::readCID () { + return _state.cid; +} + +int GSwifi::readACID () { + int r = -1; + if (_state.acid >= 0 && _con[_state.acid].connected == true) { + r = _state.acid; + _state.acid = -1; + } + return r; +} + +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; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifi/GSwifi.h Sun Jan 27 14:31:19 2013 +0000 @@ -0,0 +1,285 @@ +/* Copyright (C) 2012 mbed.org, 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. + * + * @section DESCRIPTION + * + * GainSpan GS1011, Wi-Fi module + * + * http://www.gainspan.com/modules + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ + +#ifndef GSwifi_H +#define GSwifi_H + +#include "mbed.h" +#include "CBuffer.h" + +#define DEFAULT_WAIT_RESP_TIMEOUT 500 +#define CFG_TIMEOUT 10000 // ms +#define CFG_TIMEOUT2 30000 // ms +#define CFG_CMD_SIZE 100 +#define CFG_DATA_SIZE 1000 + +#define CFG_UART_BAUD 9600 +#define CFG_DNSNAME "setup.local" +#define CFG_WREGDOMAIN "2" // 0:FCC, 1:ETSI, 2:TELEC +#define MAX_TRY_JOIN 1 + + +//Debug is disabled by default +#if (0 && !defined(TARGET_LPC11U24)) +#define DBG(x, ...) std::printf("[GSwifi : DBG]" x "\r\n", ##__VA_ARGS__); +#define WARN(x, ...) std::printf("[GSwifi : WARN]" x "\r\n", ##__VA_ARGS__); +#define ERR(x, ...) std::printf("[GSwifi : ERR]" x "\r\n", ##__VA_ARGS__); +#else +#define DBG(x, ...) +#define WARN(x, ...) +#define ERR(x, ...) +#endif + +#if !defined(TARGET_LPC11U24) +#define INFO(x, ...) printf("[GSwifi : INFO]\r\n"x"\r\n", ##__VA_ARGS__); +#else +#define INFO(x, ...) +#endif + + +class GSwifi +{ + +public: + + enum Security { + SEC_AUTO = 0, + SEC_NONE = 0, + SEC_OPEN = 1, + SEC_WEP = 2, + SEC_WPA_PSK = 4, + SEC_WPA2_PSK = 8, + SEC_WPA_ENT = 16, + SEC_WPA2_ENT = 32, + SEC_WPS_BUTTON = 64, + }; + + enum Protocol { + PROTO_UDP = 0, + PROTO_TCP = 1, + PROTO_HTTPGET, + PROTO_HTTPPOST, + PROTO_HTTPD, + }; + + enum Response { + RES_NULL, + RES_NORMAL, + RES_CONNECT, + RES_WPS, + RES_MACADDRESS, + RES_DHCP, + RES_DNSLOOKUP, + RES_HTTP, + RES_RSSI, + RES_TIME, + RES_OK, + RES_FAILURE, + }; + + enum Mode { + MODE_COMMAND, + MODE_DATA_RX, + MODE_DATA_RXUDP, + MODE_DATA_RXHTTP, + }; + + enum Status { + STAT_READY, + STAT_STANDBY, + STAT_WAKEUP, + STAT_DEEPSLEEP, + }; + + /* + * Constructor + * + * @param tx mbed pin to use for tx line of Serial interface + * @param rx mbed pin to use for rx line of Serial interface + * \param cts mbed pin to use for cts line of Serial interface + * \param rts mbed pin to use for rts line of Serial interface + * @param reset reset pin of the wifi module () + * @param ssid ssid of the network + * @param phrase WEP or WPA key + * @param sec Security type (NONE, WEP_128 or WPA) + */ + GSwifi( PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, const char * ssid, const char * phrase, Security sec); + + /* + * Connect the wifi module to the ssid contained in the constructor. + * + * @return true if connected, false otherwise + */ + bool join(); + + /* + * Disconnect the wifly module from the access point + * + * @ returns true if successful + */ + bool disconnect(); + + /* + * Reset the wifi module + */ + void reset(); + + /* + * Check if characters are available + * + * @return number of available characters + */ + int readable(int cid); + + /* + * Check if characters are available + * + * @return number of available characters + */ + int writeable(); + + /* + * Check if a tcp link is active + * + * @returns true if successful + */ + bool is_connected(int cid); + + /* + * Read a character + * + * @return the character read + */ + char getc(int cid); + + /* + * Flush the buffer + */ + void flush(int cid); + + /* + * Write a character + * + * @param the character which will be written + */ + int putc(char c); + + /* + * Send a string to the wifi module by serial port. This function desactivates the user interrupt handler when a character is received to analyze the response from the wifi module. + * Useful to send a command to the module and wait a response. + * + * + * @param str string to be sent + * @param len string length + * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO") + * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL) + * + * @return true if ACK has been found in the response from the wifi module. False otherwise or if there is no response in 5s. + */ + int send(const char * str, int len, Response res = RES_NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT); + + /* + * Send a command to the wify module. Check if the module is in command mode. If not enter in command mode + * + * @param str string to be sent + * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO") + * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL) + * + * @returns true if successful + */ + bool sendCommand(const char * cmd, Response res = RES_NORMAL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT); + + /* + * Return true if the module is using dhcp + * + * @returns true if the module is using dhcp + */ + bool isDHCP() { + return _state.dhcp; + } + + bool gethostbyname(const char * host, char * ip); + + static GSwifi * getInstance() { + return _inst; + }; + + bool readRemote(int cid, char **ip, int *port); + int readCID (); + int readACID (); + +protected: + Serial _uart; + bool _rts; + DigitalOut _reset; + char _phrase[30]; + char _ssid[30]; + char _ip[16]; + char _netmask[16]; + char _gateway[16]; + char _nameserver[16]; + char _resolv[16]; + int _rssi; + time_t _time; + CircBuffer<char> _buf_gswifi; + + static GSwifi * _inst; + + void attach_rx(bool null); + void handler_rx(void); + + int x2i (char c); + char i2x (int i); + void parseResponse (); + void parseCmdResponse (char *buf); + + typedef struct STATE { + bool associated; + bool dhcp; + Security sec; + Mode mode; + Status status; + bool escape; + int cid, acid; + volatile Response cmdres, retres; + int n; + } State; + + State _state; + + typedef struct CONNECTION { + bool connected; + char ip[16]; + int port; + CircBuffer<char> *buf; + int parent; + } Connection; + + Connection _con[16]; +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface.cpp Sun Jan 27 14:31:19 2013 +0000 @@ -0,0 +1,43 @@ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ + +#include "GSwifiInterface.h" + +GSwifiInterface::GSwifiInterface( PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, + const char * ssid, const char * phrase, Security sec) : + GSwifi(tx, rx, cts, rts, reset, ssid, phrase, sec) +{ +} + +int GSwifiInterface::init() +{ + _state.dhcp = true; + return 0; +} + +int GSwifiInterface::init(const char* ip, const char* mask, const char* gateway) +{ + _state.dhcp = false; + strncpy(_ip, ip, sizeof(_ip)); + strncpy(_netmask, mask, sizeof(_netmask)); + strncpy(_gateway, gateway, sizeof(_gateway)); + + return 0; +} + +int GSwifiInterface::connect() +{ + return join(); +} + +int GSwifiInterface::disconnect() +{ + return GSwifi::disconnect(); +} + +char * GSwifiInterface::getIPAddress() +{ + + return _ip; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface.h Sun Jan 27 14:31:19 2013 +0000 @@ -0,0 +1,90 @@ +/* GSwifiInterface.h */ +/* Copyright (C) 2012 mbed.org, 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. + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ + +#ifndef GSwifiINTERFACE_H_ +#define GSwifiINTERFACE_H_ + +#include "GSwifi.h" + + /** Interface using GSwifi to connect to an IP-based network + * + */ +class GSwifiInterface: public GSwifi { +public: + + /** + * Constructor + * + * \param tx mbed pin to use for tx line of Serial interface + * \param rx mbed pin to use for rx line of Serial interface + * \param cts mbed pin to use for cts line of Serial interface + * \param rts mbed pin to use for rts line of Serial interface + * \param reset reset pin of the wifi module () + * \param ssid ssid of the network + * \param phrase WEP or WPA key + * \param sec Security type (NONE, WEP_128 or WPA) + */ + GSwifiInterface(PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, const char * ssid, const char * phrase, Security sec = SEC_NONE); + + /** Initialize the interface with DHCP. + * Initialize the interface and configure it to use DHCP (no connection at this point). + * \return 0 on success, a negative number on failure + */ + int init(); //With DHCP + + /** Initialize the interface with a static IP address. + * Initialize the interface and configure it with the following static configuration (no connection at this point). + * \param ip the IP address to use + * \param mask the IP address mask + * \param gateway the gateway to use + * \return 0 on success, a negative number on failure + */ + int init(const char* ip, const char* mask, const char* gateway); + + /** Connect + * Bring the interface up, start DHCP if needed. + * \return 0 on success, a negative number on failure + */ + int connect(); + + /** Disconnect + * Bring the interface down + * \return 0 on success, a negative number on failure + */ + int disconnect(); + + /** Get IP address + * + * @ returns ip address + */ + char* getIPAddress(); + +private: + char _ip_string[20]; + bool _ip_set; +}; + +#include "TCPSocketConnection.h" +#include "TCPSocketServer.h" +#include "UDPSocket.h" + +#endif /* WIFLYINTERFACE_H_ */
--- a/Socket/Endpoint.cpp Thu Dec 20 15:08:58 2012 +0000 +++ b/Socket/Endpoint.cpp Sun Jan 27 14:31:19 2013 +0000 @@ -1,50 +1,52 @@ -/* Copyright (C) 2012 mbed.org, 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. - */ -#include "Socket/Socket.h" -#include "Socket/Endpoint.h" -#include <cstring> - -using std::memset; - -Endpoint::Endpoint() { - wifly = Wifly::getInstance(); - if (wifly == NULL) - error("Endpoint constructor error: no wifly instance available!\r\n"); - reset_address(); -} -Endpoint::~Endpoint() {} - -void Endpoint::reset_address(void) { - _ipAddress[0] = '\0'; - _port = 0; -} - -int Endpoint::set_address(const char* host, const int port) { - //Resolve DNS address or populate hard-coded IP address - wifly->gethostbyname(host, _ipAddress); - _port = port; - return 0; -} - -char* Endpoint::get_address() { - return _ipAddress; -} - -int Endpoint::get_port() { - return _port; -} +/* Copyright (C) 2012 mbed.org, 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. + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ +#include "Socket/Socket.h" +#include "Socket/Endpoint.h" +#include <cstring> + +using std::memset; + +Endpoint::Endpoint() { + _ewifi = GSwifi::getInstance(); + if (_ewifi == NULL) + error("Endpoint constructor error: no wifly instance available!\r\n"); + reset_address(); +} +Endpoint::~Endpoint() {} + +void Endpoint::reset_address(void) { + _ipAddress[0] = '\0'; + _port = 0; +} + +int Endpoint::set_address(const char* host, const int port) { + //Resolve DNS address or populate hard-coded IP address + _port = port; + return _ewifi->gethostbyname(host, _ipAddress) == true ? 0 : -1; +} + +char* Endpoint::get_address() { + return _ipAddress; +} + +int Endpoint::get_port() { + return _port; +}
--- a/Socket/Endpoint.h Thu Dec 20 15:08:58 2012 +0000 +++ b/Socket/Endpoint.h Sun Jan 27 14:31:19 2013 +0000 @@ -1,65 +1,68 @@ -/* Copyright (C) 2012 mbed.org, 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. - */ -#ifndef ENDPOINT_H -#define ENDPOINT_H - -#include "Wifly.h" - -class UDPSocket; - -/** -IP Endpoint (address, port) -*/ -class Endpoint { - friend class UDPSocket; - -public: - /** IP Endpoint (address, port) - */ - Endpoint(void); - - ~Endpoint(void); - - /** Reset the address of this endpoint - */ - void reset_address(void); - - /** Set the address of this endpoint - \param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS). - \param port The endpoint port - \return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS). - */ - int set_address(const char* host, const int port); - - /** Get the IP address of this endpoint - \return The IP address of this endpoint. - */ - char* get_address(void); - - /** Get the port of this endpoint - \return The port of this endpoint - */ - int get_port(void); - -protected: - char _ipAddress[16]; - int _port; - Wifly * wifly; -}; - -#endif +/* Copyright (C) 2012 mbed.org, 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. + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ +#ifndef ENDPOINT_H +#define ENDPOINT_H + +#include "GSwifi.h" + +class UDPSocket; + +/** +IP Endpoint (address, port) +*/ +class Endpoint { + friend class UDPSocket; + +public: + /** IP Endpoint (address, port) + */ + Endpoint(void); + + ~Endpoint(void); + + /** Reset the address of this endpoint + */ + void reset_address(void); + + /** Set the address of this endpoint + \param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS). + \param port The endpoint port + \return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS). + */ + int set_address(const char* host, const int port); + + /** Get the IP address of this endpoint + \return The IP address of this endpoint. + */ + char* get_address(void); + + /** Get the port of this endpoint + \return The port of this endpoint + */ + int get_port(void); + +protected: + char _ipAddress[16]; + int _port; + GSwifi * _ewifi; +}; + +#endif
--- a/Socket/Socket.cpp Thu Dec 20 15:08:58 2012 +0000 +++ b/Socket/Socket.cpp Sun Jan 27 14:31:19 2013 +0000 @@ -1,39 +1,54 @@ -/* Copyright (C) 2012 mbed.org, 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. - */ - -#include "Socket.h" -#include <cstring> - -Socket::Socket() : _blocking(true), _timeout(1500) { - wifi = Wifly::getInstance(); - if (wifi == NULL) - error("Socket constructor error: no wifly instance available!\r\n"); -} - -void Socket::set_blocking(bool blocking, unsigned int timeout) { - _blocking = blocking; - _timeout = timeout; -} - -int Socket::close() { - return (wifi->close()) ? 0 : -1; -} - -Socket::~Socket() { - close(); //Don't want to leak -} +/* Copyright (C) 2012 mbed.org, 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. + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ + +#include "Socket.h" +#include <cstring> + +Socket::Socket() { + _wifi = GSwifi::getInstance(); + if (_wifi == NULL) + error("Socket constructor error: no wifly instance available!\r\n"); + _blocking = true; + _timeout = 1500; + + _server = false; + _cid = -1; + _port = 0; +} + +void Socket::set_blocking(bool blocking, unsigned int timeout) { + _blocking = blocking; + _timeout = timeout; +} + +int Socket::close() { + char cmd[CFG_CMD_SIZE]; + + if (_cid < 0) return 0; + + sprintf(cmd, "AT+NCLOSE=%X", _cid); + _cid = -1; + return _wifi->sendCommand(cmd); +} + +Socket::~Socket() { + close(); //Don't want to leak +}
--- a/Socket/Socket.h Thu Dec 20 15:08:58 2012 +0000 +++ b/Socket/Socket.h Sun Jan 27 14:31:19 2013 +0000 @@ -1,51 +1,58 @@ -/* Copyright (C) 2012 mbed.org, 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. - */ -#ifndef SOCKET_H_ -#define SOCKET_H_ - -#include "Wifly.h" - -/** Socket file descriptor and select wrapper - */ -class Socket { -public: - /** Socket - */ - Socket(); - - /** Set blocking or non-blocking mode of the socket and a timeout on - blocking socket operations - \param blocking true for blocking mode, false for non-blocking mode. - \param timeout timeout in ms [Default: (1500)ms]. - */ - void set_blocking(bool blocking, unsigned int timeout=1500); - - /** Close the socket file descriptor - */ - int close(); - - ~Socket(); - -protected: - bool _blocking; - int _timeout; - Wifly * wifi; -}; - - -#endif /* SOCKET_H_ */ +/* Copyright (C) 2012 mbed.org, 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. + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ +#ifndef SOCKET_H_ +#define SOCKET_H_ + +#include "GSwifi.h" + +/** Socket file descriptor and select wrapper + */ +class Socket { +public: + /** Socket + */ + Socket(); + + /** Set blocking or non-blocking mode of the socket and a timeout on + blocking socket operations + \param blocking true for blocking mode, false for non-blocking mode. + \param timeout timeout in ms [Default: (1500)ms]. + */ + void set_blocking(bool blocking, unsigned int timeout=1500); + + /** Close the socket file descriptor + */ + int close(); + + ~Socket(); + +protected: + bool _blocking; + int _timeout; + GSwifi * _wifi; + + bool _server; + int _cid; + int _port; +}; + + +#endif /* SOCKET_H_ */
--- a/Socket/TCPSocketConnection.cpp Thu Dec 20 15:08:58 2012 +0000 +++ b/Socket/TCPSocketConnection.cpp Sun Jan 27 14:31:19 2013 +0000 @@ -1,125 +1,159 @@ -/* Copyright (C) 2012 mbed.org, 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. - */ - -#include "TCPSocketConnection.h" -#include <algorithm> - -TCPSocketConnection::TCPSocketConnection() {} - -int TCPSocketConnection::connect(const char* host, const int port) -{ - if (!wifi->connect(host, port)) - return -1; - wifi->flush(); - return 0; -} - -bool TCPSocketConnection::is_connected(void) -{ - return wifi->is_connected(); -} - -int TCPSocketConnection::send(char* data, int length) -{ - Timer tmr; - - if (!_blocking) { - tmr.start(); - while (tmr.read_ms() < _timeout) { - if (wifi->writeable()) - break; - } - if (tmr.read_ms() >= _timeout) { - return -1; - } - } - return wifi->send(data, length); -} - -// -1 if unsuccessful, else number of bytes written -int TCPSocketConnection::send_all(char* data, int length) -{ - Timer tmr; - int idx = 0; - tmr.start(); - - while ((tmr.read_ms() < _timeout) || _blocking) { - - idx += wifi->send(data, length); - - if (idx == length) - return idx; - } - return (idx == 0) ? -1 : idx; -} - -// -1 if unsuccessful, else number of bytes received -int TCPSocketConnection::receive(char* data, int length) -{ - Timer tmr; - int time = -1; - - - if (!_blocking) { - tmr.start(); - while (time < _timeout + 20) { - if (wifi->readable()) { - break; - } - time = tmr.read_ms(); - } - if (time >= _timeout + 20) { - return -1; - } - } - - - while(!wifi->readable()); - int nb_available = wifi->readable(); - for (int i = 0; i < min(nb_available, length); i++) { - data[i] = wifi->getc(); - } - - return min(nb_available, length); -} - - -// -1 if unsuccessful, else number of bytes received -int TCPSocketConnection::receive_all(char* data, int length) -{ - Timer tmr; - int idx = 0; - int time = -1; - - tmr.start(); - - while (time < _timeout || _blocking) { - - int nb_available = wifi->readable(); - for (int i = 0; i < min(nb_available, length); i++) { - data[idx++] = wifi->getc(); - } - - if (idx == length) - break; - - time = tmr.read_ms(); - } - - return (idx == 0) ? -1 : idx; -} +/* Copyright (C) 2012 mbed.org, 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. + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ + +#include "TCPSocketConnection.h" +#include <algorithm> + +TCPSocketConnection::TCPSocketConnection() {} + +int TCPSocketConnection::connect(const char* host, const int port) +{ + char cmd[CFG_CMD_SIZE]; + char ip[16]; + + if (_cid < 0 || !_wifi->is_connected(_cid)) { + // Socket open + if (_wifi->gethostbyname(host, ip) == false) return -1; + _server = false; + sprintf(cmd, "AT+NCTCP=%s,%d", ip, port); + if (_wifi->sendCommand(cmd, GSwifi::RES_CONNECT) == false) return -1; + _cid = _wifi->readCID(); + return 0; + } + + return -1; +} + +bool TCPSocketConnection::is_connected(void) +{ + return _wifi->is_connected(_cid); +} + +int TCPSocketConnection::send(char* data, int length) +{ + char cmd[CFG_CMD_SIZE]; + Timer tmr; + + if (!_blocking) { + tmr.start(); + while (tmr.read_ms() < _timeout) { + if (_wifi->writeable()) + break; + } + if (tmr.read_ms() >= _timeout) { + return -1; + } + } + + // TCP Client/Server + sprintf(cmd, "\x1bZ%X%04d", _cid, length); + _wifi->send(cmd, strlen(cmd)); + return _wifi->send(data, length, GSwifi::RES_NORMAL); +} + +// -1 if unsuccessful, else number of bytes written +int TCPSocketConnection::send_all(char* data, int length) +{ + char cmd[CFG_CMD_SIZE]; + Timer tmr; + int idx = 0; + tmr.start(); + + // TCP Client/Server + sprintf(cmd, "\x1bZ%X%04d", _cid, length); + _wifi->send(cmd, strlen(cmd)); + + while ((tmr.read_ms() < _timeout) || _blocking) { + + idx += _wifi->send(data, length, GSwifi::RES_NORMAL); + + if (idx == -1) return -1; + if (idx == length) + return idx; + } + return (idx == 0) ? -1 : idx; +} + +// -1 if unsuccessful, else number of bytes received +int TCPSocketConnection::receive(char* data, int length) +{ + Timer tmr; + int time = -1; + + + if (!_blocking) { + tmr.start(); + while (time < _timeout + 20) { + if (_wifi->readable(_cid)) { + break; + } + time = tmr.read_ms(); + } + if (time >= _timeout + 20) { + return -1; + } + } + + + while(!_wifi->readable(_cid)); + int nb_available = _wifi->readable(_cid); + for (int i = 0; i < min(nb_available, length); i++) { + data[i] = _wifi->getc(_cid); + } + + return min(nb_available, length); +} + + +// -1 if unsuccessful, else number of bytes received +int TCPSocketConnection::receive_all(char* data, int length) +{ + Timer tmr; + int idx = 0; + int time = -1; + + tmr.start(); + + while (time < _timeout || _blocking) { + + int nb_available = _wifi->readable(_cid); + for (int i = 0; i < min(nb_available, length); i++) { + data[idx++] = _wifi->getc(_cid); + } + + if (idx == length) + break; + + time = tmr.read_ms(); + } + + return (idx == 0) ? -1 : idx; +} + +void TCPSocketConnection::confCID (int cid) { + char *ip; + int port; + _server = true; + _cid = cid; + if (_wifi->readRemote(_cid, &ip, &port)) { + set_address(ip, port); + } +}
--- a/Socket/TCPSocketConnection.h Thu Dec 20 15:08:58 2012 +0000 +++ b/Socket/TCPSocketConnection.h Sun Jan 27 14:31:19 2013 +0000 @@ -1,76 +1,81 @@ -/* Copyright (C) 2012 mbed.org, 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. - */ - -#ifndef TCPSOCKET_H -#define TCPSOCKET_H - -#include "Socket.h" -#include "Endpoint.h" - -/** -TCP socket connection -*/ -class TCPSocketConnection: public Socket, public Endpoint { - -public: - /** TCP socket connection - */ - TCPSocketConnection(); - - /** Connects this TCP socket to the server - \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS. - \param port The host's port to connect to. - \return 0 on success, -1 on failure. - */ - int connect(const char* host, const int port); - - /** Check if the socket is connected - \return true if connected, false otherwise. - */ - bool is_connected(void); - - /** Send data to the remote host. - \param data The buffer to send to the host. - \param length The length of the buffer to send. - \return the number of written bytes on success (>=0) or -1 on failure - */ - int send(char* data, int length); - - /** Send all the data to the remote host. - \param data The buffer to send to the host. - \param length The length of the buffer to send. - \return the number of written bytes on success (>=0) or -1 on failure - */ - int send_all(char* data, int length); - - /** Receive data from the remote host. - \param data The buffer in which to store the data received from the host. - \param length The maximum length of the buffer. - \return the number of received bytes on success (>=0) or -1 on failure - */ - int receive(char* data, int length); - - /** Receive all the data from the remote host. - \param data The buffer in which to store the data received from the host. - \param length The maximum length of the buffer. - \return the number of received bytes on success (>=0) or -1 on failure - */ - int receive_all(char* data, int length); -}; - -#endif +/* Copyright (C) 2012 mbed.org, 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. + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ + +#ifndef TCPSOCKET_H +#define TCPSOCKET_H + +#include "Socket.h" +#include "Endpoint.h" + +/** +TCP socket connection +*/ +class TCPSocketConnection: public Socket, public Endpoint { + +public: + /** TCP socket connection + */ + TCPSocketConnection(); + + /** Connects this TCP socket to the server + \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS. + \param port The host's port to connect to. + \return 0 on success, -1 on failure. + */ + int connect(const char* host, const int port); + + /** Check if the socket is connected + \return true if connected, false otherwise. + */ + bool is_connected(void); + + /** Send data to the remote host. + \param data The buffer to send to the host. + \param length The length of the buffer to send. + \return the number of written bytes on success (>=0) or -1 on failure + */ + int send(char* data, int length); + + /** Send all the data to the remote host. + \param data The buffer to send to the host. + \param length The length of the buffer to send. + \return the number of written bytes on success (>=0) or -1 on failure + */ + int send_all(char* data, int length); + + /** Receive data from the remote host. + \param data The buffer in which to store the data received from the host. + \param length The maximum length of the buffer. + \return the number of received bytes on success (>=0) or -1 on failure + */ + int receive(char* data, int length); + + /** Receive all the data from the remote host. + \param data The buffer in which to store the data received from the host. + \param length The maximum length of the buffer. + \return the number of received bytes on success (>=0) or -1 on failure + */ + int receive_all(char* data, int length); + + void confCID (int cid); +}; + +#endif
--- a/Socket/TCPSocketServer.cpp Thu Dec 20 15:08:58 2012 +0000 +++ b/Socket/TCPSocketServer.cpp Sun Jan 27 14:31:19 2013 +0000 @@ -1,90 +1,60 @@ -/* Copyright (C) 2012 mbed.org, 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. - */ - -#include "TCPSocketServer.h" -#include <string> - -TCPSocketServer::TCPSocketServer() {} - -// Server initialization -int TCPSocketServer::bind(int port) { - char cmd[20]; - - // set TCP protocol - wifi->setProtocol(TCP); - - // set local port - sprintf(cmd, "set i l %d\r", port); - if (!wifi->sendCommand(cmd, "AOK")) - return -1; - - // save - if (!wifi->sendCommand("save\r", "Stor")) - return -1; - - // reboot - wifi->reboot(); - - // connect the network - if (wifi->isDHCP()) { - if (!wifi->sendCommand("join\r", "DHCP=ON", NULL, 10000)) - return -1; - } else { - if (!wifi->sendCommand("join\r", "Associated", NULL, 10000)) - return -1; - } - - // exit - wifi->exit(); - - wait(0.2); - wifi->flush(); - return 0; -} - -int TCPSocketServer::listen(int backlog) { - if (backlog != 1) - return -1; - return 0; -} - - -int TCPSocketServer::accept(TCPSocketConnection& connection) { - int nb_available = 0, pos = 0; - char c; - string str; - bool o_find = false; - while (1) { - while(!wifi->readable()); - nb_available = wifi->readable(); - for (int i = 0; i < nb_available; i++) { - c = wifi->getc(); - if (c == '*') { - o_find = true; - } - if (o_find && c != '\r' && c != '\n') { - str += c; - pos = str.find("*OPEN*"); - if (pos != string::npos) { - wifi->flush(); - return 0; - } - } - } - } +/* Copyright (C) 2012 mbed.org, 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. + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ + +#include "TCPSocketServer.h" +#include <string> + +TCPSocketServer::TCPSocketServer() {} + +// Server initialization +int TCPSocketServer::bind(int port) { + _port = port; + return 0; +} + +int TCPSocketServer::listen(int backlog) { + char cmd[CFG_CMD_SIZE]; + + _server = true; + if (_cid < 0) { + // Socket open + _server = false; + sprintf(cmd, "AT+NSTCP=%d", _port); + if (_wifi->sendCommand(cmd, GSwifi::RES_CONNECT) == false) return -1; + _cid = _wifi->readCID(); + } + + if (backlog != 1) + return -1; + return 0; +} + + +int TCPSocketServer::accept(TCPSocketConnection& connection) { + int acid; + while (1) { + acid = _wifi->readACID(); + if (acid >= 0) { + connection.confCID(acid); + return 0; + } + } } \ No newline at end of file
--- a/Socket/TCPSocketServer.h Thu Dec 20 15:08:58 2012 +0000 +++ b/Socket/TCPSocketServer.h Sun Jan 27 14:31:19 2013 +0000 @@ -15,6 +15,9 @@ * 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. */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ #ifndef TCPSOCKETSERVER_H #define TCPSOCKETSERVER_H
--- a/Socket/UDPSocket.cpp Thu Dec 20 15:08:58 2012 +0000 +++ b/Socket/UDPSocket.cpp Sun Jan 27 14:31:19 2013 +0000 @@ -1,185 +1,158 @@ -/* Copyright (C) 2012 mbed.org, 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. - */ - -#include "UDPSocket.h" - -#include <string> -#include <algorithm> - -UDPSocket::UDPSocket() -{ - endpoint_configured = false; - endpoint_read = false; -} - -int UDPSocket::init(void) -{ - wifi->setProtocol(UDP); - wifi->exit(); - return 0; -} - -// Server initialization -int UDPSocket::bind(int port) -{ - char cmd[17]; - - // set local port - sprintf(cmd, "set i l %d\r", port); - if (!wifi->sendCommand(cmd, "AOK")) - return -1; - - // save - if (!wifi->sendCommand("save\r", "Stor")) - return -1; - - // reboot - wifi->reboot(); - - // set udp protocol - wifi->setProtocol(UDP); - - // connect the network - if (wifi->isDHCP()) { - if (!wifi->sendCommand("join\r", "DHCP=ON", NULL, 10000)) - return -1; - } else { - if (!wifi->sendCommand("join\r", "Associated", NULL, 10000)) - return -1; - } - - // exit - wifi->exit(); - wifi->flush(); - return 0; -} - -// -1 if unsuccessful, else number of bytes written -int UDPSocket::sendTo(Endpoint &remote, char *packet, int length) -{ - Timer tmr; - int idx = 0; - - confEndpoint(remote); - - tmr.start(); - - while ((tmr.read_ms() < _timeout) || _blocking) { - - idx += wifi->send(packet, length); - - if (idx == length) - return idx; - } - return (idx == 0) ? -1 : idx; -} - -// -1 if unsuccessful, else number of bytes received -int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length) -{ - Timer tmr; - int idx = 0; - int nb_available = 0; - int time = -1; - - if (_blocking) { - while (1) { - nb_available = wifi->readable(); - if (nb_available != 0) { - break; - } - } - } - - tmr.start(); - - while (time < _timeout) { - - nb_available = wifi->readable(); - for (int i = 0; i < min(nb_available, length); i++) { - buffer[idx] = wifi->getc(); - idx++; - } - - if (idx == length) { - break; - } - - time = tmr.read_ms(); - } - - readEndpoint(remote); - return (idx == 0) ? -1 : idx; -} - -bool UDPSocket::confEndpoint(Endpoint & ep) -{ - char * host; - char cmd[30]; - if (!endpoint_configured) { - host = ep.get_address(); - if (host[0] != '\0') { - // set host - sprintf(cmd, "set i h %s\r", host); - if (!wifi->sendCommand(cmd, "AOK")) - return false; - - // set remote port - sprintf(cmd, "set i r %d\r", ep.get_port()); - if (!wifi->sendCommand(cmd, "AOK")) - return false; - - wifi->exit(); - endpoint_configured = true; - return true; - } - } - return true; -} - -bool UDPSocket::readEndpoint(Endpoint & ep) -{ - char recv[256]; - int begin = 0; - int end = 0; - string str; - string addr; - int port; - if (!endpoint_read) { - if (!wifi->sendCommand("get ip\r", NULL, recv)) - return false; - wifi->exit(); - str = recv; - begin = str.find("HOST="); - end = str.find("PROTO="); - if (begin != string::npos && end != string::npos) { - str = str.substr(begin + 5, end - begin - 5); - int pos = str.find(":"); - if (pos != string::npos) { - addr = str.substr(0, pos); - port = atoi(str.substr(pos + 1).c_str()); - ep.set_address(addr.c_str(), port); - endpoint_read = true; - wifi->flush(); - return true; - } - } - wifi->flush(); - } - return false; -} +/* Copyright (C) 2012 mbed.org, 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. + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ + +#include "UDPSocket.h" + +#include <string> +#include <algorithm> + +UDPSocket::UDPSocket() +{ + endpoint_connected = false; +} + +int UDPSocket::init(void) +{ + _server = false; + return 0; +} + +// Server initialization +int UDPSocket::bind(int port) +{ + _port = port; + _server = true; + return 0; +} + +// -1 if unsuccessful, else number of bytes written +int UDPSocket::sendTo(Endpoint &remote, char *packet, int length) +{ + Timer tmr; + int idx = 0; + + tmr.start(); + + while ((tmr.read_ms() < _timeout) || _blocking) { + + idx += sendPacket(remote, packet, length); + + if (idx == -1) return -1; + if (idx == length) + return idx; + } + return (idx == 0) ? -1 : idx; +} + +// -1 if unsuccessful, else number of bytes received +int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length) +{ + Timer tmr; + int idx = 0; + int nb_available = 0; + int time = -1; + + if (_cid < 0 || !_wifi->is_connected(_cid)) { + // Socket open + char cmd[CFG_CMD_SIZE]; + if (_server) { + sprintf(cmd, "AT+NSUDP=%d", _port); + } else { + sprintf(cmd, "AT+NCUDP=%s,%d", remote.get_address(), remote.get_port()); + if (_port) { + sprintf(&cmd[strlen(cmd)], ",%d", _port); + } + } + if (_wifi->sendCommand(cmd, GSwifi::RES_CONNECT) == false) return -1; + _cid = _wifi->readCID(); + } + + if (_blocking) { + while (1) { + nb_available = _wifi->readable(_cid); + if (nb_available != 0) { + break; + } + } + } + + tmr.start(); + + while (time < _timeout) { + + nb_available = _wifi->readable(_cid); + for (int i = 0; i < min(nb_available, length); i++) { + buffer[idx] = _wifi->getc(_cid); + idx++; + } + + if (idx == length) { + break; + } + + time = tmr.read_ms(); + } + + if (_server) { + char *ip; + int port; + if (_wifi->readRemote(_cid, &ip, &port)) { + remote.set_address(ip, port); + } + } + return (idx == 0) ? -1 : idx; +} + +int UDPSocket::sendPacket (Endpoint &ep, const char *buf, int len) +{ + char cmd[CFG_CMD_SIZE]; + Timer tmr; + int result = 0; + + if (_cid < 0 || !_wifi->is_connected(_cid)) { + // Socket open + char cmd[CFG_CMD_SIZE]; + if (_server) { + sprintf(cmd, "AT+NSUDP=%d", _port); + } else { + sprintf(cmd, "AT+NCUDP=%s,%d", ep.get_address(), ep.get_port()); + if (_port) { + sprintf(&cmd[strlen(cmd)], ",%d", _port); + } + } + if (_wifi->sendCommand(cmd, GSwifi::RES_CONNECT) == false) return -1; + _cid = _wifi->readCID(); + } + + if (_server) { + // UDP Server + sprintf(cmd, "\x1bY%X%s:%d:%04d", _cid, ep.get_address(), ep.get_port(), len); + _wifi->send(cmd, strlen(cmd)); + result = _wifi->send(buf, len, GSwifi::RES_NORMAL); + } else { + // UDP Client + sprintf(cmd, "\x1bZ%X%04d", _cid, len); + _wifi->send(cmd, strlen(cmd)); + result = _wifi->send(buf, len, GSwifi::RES_NORMAL); + } + + return result; +}
--- a/Socket/UDPSocket.h Thu Dec 20 15:08:58 2012 +0000 +++ b/Socket/UDPSocket.h Sun Jan 27 14:31:19 2013 +0000 @@ -1,75 +1,76 @@ -/* Copyright (C) 2012 mbed.org, 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. - */ - -#ifndef UDPSOCKET_H -#define UDPSOCKET_H - -#include "Endpoint.h" -#include "Socket.h" - -#include <cstdint> - -/** -UDP Socket -*/ -class UDPSocket: public Socket { - -public: - /** Instantiate an UDP Socket. - */ - UDPSocket(); - - /** Init the UDP Client Socket without binding it to any specific port - \return 0 on success, -1 on failure. - */ - int init(void); - - /** Bind a UDP Server Socket to a specific port - \param port The port to listen for incoming connections on - \return 0 on success, -1 on failure. - */ - int bind(int port = -1); - - /** Send a packet to a remote endpoint - \param remote The remote endpoint - \param packet The packet to be sent - \param length The length of the packet to be sent - \return the number of written bytes on success (>=0) or -1 on failure - */ - int sendTo(Endpoint &remote, char *packet, int length); - - /** Receive a packet from a remote endpoint - \param remote The remote endpoint - \param buffer The buffer for storing the incoming packet data. If a packet - is too long to fit in the supplied buffer, excess bytes are discarded - \param length The length of the buffer - \return the number of received bytes on success (>=0) or -1 on failure - */ - int receiveFrom(Endpoint &remote, char *buffer, int length); - -private: - bool confEndpoint(Endpoint & ep); - bool readEndpoint(Endpoint & ep); - bool endpoint_configured; - bool endpoint_read; - -}; - -#include "def.h" - -#endif +/* Copyright (C) 2012 mbed.org, 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. + */ +/* Copyright (C) 2013 gsfan, MIT License + * port to the GainSpan Wi-FI module GS1011 + */ + +#ifndef UDPSOCKET_H +#define UDPSOCKET_H + +#include "Endpoint.h" +#include "Socket.h" + +#include <cstdint> + +/** +UDP Socket +*/ +class UDPSocket: public Socket { + +public: + /** Instantiate an UDP Socket. + */ + UDPSocket(); + + /** Init the UDP Client Socket without binding it to any specific port + \return 0 on success, -1 on failure. + */ + int init(void); + + /** Bind a UDP Server Socket to a specific port + \param port The port to listen for incoming connections on + \return 0 on success, -1 on failure. + */ + int bind(int port = -1); + + /** Send a packet to a remote endpoint + \param remote The remote endpoint + \param packet The packet to be sent + \param length The length of the packet to be sent + \return the number of written bytes on success (>=0) or -1 on failure + */ + int sendTo(Endpoint &remote, char *packet, int length); + + /** Receive a packet from a remote endpoint + \param remote The remote endpoint + \param buffer The buffer for storing the incoming packet data. If a packet + is too long to fit in the supplied buffer, excess bytes are discarded + \param length The length of the buffer + \return the number of received bytes on success (>=0) or -1 on failure + */ + int receiveFrom(Endpoint &remote, char *buffer, int length); + +private: + bool endpoint_connected; + int sendPacket (Endpoint &ep, const char *buf, int len); + +}; + +#include "def.h" + +#endif
--- a/Wifly/CBuffer.h Thu Dec 20 15:08:58 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* Copyright (C) 2012 mbed.org, 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. - */ - -#ifndef CIRCBUFFER_H_ -#define CIRCBUFFER_H_ - -template <class T> -class CircBuffer { -public: - CircBuffer(int length) { - write = 0; - read = 0; - size = length + 1; - buf = (T *)malloc(size * sizeof(T)); - }; - - bool isFull() { - return (((write + 1) % size) == read); - }; - - bool isEmpty() { - return (read == write); - }; - - void queue(T k) { - if (isFull()) { - read++; - read %= size; - } - buf[write++] = k; - write %= size; - } - - void flush() { - read = 0; - write = 0; - } - - - uint32_t available() { - return (write >= read) ? write - read : size - read + write; - }; - - bool dequeue(T * c) { - bool empty = isEmpty(); - if (!empty) { - *c = buf[read++]; - read %= size; - } - return(!empty); - }; - -private: - volatile uint32_t write; - volatile uint32_t read; - uint32_t size; - T * buf; -}; - -#endif
--- a/Wifly/Wifly.cpp Thu Dec 20 15:08:58 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,546 +0,0 @@ -/* Copyright (C) 2012 mbed.org, 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. - */ - -#include "mbed.h" -#include "Wifly.h" -#include <string> -#include <algorithm> - -//Debug is disabled by default -#if (0 && !defined(TARGET_LPC11U24)) -#define DBG(x, ...) std::printf("[Wifly : DBG]"x"\r\n", ##__VA_ARGS__); -#define WARN(x, ...) std::printf("[Wifly : WARN]"x"\r\n", ##__VA_ARGS__); -#define ERR(x, ...) std::printf("[Wifly : ERR]"x"\r\n", ##__VA_ARGS__); -#else -#define DBG(x, ...) -#define WARN(x, ...) -#define ERR(x, ...) -#endif - -#if !defined(TARGET_LPC11U24) -#define INFO(x, ...) printf("[Wifly : INFO]"x"\r\n", ##__VA_ARGS__); -#else -#define INFO(x, ...) -#endif - -#define MAX_TRY_JOIN 3 - -Wifly * Wifly::inst; - -Wifly::Wifly( PinName tx, PinName rx, PinName _reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec): - wifi(tx, rx), reset_pin(_reset), tcp_status(tcp_status), buf_wifly(256) -{ - memset(&state, 0, sizeof(state)); - state.sec = sec; - - // change all ' ' in '$' in the ssid and the passphrase - strcpy(this->ssid, ssid); - for (int i = 0; i < strlen(ssid); i++) { - if (this->ssid[i] == ' ') - this->ssid[i] = '$'; - } - strcpy(this->phrase, phrase); - for (int i = 0; i < strlen(phrase); i++) { - if (this->phrase[i] == ' ') - this->phrase[i] = '$'; - } - - inst = this; - attach_rx(false); - state.cmd_mode = false; -} - -bool Wifly::join() -{ - char cmd[20]; - - for (int i= 0; i < MAX_TRY_JOIN; i++) { - - // no auto join - if (!sendCommand("set w j 0\r", "AOK")) - continue; - - //no echo - if (!sendCommand("set u m 1\r", "AOK")) - continue; - - // set time - if (!sendCommand("set c t 30\r", "AOK")) - continue; - - // set size - if (!sendCommand("set c s 1024\r", "AOK")) - continue; - - // red led on when tcp connection active - if (!sendCommand("set s i 0x40\r", "AOK")) - continue; - - // no string sent to the tcp client - if (!sendCommand("set c r 0\r", "AOK")) - continue; - - // tcp protocol - if (!sendCommand("set i p 2\r", "AOK")) - continue; - - // tcp retry - if (!sendCommand("set i f 0x7\r", "AOK")) - continue; - - // set dns server - if (!sendCommand("set d n rn.microchip.com\r", "AOK")) - continue; - - //dhcp - sprintf(cmd, "set i d %d\r", (state.dhcp) ? 1 : 0); - if (!sendCommand(cmd, "AOK")) - continue; - - // ssid - sprintf(cmd, "set w s %s\r", ssid); - if (!sendCommand(cmd, "AOK")) - continue; - - //auth - sprintf(cmd, "set w a %d\r", state.sec); - if (!sendCommand(cmd, "AOK")) - continue; - - // if no dhcp, set ip, netmask and gateway - if (!state.dhcp) { - DBG("not dhcp\r"); - - sprintf(cmd, "set i a %s\r\n", ip); - if (!sendCommand(cmd, "AOK")) - continue; - - sprintf(cmd, "set i n %s\r", netmask); - if (!sendCommand(cmd, "AOK")) - continue; - - sprintf(cmd, "set i g %s\r", gateway); - if (!sendCommand(cmd, "AOK")) - continue; - } - - //key step - if (state.sec != NONE) { - if (state.sec == WPA) - sprintf(cmd, "set w p %s\r", phrase); - else if (state.sec == WEP_128) - sprintf(cmd, "set w k %s\r", phrase); - - if (!sendCommand(cmd, "AOK")) - continue; - } - - //join the network (10s timeout) - if (state.dhcp) { - if (!sendCommand("join\r", "DHCP=ON", NULL, 10000)) - continue; - } else { - if (!sendCommand("join\r", "Associated", NULL, 10000)) - continue; - } - - if (!sendCommand("save\r", "Stor")) - continue; - - exit(); - - state.associated = true; - INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, getStringSecurity()); - return true; - } - return false; -} - - -bool Wifly::setProtocol(Protocol p) -{ - // use udp auto pairing - char cmd[20]; - sprintf(cmd, "set i p %d\r", p); - if (!sendCommand(cmd, "AOK")) - return false; - - switch(p) { - case TCP: - // set ip flags: tcp retry enabled - if (!sendCommand("set i f 0x07\r", "AOK")) - return false; - break; - case UDP: - // set ip flags: udp auto pairing enabled - if (!sendCommand("set i h 0.0.0.0\r", "AOK")) - return false; - if (!sendCommand("set i f 0x40\r", "AOK")) - return false; - break; - } - state.proto = p; - return true; -} - -char * Wifly::getStringSecurity() -{ - switch(state.sec) { - case NONE: - return "NONE"; - case WEP_128: - return "WEP_128"; - case WPA: - return "WPA"; - } - return "UNKNOWN"; -} - -bool Wifly::connect(const char * host, int port) -{ - char rcv[20]; - char cmd[20]; - - // try to open - sprintf(cmd, "open %s %d\r", host, port); - if (sendCommand(cmd, "OPEN", NULL, 10000)) { - state.tcp = true; - state.cmd_mode = false; - return true; - } - - // if failed, retry and parse the response - if (sendCommand(cmd, NULL, rcv, 5000)) { - if (strstr(rcv, "OPEN") == NULL) { - if (strstr(rcv, "Connected") != NULL) { - wait(0.25); - if (!sendCommand("close\r", "CLOS")) - return false; - wait(0.25); - if (!sendCommand(cmd, "OPEN", NULL, 10000)) - return false; - } else { - return false; - } - } - } else { - return false; - } - - state.tcp = true; - state.cmd_mode = false; - - return true; -} - - -bool Wifly::gethostbyname(const char * host, char * ip) -{ - string h = host; - char cmd[30], rcv[100]; - int l = 0; - char * point; - int nb_digits = 0; - - // no dns needed - int pos = h.find("."); - if (pos != string::npos) { - string sub = h.substr(0, h.find(".")); - nb_digits = atoi(sub.c_str()); - } - //printf("substrL %s\r\n", sub.c_str()); - if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) { - strcpy(ip, host); - } - // dns needed - else { - nb_digits = 0; - sprintf(cmd, "lookup %s\r", host); - if (!sendCommand(cmd, NULL, rcv)) - return false; - - // look for the ip address - char * begin = strstr(rcv, "=") + 1; - for (int i = 0; i < 3; i++) { - point = strstr(begin + l, "."); - DBG("str: %s", begin + l); - l += point - (begin + l) + 1; - } - DBG("str: %s", begin + l); - while(*(begin + l + nb_digits) >= '0' && *(begin + l + nb_digits) <= '9') { - DBG("digit: %c", *(begin + l + nb_digits)); - nb_digits++; - } - memcpy(ip, begin, l + nb_digits); - ip[l+nb_digits] = 0; - DBG("ip from dns: %s", ip); - } - return true; -} - - -void Wifly::flush() -{ - buf_wifly.flush(); -} - -bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int timeout) -{ - if (!state.cmd_mode) { - cmdMode(); - } - if (send(cmd, strlen(cmd), ack, res, timeout) == -1) { - ERR("sendCommand: cannot %s\r\n", cmd); - exit(); - return false; - } - return true; -} - -bool Wifly::cmdMode() -{ - // if already in cmd mode, return - if (state.cmd_mode) - return true; - - if (send("$$$", 3, "CMD") == -1) { - ERR("cannot enter in cmd mode\r\n"); - exit(); - return false; - } - state.cmd_mode = true; - return true; -} - -bool Wifly::disconnect() -{ - // if already disconnected, return - if (!state.associated) - return true; - - if (!sendCommand("leave\r", "DeAuth")) - return false; - exit(); - - state.associated = false; - return true; - -} - -bool Wifly::is_connected() -{ - return (tcp_status.read() == 1) ? true : false; -} - - -void Wifly::reset() -{ - reset_pin = 0; - wait(0.2); - reset_pin = 1; - wait(0.2); -} - -bool Wifly::reboot() -{ - // if already in cmd mode, return - if (!sendCommand("reboot\r")) - return false; - - wait(0.3); - - state.cmd_mode = false; - return true; -} - -bool Wifly::close() -{ - // if not connected, return - if (!state.tcp) - return true; - - wait(0.25); - if (!sendCommand("close\r", "CLOS")) - return false; - exit(); - - state.tcp = false; - return true; -} - - -int Wifly::putc(char c) -{ - while (!wifi.writeable()); - return wifi.putc(c); -} - - -bool Wifly::exit() -{ - flush(); - if (!state.cmd_mode) - return true; - if (!sendCommand("exit\r", "EXIT")) - return false; - state.cmd_mode = false; - flush(); - return true; -} - - -int Wifly::readable() -{ - return buf_wifly.available(); -} - -int Wifly::writeable() -{ - return wifi.writeable(); -} - -char Wifly::getc() -{ - char c; - while (!buf_wifly.available()); - buf_wifly.dequeue(&c); - return c; -} - -void Wifly::handler_rx(void) -{ - //read characters - while (wifi.readable()) - buf_wifly.queue(wifi.getc()); -} - -void Wifly::attach_rx(bool callback) -{ - if (!callback) - wifi.attach(NULL); - else - wifi.attach(this, &Wifly::handler_rx); -} - - -int Wifly::send(const char * str, int len, const char * ACK, char * res, int timeout) -{ - char read; - size_t found = string::npos; - string checking; - Timer tmr; - int result = 0; - - DBG("will send: %s\r\n",str); - - attach_rx(false); - - //We flush the buffer - while (wifi.readable()) - wifi.getc(); - - if (!ACK || !strcmp(ACK, "NO")) { - for (int i = 0; i < len; i++) - result = (putc(str[i]) == str[i]) ? result + 1 : result; - } else { - //We flush the buffer - while (wifi.readable()) - wifi.getc(); - - tmr.start(); - for (int i = 0; i < len; i++) - result = (putc(str[i]) == str[i]) ? result + 1 : result; - - while (1) { - if (tmr.read_ms() > timeout) { - //We flush the buffer - while (wifi.readable()) - wifi.getc(); - - DBG("check: %s\r\n", checking.c_str()); - - attach_rx(true); - return -1; - } else if (wifi.readable()) { - read = wifi.getc(); - if ( read != '\r' && read != '\n') { - checking += read; - found = checking.find(ACK); - if (found != string::npos) { - wait(0.01); - - //We flush the buffer - while (wifi.readable()) - wifi.getc(); - - break; - } - } - } - } - DBG("check: %s\r\n", checking.c_str()); - - attach_rx(true); - return result; - } - - //the user wants the result from the command (ACK == NULL, res != NULL) - if ( res != NULL) { - int i = 0; - Timer timeout; - timeout.start(); - tmr.reset(); - while (1) { - if (timeout.read() > 2) { - if (i == 0) { - res = NULL; - break; - } - res[i] = '\0'; - DBG("user str 1: %s\r\n", res); - - break; - } else { - if (tmr.read_ms() > 300) { - res[i] = '\0'; - DBG("user str: %s\r\n", res); - - break; - } - if (wifi.readable()) { - tmr.start(); - read = wifi.getc(); - - // we drop \r and \n - if ( read != '\r' && read != '\n') { - res[i++] = read; - } - } - } - } - DBG("user str: %s\r\n", res); - } - - //We flush the buffer - while (wifi.readable()) - wifi.getc(); - - attach_rx(true); - DBG("result: %d\r\n", result) - return result; -} \ No newline at end of file
--- a/Wifly/Wifly.h Thu Dec 20 15:08:58 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,238 +0,0 @@ -/* Copyright (C) 2012 mbed.org, 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. - * - * @section DESCRIPTION - * - * Wifly RN131-C, wifi module - * - * Datasheet: - * - * http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Wireless/WiFi/WiFly-RN-UM.pdf - */ - -#ifndef WIFLY_H -#define WIFLY_H - -#include "mbed.h" -#include "CBuffer.h" - -#define DEFAULT_WAIT_RESP_TIMEOUT 500 - -enum Security { - NONE = 0, - WEP_128 = 1, - WPA = 3 -}; - -enum Protocol { - UDP = (1 << 0), - TCP = (1 << 1) -}; - -class Wifly -{ - -public: - /* - * Constructor - * - * @param tx mbed pin to use for tx line of Serial interface - * @param rx mbed pin to use for rx line of Serial interface - * @param reset reset pin of the wifi module () - * @param tcp_status connection status pin of the wifi module (GPIO 6) - * @param ssid ssid of the network - * @param phrase WEP or WPA key - * @param sec Security type (NONE, WEP_128 or WPA) - */ - Wifly( PinName tx, PinName rx, PinName reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec); - - /* - * Connect the wifi module to the ssid contained in the constructor. - * - * @return true if connected, false otherwise - */ - bool join(); - - /* - * Disconnect the wifly module from the access point - * - * @ returns true if successful - */ - bool disconnect(); - - /* - * Open a tcp connection with the specified host on the specified port - * - * @param host host (can be either an ip address or a name. If a name is provided, a dns request will be established) - * @param port port - * @ returns true if successful - */ - bool connect(const char * host, int port); - - - /* - * Set the protocol (UDP or TCP) - * - * @param p protocol - * @ returns true if successful - */ - bool setProtocol(Protocol p); - - /* - * Reset the wifi module - */ - void reset(); - - /* - * Reboot the wifi module - */ - bool reboot(); - - /* - * Check if characters are available - * - * @return number of available characters - */ - int readable(); - - /* - * Check if characters are available - * - * @return number of available characters - */ - int writeable(); - - /* - * Check if a tcp link is active - * - * @returns true if successful - */ - bool is_connected(); - - /* - * Read a character - * - * @return the character read - */ - char getc(); - - /* - * Flush the buffer - */ - void flush(); - - /* - * Write a character - * - * @param the character which will be written - */ - int putc(char c); - - - /* - * To enter in command mode (we can configure the module) - * - * @return true if successful, false otherwise - */ - bool cmdMode(); - - /* - * To exit the command mode - * - * @return true if successful, false otherwise - */ - bool exit(); - - /* - * Close a tcp connection - * - * @ returns true if successful - */ - bool close(); - - /* - * Send a string to the wifi module by serial port. This function desactivates the user interrupt handler when a character is received to analyze the response from the wifi module. - * Useful to send a command to the module and wait a response. - * - * - * @param str string to be sent - * @param len string length - * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO") - * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL) - * - * @return true if ACK has been found in the response from the wifi module. False otherwise or if there is no response in 5s. - */ - int send(const char * str, int len, const char * ACK = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT); - - /* - * Send a command to the wify module. Check if the module is in command mode. If not enter in command mode - * - * @param str string to be sent - * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO") - * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL) - * - * @returns true if successful - */ - bool sendCommand(const char * cmd, const char * ack = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT); - - /* - * Return true if the module is using dhcp - * - * @returns true if the module is using dhcp - */ - bool isDHCP() { - return state.dhcp; - } - - bool gethostbyname(const char * host, char * ip); - - static Wifly * getInstance() { - return inst; - }; - -protected: - Serial wifi; - DigitalOut reset_pin; - DigitalIn tcp_status; - char phrase[30]; - char ssid[30]; - const char * ip; - const char * netmask; - const char * gateway; - int channel; - CircBuffer<char> buf_wifly; - - static Wifly * inst; - - void attach_rx(bool null); - void handler_rx(void); - - - typedef struct STATE { - bool associated; - bool tcp; - bool dhcp; - Security sec; - Protocol proto; - bool cmd_mode; - } State; - - State state; - char * getStringSecurity(); -}; - -#endif \ No newline at end of file
--- a/WiflyInterface.cpp Thu Dec 20 15:08:58 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -#include "WiflyInterface.h" - -WiflyInterface::WiflyInterface( PinName tx, PinName rx, PinName reset, PinName tcp_status, - const char * ssid, const char * phrase, Security sec) : - Wifly(tx, rx, reset, tcp_status, ssid, phrase, sec) -{ - ip_set = false; -} - -int WiflyInterface::init() -{ - state.dhcp = true; - reset(); - return 0; -} - -int WiflyInterface::init(const char* ip, const char* mask, const char* gateway) -{ - state.dhcp = false; - this->ip = ip; - strcpy(ip_string, ip); - ip_set = true; - this->netmask = mask; - this->gateway = gateway; - reset(); - - return 0; -} - -int WiflyInterface::connect() -{ - return join(); -} - -int WiflyInterface::disconnect() -{ - return Wifly::disconnect(); -} - -char * WiflyInterface::getIPAddress() -{ - char * match = 0; - if (!ip_set) { - if (!sendCommand("get ip a\r", NULL, ip_string)) - return NULL; - exit(); - flush(); - match = strstr(ip_string, "<"); - if (match != NULL) { - *match = '\0'; - } - if (strlen(ip_string) < 6) { - match = strstr(ip_string, ">"); - if (match != NULL) { - int len = strlen(match + 1); - memcpy(ip_string, match + 1, len); - } - } - ip_set = true; - } - return ip_string; -} \ No newline at end of file
--- a/WiflyInterface.h Thu Dec 20 15:08:58 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* WiflyInterface.h */ -/* Copyright (C) 2012 mbed.org, 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. - */ - -#ifndef WIFLYINTERFACE_H_ -#define WIFLYINTERFACE_H_ - -#include "Wifly.h" - - /** Interface using Wifly to connect to an IP-based network - * - */ -class WiflyInterface: public Wifly { -public: - - /** - * Constructor - * - * \param tx mbed pin to use for tx line of Serial interface - * \param rx mbed pin to use for rx line of Serial interface - * \param reset reset pin of the wifi module () - * \param tcp_status connection status pin of the wifi module (GPIO 6) - * \param ssid ssid of the network - * \param phrase WEP or WPA key - * \param sec Security type (NONE, WEP_128 or WPA) - */ - WiflyInterface(PinName tx, PinName rx, PinName reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec = NONE); - - /** Initialize the interface with DHCP. - * Initialize the interface and configure it to use DHCP (no connection at this point). - * \return 0 on success, a negative number on failure - */ - int init(); //With DHCP - - /** Initialize the interface with a static IP address. - * Initialize the interface and configure it with the following static configuration (no connection at this point). - * \param ip the IP address to use - * \param mask the IP address mask - * \param gateway the gateway to use - * \return 0 on success, a negative number on failure - */ - int init(const char* ip, const char* mask, const char* gateway); - - /** Connect - * Bring the interface up, start DHCP if needed. - * \return 0 on success, a negative number on failure - */ - int connect(); - - /** Disconnect - * Bring the interface down - * \return 0 on success, a negative number on failure - */ - int disconnect(); - - /** Get IP address - * - * @ returns ip address - */ - char* getIPAddress(); - -private: - char ip_string[20]; - bool ip_set; -}; - -#include "TCPSocketConnection.h" -#include "TCPSocketServer.h" -#include "UDPSocket.h" - -#endif /* WIFLYINTERFACE_H_ */