see http://mbed.org/users/okini3939/notebook/wattmeter-shield-on-mbed/
Fork of GSwifi_xively by
Revision 4:9a2415f2ab07, committed 2013-11-27
- Comitter:
- okini3939
- Date:
- Wed Nov 27 08:18:45 2013 +0000
- Parent:
- 3:1abf2be8b312
- Commit message:
- update GSwifiInterface library
Changed in this revision
--- a/GSwifi.lib Tue Aug 20 04:34:57 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/gsfan/code/GSwifi/#72f70748f6e8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/CBuffer.h Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,78 @@ +/* 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)); + if (buf == NULL) + error("Can't allocate memory"); + }; + + bool isFull() { + return (((write + 1) % size) == read); + }; + + bool isEmpty() { + return (read == write); + }; + + void queue(T k) { + if (isFull()) { +// read++; +// read %= size; + return; + } + 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/GSwifiInterface/GSwifi/GSwifi.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,433 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#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, PinName alarm, int baud): + _gs(tx, rx), _reset(reset) +{ + _inst = this; + memset(&_state, 0, sizeof(_state)); + memset(&_con, 0, sizeof(_con)); + _state.initialized = false; + _state.status = STAT_READY; + _state.cid = -1; + _state.buf = new CircBuffer<char>(CFG_DATA_SIZE); +#ifdef CFG_ENABLE_RTOS + for (int i = 0; i < 16; i ++) { + _con[i].buf = new CircBuffer<char>(CFG_DATA_SIZE); + if (_con[i].buf == NULL) + error("CircBuffer failed"); + } + _threadPoll = NULL; +#endif + + setReset(true); + initUart(cts, rts, alarm, baud); + setAlarm(true); + wait_ms(10); + setAlarm(false); + wait_ms(100); + setReset(false); + wait_ms(100); +} + +int GSwifi::join() +{ + int i; + bool r = -1; + + _state.wm = WM_INFRASTRUCTURE; + _state.initialized = true; + if (!strlen(_state.name)) { + strncpy(_state.name, CFG_DHCPNAME, sizeof(_state.name)); + } + clearFlags(); + _state.mode = MODE_COMMAND; + sendCommand(NULL, RES_NULL, 0); + if (cmdE(false)) return -1; + if (_flow) { + cmdR(true); + } + cmdBDATA(true); + if (cmdNMAC()) return -1; + cmdWREGDOMAIN(CFG_WREGDOMAIN); + cmdWM(0); // infrastructure + wait_ms(100); + + switch (_state.sec) { + case SEC_NONE: + case SEC_OPEN: + case SEC_WEP: + cmdNDHCP(_state.dhcp, _state.name, DEFAULT_WAIT_RESP_TIMEOUT); + cmdWAUTH(_state.sec); + if (_state.sec != SEC_NONE) { + cmdWWEP(1, _state.pass); + wait_ms(100); + } + for (i = 0; i < CFG_TRYJOIN; i ++) { + r = cmdWA(_state.ssid); + if (!r) break; + DBG("retry\r\n"); + wait_ms(1000); + } + break; + case SEC_WPA_PSK: + case SEC_WPA2_PSK: + cmdNDHCP(_state.dhcp, _state.name, DEFAULT_WAIT_RESP_TIMEOUT); + cmdWAUTH(0); + cmdWPAPSK(_state.ssid, _state.pass); + wait_ms(100); + for (i = 0; i < CFG_TRYJOIN; i ++) { + r = cmdWA(_state.ssid); + if (!r) break; + DBG("retry\r\n"); + wait_ms(1000); + } + break; + case SEC_WPA_ENT: + case SEC_WPA2_ENT: + cmdWAUTH(0); + DBG("Can't support security\r\n"); + break; + case SEC_WPS_BUTTON: + cmdNDHCP(false); + cmdWAUTH(0); + r = cmdWWPS(true); + if (r) break; + if (_state.dhcp) { + r = cmdNDHCP(_state.dhcp, _state.name); + } + cmdWSTATUS(); + cmdWPAPSK(_state.ssid, _state.pass); + break; + case SEC_WPS_PIN: + cmdNDHCP(false); + cmdWAUTH(0); + r = cmdWWPS(true, _state.pass); + if (r) break; + if (_state.dhcp) { + r = cmdNDHCP(_state.dhcp, _state.name); + } + cmdWSTATUS(); + cmdWPAPSK(_state.ssid, _state.pass); + break; + default: + DBG("Can't use security\r\n"); + break; + } + + if (!r) { + // connected + if (! _state.dhcp) { + cmdDNSSET(_state.nameserver); + } + _state.associated = true; +#ifdef CFG_ENABLE_RTOS + _threadPoll = new Thread(&threadPoll); +// _threadPoll = new Thread(&threadPoll, NULL, osPriorityLow); +#endif + } + return r; +} + +int GSwifi::adhock () +{ + bool r = -1; + + _state.wm = WM_ADHOCK; + _state.initialized = true; + clearFlags(); + _state.mode = MODE_COMMAND; + sendCommand(NULL, RES_NULL, 0); + if (cmdE(false)) return -1; + if (_flow) { + cmdR(true); + } + if (cmdNMAC()) return -1; + cmdBDATA(true); + cmdWREGDOMAIN(CFG_WREGDOMAIN); + cmdWM(1); // adhock + wait_ms(100); + + cmdNDHCP(false); + if (! _state.dhcp) { + cmdNSET(_state.ip, _state.netmask, _state.ip); + } + + switch (_state.sec) { + case SEC_NONE: + case SEC_OPEN: + case SEC_WEP: + cmdWAUTH(_state.sec); + if (_state.sec != SEC_NONE) { + cmdWWEP(1, _state.pass); + wait_ms(100); + } + r = cmdWA(_state.ssid); + break; + default: + DBG("Can't use security\r\n"); + break; + } + + if (!r) { + // connected + _state.associated = true; + } + return r; +} + +int GSwifi::limitedap () +{ + bool r = -1; + + _state.wm = WM_LIMITEDAP; + _state.initialized = true; + if (!strlen(_state.name)) { + strncpy(_state.name, CFG_DNSNAME, sizeof(_state.name)); + } + clearFlags(); + _state.mode = MODE_COMMAND; + sendCommand(NULL, RES_NULL, 0); + if (cmdE(false)) return -1; + if (_flow) { + cmdR(true); + } + if (cmdNMAC()) return -1; + cmdBDATA(true); + cmdWREGDOMAIN(CFG_WREGDOMAIN); + cmdWM(2); // limitedap + wait_ms(100); + + cmdNDHCP(false); + if (! _state.dhcp) { + cmdNSET(_state.ip, _state.netmask, _state.ip); + cmdDNSSET(_state.ip); + } + cmdDHCPSRVR(true); + cmdDNS(true, _state.name); + + switch (_state.sec) { + case SEC_NONE: + case SEC_OPEN: + case SEC_WEP: + cmdWAUTH(_state.sec); + if (_state.sec != SEC_NONE) { + cmdWWEP(1, _state.pass); + wait_ms(100); + } + r = cmdWA(_state.ssid); + break; + default: + DBG("Can't use security\r\n"); + break; + } + + if (!r) { + // connected + _state.associated = true; + } + return r; +} + +int GSwifi::dissociate() +{ + int i; + + // if already disconnected, return + if (!_state.associated) + return 0; + +#ifdef CFG_ENABLE_RTOS + if (_threadPoll) { + _threadPoll->terminate(); + delete _threadPoll; + } +#endif + for (i = 0; i < 16; i ++) { + if (_con[i].buf) { + _con[i].buf->flush(); + } + } + cmdNCLOSEALL(); + cmdWD(); + cmdNDHCP(false); + wait_ms(100); + + _state.associated = false; + return 0; + +} + +bool GSwifi::isAssociated() +{ + return _state.associated; +} + +void GSwifi::poll () { +#ifndef CFG_ENABLE_RTOS + static int t = 0; + static Timer timer; + + if (_state.wm == WM_INFRASTRUCTURE && (! isAssociated()) && _state.ssid) { + if (t == 0 || timer.read() > CFG_RECONNECT) { + // Wi-Fi re-associate + if (_state.initialized) { + if (cmdWA(_state.ssid)) { + timer.reset(); + timer.start(); + t = 1; + } else { + _state.associated = true; + timer.stop(); + t = 0; + } + } else { + if (join()) { + timer.reset(); + timer.start(); + t = 1; + } else { + timer.stop(); + t = 0; + } + } + } + } +#else + if (_state.wm == WM_INFRASTRUCTURE && (! isAssociated()) && _state.ssid) { + // Wi-Fi re-associate + if (_state.initialized) { + if (!cmdWA(_state.ssid)) { + _state.associated = true; + } + } else { + join(); + } + } +#endif + + for (int i = 0; i < 16; i ++) { + if (isConnected(i) && _con[i].received && _con[i].buf) + if (_con[i].func != NULL && !_con[i].buf->isEmpty()) { + _con[i].func(i); + if (_con[i].buf->isEmpty()) { + _con[i].received = false; + } + } + } + +#ifdef CFG_ENABLE_HTTPD + httpdPoll(); +#endif +} + +#ifdef CFG_ENABLE_RTOS +void GSwifi::threadPoll (void const *args) { + GSwifi * _wifi = GSwifi::getInstance(); + if (_wifi == NULL) + error("Socket constructor error: no wifly instance available!\r\n"); + + INFO("threadPoll"); + for (;;) { + Thread::signal_wait(1); + Thread::wait(1000); + INFO("disassociated"); + while (!_wifi->isAssociated()){ + _wifi->poll(); + Thread::wait(CFG_RECONNECT * 1000); + } + } +} +#endif + +GSwifi::Status GSwifi::getStatus () { + return _state.status; +} + +int GSwifi::setMacAddress (const char *mac) { + if (cmdNMAC(mac)) return -1; + strncpy(_state.mac, mac, sizeof(_state.mac)); + return 0; +} + +int GSwifi::getMacAddress (char *mac) { + if (cmdNMAC()) return -1; + strcpy(mac, _state.mac); + return 0; +} + +int GSwifi::setAddress (const char *name) { + _state.dhcp = true; + strncpy(_state.name, name, sizeof(_state.name)); + return 0; +} + +int GSwifi::setAddress (const char *ip, const char *netmask, const char *gateway, const char *name) { + _state.dhcp = false; + strncpy(_state.ip, ip, sizeof(_state.ip)); + strncpy(_state.netmask, netmask, sizeof(_state.netmask)); + strncpy(_state.gateway, gateway, sizeof(_state.gateway)); + strncpy(_state.name, name, sizeof(_state.name)); + return 0; +} + +int GSwifi::getAddress (char *ip, char *netmask, char *gateway) { + strcpy(ip, _state.ip); + strcpy(netmask, _state.netmask); + strcpy(gateway, _state.gateway); + return 0; +} + +int GSwifi::setSsid (Security sec, const char *ssid, const char *phrase) { + int i; + + _state.sec = sec; + + // change all ' ' in '$' in the ssid and the passphrase + strncpy(_state.ssid, ssid, sizeof(_state.ssid)); + for (i = 0; i < strlen(_state.ssid); i++) { + if (_state.ssid[i] == ' ') + _state.ssid[i] = '$'; + } + + if (sec == SEC_WEP) { + if (strlen(phrase) == 5 || strlen(phrase) == 13) { + for (i = 0; i < strlen(phrase); i++) { + _state.pass[i * 2] = '0' + ((phrase[i] >> 4) & 0x0f); + _state.pass[i * 2 + 1] = '0' + (phrase[i + 1] & 0x0f); + } + } else { + strncpy(_state.pass, phrase, strlen(phrase)); + } + } else { + strncpy(_state.pass, phrase, sizeof(_state.pass)); + } + for (i = 0; i < strlen(_state.pass); i++) { + if (_state.pass[i] == ' ') + _state.pass[i] = '$'; + } + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi.h Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,678 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * @section DESCRIPTION + * + * GainSpan GS1011, Wi-Fi module + * + * http://www.gainspan.com/modules + */ +/** @file + * @brief Gainspan wi-fi module library for mbed + * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc. + */ + +#ifndef GSwifi_H +#define GSwifi_H + +#include "GSwifi_conf.h" + +#include "mbed.h" +#include "RawSerial.h" +#include "CBuffer.h" +#include <ctype.h> +#include <stdlib.h> +#include <string.h> + +#ifdef CFG_ENABLE_RTOS +#include "rtos.h" +#endif + +//Debug is disabled by default +#if defined(DEBUG) and (!defined(TARGET_LPC11U24)) +#define DBG(x, ...) std::printf("[DBG]" x "\r\n", ##__VA_ARGS__); +#define WARN(x, ...) std::printf("[WARN]" x "\r\n", ##__VA_ARGS__); +#define ERR(x, ...) std::printf("[ERR]" x "\r\n", ##__VA_ARGS__); +#define INFO(x, ...) std::printf("[INFO]" x "\r\n", ##__VA_ARGS__); +#else +#define DBG(x, ...) +#define WARN(x, ...) +#define ERR(x, ...) +#define INFO(x, ...) +#endif + + +/** GSwifi class + */ +class GSwifi +{ + +public: + + /** Wi-Fi mode + */ + enum WiFiMode { + WM_INFRASTRUCTURE, + WM_ADHOCK, + WM_LIMITEDAP, + }; + + /** Wi-Fi security + */ + 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, + SEC_WPS_PIN, + }; + + /** TCP/IP protocol + */ + enum Protocol { + PROTO_UDP = 0, + PROTO_TCP = 1, + PROTO_HTTPGET, + PROTO_HTTPPOST, + PROTO_HTTPD, + }; + + /** Client/Server + */ + enum Type { + TYPE_CLIENT = 0, + TYPE_SERVER = 1, + }; + + enum Response { + RES_NULL, + RES_CONNECT, + RES_WPAPSK, + RES_WPS, + RES_MACADDRESS, + RES_DHCP, + RES_DNSLOOKUP, + RES_HTTP, + RES_RSSI, + RES_TIME, + RES_STATUS, + }; + + enum Mode { + MODE_COMMAND, + MODE_CMDRESP, + MODE_ESCAPE, + MODE_DATA_RX, + MODE_DATA_RX_BULK, + MODE_DATA_RXUDP, + MODE_DATA_RXUDP_BULK, + MODE_DATA_RXHTTP, + MODE_DATA_RAW, + }; + + enum Status { + STAT_NONE, + STAT_READY, + STAT_STANDBY, + STAT_WAKEUP, + STAT_DEEPSLEEP, + }; + + // ----- GSwifi.cpp ----- + /** 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 alarm alarm pin of the wifi module (default NULL) + * \param baud baud rate of Serial interface (default 9600) + */ + GSwifi (PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, PinName alarm = NC, int baud = 9600); + + /** Connect the wifi module to the ssid contained in the constructor. + * @param sec Security type (NONE, WEP_128 or WPA) + * @param ssid ssid of the network + * @param phrase WEP or WPA key + * @return 0 if connected, -1 otherwise + */ + int join (); + + /** Connect the wifi module to the adhock in the constructor. + * @param sec Security type (NONE, WEP_128 or WPA) + * @param ssid ssid of the network + * @param phrase WEP or WPA key + * @return 0 if connected, -1 otherwise + */ + int adhock (); + + /** Connect the wifi module to the limited AP in the constructor. + * @param sec Security type (NONE, WEP_128 or WPA) + * @param ssid ssid of the network + * @param phrase WEP or WPA key + * @return 0 if connected, -1 otherwise + */ + int limitedap (); + + /** Disconnect the wifi module from the access point + * @returns 0 if successful + */ + int dissociate (); + int disconnect () { + return dissociate(); + } + + /** Check if a Wi-Fi link is active + * @returns true if successful + */ + bool isAssociated(); + + /** polling if not use rtos + */ + void poll (); + + /** get Wi-Fi modue status + * @return Status + */ + Status getStatus (); + + /** set MAC address + */ + int setMacAddress (const char *mac); + /** get MAC address + */ + int getMacAddress (char *mac); + + /** use DHCP + */ + int setAddress (const char *name = NULL); + /** use static IP address + * @param ip my ip address (dhcp start address) + * @param netmask subnet mask + * @param gateway default gateway + * @param dns my host name (default NULL) + */ + int setAddress (const char *ip, const char *netmask, const char *gateway, const char *name = NULL); + /** get IP address + */ + int getAddress (char *ip, char *netmask, char *gateway); + + /** set Wi-Fi security parameter + * @param sec Security + * @param ssid SSID + * @param pass pass phrase + */ + int setSsid (Security sec, const char *ssid, const char *phrase); + + static GSwifi * getInstance() { + return _inst; + }; + + // ----- GSwifi_util.cpp ----- + int setRegion (int reg); + + /** get RSSI + * @return RSSI (dBm) + */ + int getRssi (); + + /** power save mode + * @param active rx radio 0:switched off, 1:always on + * @param save power save 0:disable, 1:enable + */ + int powerSave (int active, int save); + + /** RF power + * @param power 0(high)-7(low) + */ + int setRfPower (int power); + + /** set system time + * @param time date time (UTC) + */ + int setTime (time_t time); + + /** get system time + * @return date time (UTC) + */ + time_t getTime (); + + /** set NTP server + * @param host SNTP server + * @param sec time sync interval, 0:one time + */ + int ntpdate (char *host, int sec = 0); + + /** GPIO output + * @param port 10,11,30,31 + * @param out 0:set(high), 1:reset(low) + */ + int setGpio (int port, int out); + + /** Web server + */ + int provisioning (char *user, char *pass); + + /** standby mode + * @param msec wakeup after + * wakeup after msec or alarm1/2 + * core off, save to RTC ram + */ + int standby (int msec); + + /** deep sleep mode + */ + int deepSleep (); + + /** restore standby or deep sleep + */ + int wakeup (); + + // ----- GSwifi_sock.cpp ----- + /** Resolv hostname + * @param name hostname + * @param ip resolved ip address + */ + int getHostByName(const char * host, char * ip); + + /** TCP/UDP client + * @return CID, -1:failure + */ + int open (Protocol proto, const char *ip, int port, int src = 0, void(*func)(int) = NULL); + + /** TCP/UDP server + * @return CID, -1:failure + */ + int listen (Protocol proto, int port, void(*func)(int) = NULL); + + /** close client/server + */ + int close (int cid); + + /** send data tcp(s/c), udp(c) + */ + int send (int cid, const char *buf, int len); + + /** send data udp(s) + */ + int sendto (int cid, const char *buf, int len, const char *ip, int port); + + /** recv data tcp(s/c), udp(c) + * @return length + */ + int recv (int cid, char *buf, int len); + + /** recv data udp(s) + * @return length + */ + int recvfrom (int cid, char *buf, int len, char *ip, int *port); + + /** readable recv data + */ + int readable (int cid); + + /** tcp/udp connected + */ + bool isConnected (int cid); + + int accept (int cid); + int getRemote(int cid, char **ip, int *port); + + // ----- GSwifi_http.cpp ----- + /** http request (GET method) + */ + int httpGet (const char *host, int port, const char *uri, bool ssl = false, const char *user = NULL, const char *pwd = NULL, void(*func)(int) = NULL); + int httpGet (const char *host, int port, const char *uri, void(*func)(int) = NULL) { + return httpGet(host, port, uri, false, NULL, NULL, func); + } + /** http request (POST method) + */ + int httpPost (const char *host, int port, const char *uri, const char *body, bool ssl = false, const char *user = NULL, const char *pwd = NULL, void(*func)(int) = NULL); + int httpPost (const char *host, int port, const char *uri, const char *body, void(*func)(int) = NULL) { + return httpPost(host, port, uri, body, false, NULL, NULL, func); + } + + int base64encode (const char *input, int length, char *output, int len); + int urlencode (const char *str, char *buf, int len); + int urldecode (const char *str, char *buf, int len); + +#ifdef CFG_ENABLE_HTTPD + // ----- GSwifi_httpd.cpp ----- + /** start http server + * @param port + */ + int httpd (int port = 80); + + // ----- GSwifi_httpd_util.cpp ----- + /** attach uri to dirctory handler + */ + void httpdError (int cid, int err); + /** attach uri to dirctory handler + */ + int httpdAttach (const char *uri, const char *dir); + /** attach uri to cgi handler + */ + int httpdAttach (const char *uri, void (*funcCgi)(int)); +#endif + +#ifdef CFG_ENABLE_WEBSOCKET + // ----- GSwifi_httpd_ws.cpp ----- + /** websocket request (Upgrade method) + * @return CID, -1:failure + */ + int wsOpen (const char *host, int port, const char *uri, const char *user = NULL, const char *pwd = NULL); + /** send websocket data + */ + int wsSend (int cid, const char *buf, int len, const char *mask = NULL); +#endif + +#ifdef CFG_ENABLE_SMTP + // ----- GSwifi_smtp.cpp ----- + /** send mail (smtp) + * @param host SMTP server + * @param port SMTP port (25 or 587 or etc.) + * @param to To address + * @param from From address + * @param subject Subject + * @param mesg Message + * @param user username (SMTP Auth) + * @param pwd password (SMTP Auth) + * @retval 0 success + * @retval -1 failure + */ + int mail (const char *host, int port, const char *to, const char *from, const char *subject, const char *mesg, const char *user = NULL, const char *pwd = NULL); +#endif + + // ----- GSwifi_msg.cpp ----- + + // ----- GSwifi_at.cpp ----- + /** Send a command to the wifi module. Check if the module is in command mode. If not enter in command mode + * @param cmd string to be sent + * @param res need response + * @param timeout + * @returns 0 if successful + */ + int sendCommand(const char * cmd, Response res = RES_NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT); + + /** Send a command to the wifi module. Check if the module is in command mode. If not enter in command mode + * @param data string to be sent + * @param res need response + * @param timeout + * @param cmd + * @returns 0 if successful + */ + int sendData(const char * data, int len, int timeout = CFG_TIMEOUT, const char * cmd = NULL); + + +protected: + + static GSwifi * _inst; +#ifdef CFG_ENABLE_RTOS + Thread *_threadPoll; + Mutex _mutexUart; +#endif + +// Serial _gs; + RawSerial _gs; + int _baud; + DigitalIn *_cts; + DigitalOut *_rts; + int _flow; +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088) + LPC_UART1_TypeDef *_uart; +#elif defined(TARGET_LPC11U24) + LPC_USART_Type *_uart; +#elif defined(TARGET_LPC11XX) + LPC_UART_TypeDef *_uart; +#endif + DigitalInOut _reset; + DigitalInOut *_alarm; + + struct STATE { + WiFiMode wm; + Security sec; + char ssid[35]; + char pass[66]; + char ip[16]; + char netmask[16]; + char gateway[16]; + char nameserver[16]; + char mac[18]; + char resolv[16]; + char name[32]; + int rssi; + bool dhcp; + time_t time; + + bool initialized; + bool associated; + volatile Mode mode; + volatile Status status; + bool escape; + volatile bool ok, failure; + volatile Response res; + int cid; + int n; + CircBuffer<char> *buf; + } _state; + + struct CONNECTION { + Protocol protocol; + Type type; + bool connected; + char ip[16]; + int port; + CircBuffer<char> *buf; + volatile bool received; + volatile int parent; + volatile bool accept; + void(*func)(int); + } _con[16]; + +#ifdef CFG_ENABLE_HTTPD + enum HttpdMode { + HTTPDMODE_REQUEST, + HTTPDMODE_REQUEST_STR, + HTTPDMODE_HEADER, + HTTPDMODE_BODY, + HTTPDMODE_ENTER, + HTTPDMODE_ERROR, + HTTPDMODE_WEBSOCKET, + HTTPDMODE_WEBSOCKET_MASK, + HTTPDMODE_WEBSOCKET_BODY, + HTTPDMODE_WEBSOCKET_ENTER, + }; + + enum HttpdReq { + REQ_HTTPGET, + REQ_HTTPPOST, + }; + + struct HTTPD { + HttpdMode mode; + HttpdReq req; + CircBuffer <char>*buf; + char *uri; + char *filename; + char *querystring; + int enter; + int length; + int n; + int keepalive; +#ifdef CFG_ENABLE_WEBSOCKET + int websocket; + char *websocket_key; + int websocket_opcode; + int websocket_flg; + char websocket_mask[4]; + int websocket_payload; +#endif + } _httpd[16]; + + struct HTTPD_HANDLER { + char *uri; + char *dir; + void (*func)(int); + } _httpd_handler[CFG_HTTPD_HANDLER_NUM]; + + int _httpd_cid; + int _handler_count; +#endif // CFG_ENABLE_HTTPD + + + // ----- GSwifi.cpp ----- +#ifdef CFG_ENABLE_RTOS + static void threadPoll (void const *args); +#endif + + // ----- GSwifi_sock.cpp ----- + void initCon (int cid, bool connected); + + // ----- GSwifi_util.cpp ----- + int x2i (char c); + char i2x (int i); + int from_hex (int ch); + int to_hex (int code); + + // ----- GSwifi_http.cpp ----- + +#ifdef CFG_ENABLE_HTTPD + // ----- GSwifi_httpd.cpp ----- + void httpdRecvData (int cid, char c); + int httpdParseRequest (int cid); + void httpdPoll (); + int httpdParseHeader (int cid); + void reqContentLength (int cid, const char *buf); + void reqConnection (int cid, const char *buf); + void reqUpgrade (int cid, const char *buf); + void reqWebSocketVersion (int cid, const char *buf); + void reqWebSocketKey (int cid, const char *buf); + + // ----- GSwifi_httpd_util.cpp ----- + int httpdFile (int cid, char *dir); + int httpdGetHandler (const char *uri); + char *mimetype (char *file); + int strnicmp (const char *p1, const char *p2, int n); +#endif + +#ifdef CFG_ENABLE_WEBSOCKET + // ----- GSwifi_httpd_ws.cpp ----- + int wsWait (int cid, int code); +#ifdef CFG_ENABLE_HTTPD + void wsRecvData (int cid, char c); + int wsParseRequest (int cid); + int wsAccept (int cid); +#endif +#endif + +#ifdef CFG_ENABLE_SMTP + // ----- GSwifi_smtp.cpp ----- + int smtpWait (int cid, int code); +#endif + + // ----- GSwifi_msg.cpp ----- + void recvData (char c); + int parseMessage (); + void msgOk (const char*); + void msgError (const char*); + void msgConnect (const char*); + void msgDisconnect (const char*); + void msgDisassociated (const char*); + void msgReset (const char*); + void msgOutofStandby (const char*); + void msgOutofDeepsleep (const char*); + void resNormal (const char*); + void resConnect (const char*); + void resWpapsk (const char *buf); + void resWps (const char*); + void resMacAddress (const char*); + void resIp (const char*); + void resLookup (const char*); + void resRssi (const char*); + void resTime (const char*); + void resChannel (const char*); + void resStatus (const char*); + void resHttp (const char *buf); + + // ----- GSwifi_at.cpp ----- + void clearFlags (); + int cmdAT (); + int cmdE (bool n); + int cmdR (bool n); + int cmdNMAC (const char *s = NULL); + int cmdWREGDOMAIN (int n = CFG_WREGDOMAIN); + int cmdWS (); + int cmdWM (int n); + int cmdWA (const char *s); + int cmdWD (); + int cmdWWPS (bool n, const char *p = NULL); + int cmdNSTAT (); + int cmdWSTATUS (); + int cmdWRSSI (); + int cmdWAUTH (int n); + int cmdWWEP (int n, const char *s); + int cmdWPAPSK (const char *s, const char *p); + int cmdWRXACTIVE (bool n); + int cmdWRXPS (bool n); + int cmdWP (int n); + int cmdNDHCP (bool n, const char *s = NULL, int m = CFG_TIMEOUT); + int cmdDHCPSRVR (bool n); + int cmdNSET (const char *s, const char *t, const char *u); + int cmdDNS (bool n, const char *s); + int cmdDNSLOOKUP (const char *s); + int cmdDNSSET (const char *s); + int cmdSTORENWCONN (); + int cmdRESTORENWCONN (); + int cmdBDATA (bool n); + int cmdNCTCP (const char *s, int n); + int cmdNCUDP (const char *s, int n, int m = 0); + int cmdNSTCP (int n); + int cmdNSUDP (int n); + int cmdNCLOSE (int n); + int cmdNCLOSEALL (); + int cmdHTTPCONF (int n, const char *s); + int cmdHTTPCONFDEL (int n); + int cmdHTTPOPEN (const char *s, int n = 80, bool m = false); + int cmdHTTPSEND (int n, bool m, const char *s, int t = 0); + int cmdHTTPCLOSE (int n); + int cmdPSDPSLEEP (int n = 0); + int cmdPSSTBY (int n, int m = 0); + int cmdWEBPROV (const char *s, const char *p); + int cmdSETTIME (const char *s, const char *t); + int cmdGETTIME (); + int cmdNTIMESYNC (bool n, const char *s, int m = 0); + int cmdDGPIO (int n, int m); + + // ----- GSwifi_hal.cpp ----- + void setReset (bool flg); + void setAlarm (bool flg); + void isrUart (); + int getUart (); + void putUart (char c); + void setRts (bool flg); + int lockUart (int ms); + void unlockUart (); + void initUart (PinName cts, PinName rts, PinName alarm, int baud); + +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi_at.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,403 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "GSwifi.h" + +void GSwifi::clearFlags () { + _state.ok = false; + _state.failure = false; + _state.res = RES_NULL; + _state.n = 0; +} + +int GSwifi::sendCommand(const char * cmd, Response res, int timeout) { + int i; + Timer t; + + if (lockUart(timeout)) return -1; + + clearFlags(); + _state.res = res; + for (i = 0; i < strlen(cmd); i ++) { + putUart(cmd[i]); + } + putUart('\r'); + putUart('\n'); + unlockUart(); + INFO("command: '%s'\r\n", cmd); + + if (timeout) { + t.start(); + for (;;) { + if (_state.ok && _state.res == RES_NULL) break; + if (_state.failure || t.read_ms() > timeout) { + WARN("failure or timeout\r\n"); + _state.res = RES_NULL; + return -1; + } + } + t.stop(); + } + INFO("ok\r\n"); + _state.res = RES_NULL; + + return 0; +} + +int GSwifi::sendData(const char * data, int len, int timeout, const char * cmd) { + int i; + Timer t; + + if (lockUart(timeout)) return -1; + + clearFlags(); + for (i = 0; i < strlen(cmd); i ++) { + putUart(cmd[i]); + } + for (i = 0; i < len; i ++) { + putUart(data[i]); + } + unlockUart(); + INFO("data: '%s' %d\r\n", cmd, len); + + if (timeout) { + t.start(); + for (;;) { + if (_state.ok) break; + if (_state.failure || t.read_ms() > timeout) { + WARN("failure or timeout\r\n"); + return -1; + } + } + t.stop(); + } + + return i; +} + + +int GSwifi::cmdAT () { + return sendCommand("AT"); +} + +int GSwifi::cmdE (bool n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "ATE%d", n ? 1 : 0); + return sendCommand(cmd); +} + +int GSwifi::cmdR (bool n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT&R%d", n ? 1 : 0); + return sendCommand(cmd); +} + +int GSwifi::cmdNMAC (const char *s) { + int r; + char cmd[CFG_CMD_SIZE]; + const char xmac[] = "00:1D:C9:01:99:99"; + if (s) { + sprintf(cmd, "AT+NMAC2=%s", s); + r = sendCommand(cmd); + } else { + sprintf(cmd, "AT+NMAC=?"); + r = sendCommand(cmd, RES_MACADDRESS); + if (!r && strncmp(_state.mac, xmac, 17) == 0) { + r = -1; + } + } + return r; +} + +int GSwifi::cmdWREGDOMAIN (int n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+WREGDOMAIN=%d", n); + return sendCommand(cmd); +} + +int GSwifi::cmdWS () { + return sendCommand("AT+WS"); +} + +int GSwifi::cmdWM (int n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+WM=%d", n); + return sendCommand(cmd); +} + +int GSwifi::cmdWA (const char *s) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+WA=%s", s); + return sendCommand(cmd, RES_DHCP, CFG_TIMEOUT); +} + +int GSwifi::cmdWD () { + return sendCommand("AT+WD"); +} + +int GSwifi::cmdWWPS (bool n, const char *p) { + char cmd[CFG_CMD_SIZE]; + if (p) { + sprintf(cmd, "AT+WWPS=2,%s", p); + } else { + sprintf(cmd, "AT+WWPS=%d", n ? 1 : 0); + } + return sendCommand(cmd, RES_WPS, CFG_TIMEOUT); +} + +int GSwifi::cmdNSTAT () { + return sendCommand("AT+NSTAT=?"); +} + +int GSwifi::cmdWSTATUS () { + return sendCommand("AT+WSTATUS", RES_STATUS); +} + +int GSwifi::cmdWRSSI () { + return sendCommand("AT+WRSSI=?", RES_RSSI); +} + +int GSwifi::cmdWAUTH (int n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+WAUTH=%d", n); + return sendCommand(cmd); +} + +int GSwifi::cmdWWEP (int n, const char *s) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+WWEP%d=%s", n, s); + return sendCommand(cmd); +} + +int GSwifi::cmdWPAPSK (const char *s, const char *p) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+WPAPSK=%s,%s", s, p); + return sendCommand(cmd, RES_WPAPSK, CFG_TIMEOUT); +} + +int GSwifi::cmdWRXACTIVE (bool n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+WRXACTIVE=%d", n ? 1 : 0); + return sendCommand(cmd); +} + +int GSwifi::cmdWRXPS (bool n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+WRXPS=%d", n ? 1 : 0); + return sendCommand(cmd); +} + +int GSwifi::cmdWP (int n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+WP=%d", n); + return sendCommand(cmd); +} + +int GSwifi::cmdNDHCP (bool n, const char *s, int m) { + char cmd[CFG_CMD_SIZE]; + if (n) { + if (s) { + sprintf(cmd, "AT+NDHCP=1,%s", s); + } else { + sprintf(cmd, "AT+NDHCP=1"); + } + return sendCommand(cmd, RES_DHCP, m); + } else { + return sendCommand("AT+NDHCP=0"); + } +} + +int GSwifi::cmdDHCPSRVR (bool n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+DHCPSRVR=%d", n ? 1 : 0); + return sendCommand(cmd); +} + +int GSwifi::cmdNSET (const char *s, const char *t, const char *u) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+NSET=%s,%s,%s", s, t, u); + return sendCommand(cmd); +} + +int GSwifi::cmdDNS (bool n, const char *s) { + char cmd[CFG_CMD_SIZE]; + if (n) { + if (s) { + sprintf(cmd, "AT+DNS=1,%s", s); + } else { + sprintf(cmd, "AT+DNS=1," CFG_DNSNAME); + } + } else { + sprintf(cmd, "AT+DNS=0"); + } + return sendCommand(cmd); +} + +int GSwifi::cmdDNSLOOKUP (const char *s) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+DNSLOOKUP=%s", s); + return sendCommand(cmd, RES_DNSLOOKUP, CFG_TIMEOUT); +} + +int GSwifi::cmdDNSSET (const char *s) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+DNSSET=%s", s); + return sendCommand(cmd); +} + +int GSwifi::cmdSTORENWCONN () { + return sendCommand("AT+STORENWCONN"); +} + +int GSwifi::cmdRESTORENWCONN () { + return sendCommand("AT+RESTORENWCONN"); +} + +int GSwifi::cmdBDATA (bool n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+BDATA=%d", n ? 1 : 0); + return sendCommand(cmd); +} + +int GSwifi::cmdNCTCP (const char *s, int n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+NCTCP=%s,%d", s, n); + return sendCommand(cmd, RES_CONNECT, CFG_TIMEOUT); +} + +int GSwifi::cmdNCUDP (const char *s, int n, int m) { + char cmd[CFG_CMD_SIZE]; + if (m) { + sprintf(cmd, "AT+NCUDP=%s,%d,%d", s, n, m); + } else { + sprintf(cmd, "AT+NCUDP=%s,%d", s, n); + } + return sendCommand(cmd, RES_CONNECT, CFG_TIMEOUT); +} + +int GSwifi::cmdNSTCP (int n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+NSTCP=%d", n); + return sendCommand(cmd, RES_CONNECT); +} + +int GSwifi::cmdNSUDP (int n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+NSUDP=%d", n); + return sendCommand(cmd, RES_CONNECT); +} + +int GSwifi::cmdNCLOSE (int n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+NCLOSE=%d", n); + return sendCommand(cmd, RES_NULL, CFG_TIMEOUT); +} + +int GSwifi::cmdNCLOSEALL () { + return sendCommand("AT+NCLOSEALL", RES_NULL, CFG_TIMEOUT); +} + +int GSwifi::cmdHTTPCONF (int n, const char *s) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+HTTPCONF=%d,%s", n, s); + return sendCommand(cmd); +} + +int GSwifi::cmdHTTPCONFDEL (int n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+HTTPCONFDEL=%d", n); + return sendCommand(cmd); +} + +int GSwifi::cmdHTTPOPEN (const char *s, int n, bool m) { + char cmd[CFG_CMD_SIZE]; + if (m) { + sprintf(cmd, "AT+HTTPOPEN=%s,%d,1", s, n); + } else { + sprintf(cmd, "AT+HTTPOPEN=%s,%d", s, n); + } + return sendCommand(cmd, RES_HTTP, CFG_TIMEOUT); +} + +int GSwifi::cmdHTTPSEND (int n, bool m, const char *s, int t) { + char cmd[CFG_CMD_SIZE]; + if (m) { + sprintf(cmd, "AT+HTTPSEND=%d,3,%d,%s,%d", n, CFG_TIMEOUT / 1000, s, t); + } else { + sprintf(cmd, "AT+HTTPSEND=%d,1,%d,%s", n, CFG_TIMEOUT / 1000, s); + } + return sendCommand(cmd); +} + +int GSwifi::cmdHTTPCLOSE (int n) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+HTTPCLOSE=%d", n); + return sendCommand(cmd, RES_NULL, CFG_TIMEOUT); +} + +int GSwifi::cmdPSDPSLEEP (int n) { + char cmd[CFG_CMD_SIZE]; + if (n) { + sprintf(cmd, "AT+PSDPSLEEP=%d", n); + } else { + sprintf(cmd, "AT+PSDPSLEEP"); + } + return sendCommand(cmd, RES_NULL, 0); +} + +int GSwifi::cmdPSSTBY (int n, int m) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+PSSTBY=%d,0,%d,%d", n, m, m); + return sendCommand(cmd, RES_NULL, 0); +} + +int GSwifi::cmdWEBPROV (const char *s, const char *p) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+WEBPROV=%s,%s", s, p); + return sendCommand(cmd); +} + +int GSwifi::cmdSETTIME (const char *s, const char *t) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+SETTIME=%s,%s", s, t); + return sendCommand(cmd); +} + +int GSwifi::cmdGETTIME () { + return sendCommand("AT+GETTIME=?", RES_TIME); +} + +int GSwifi::cmdNTIMESYNC (bool n, const char *s, int m) { + char cmd[CFG_CMD_SIZE]; + if (n) { + if (m) { + sprintf(cmd, "AT+NTIMESYNC=1,%s,%d,1,%d", s, CFG_TIMEOUT / 1000, m); + } else { + sprintf(cmd, "AT+NTIMESYNC=1,%s,%d,0", s, CFG_TIMEOUT / 1000); + } + } else { + sprintf(cmd, "AT+NTIMESYNC=0"); + } + return sendCommand(cmd, RES_NULL, CFG_TIMEOUT); +} + +int GSwifi::cmdDGPIO (int n, int m) { + char cmd[CFG_CMD_SIZE]; + sprintf(cmd, "AT+DGPIO=%d,%d", n, m); + return sendCommand(cmd); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi_conf.h Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,34 @@ + +//#define DEBUG +//#define DEBUG_DUMP + +//#define CFG_ENABLE_RTOS +//#define CFG_ENABLE_HTTPD +//#define CFG_ENABLE_WEBSOCKET +//#define CFG_ENABLE_SMTP +//#define CFG_UART_DIRECT + +#define CFG_UART_BAUD 9600 +#define CFG_WREGDOMAIN 2 // 0:FCC, 1:ETSI, 2:TELEC +#define CFG_DHCPNAME "mbed-gswifi" +#define CFG_DNSNAME "setup.local" +#define CFG_TRYJOIN 3 +#define CFG_RECONNECT 30 // sec + +#define DEFAULT_WAIT_RESP_TIMEOUT 500 +#define CFG_TIMEOUT 30000 // ms + +#define CFG_CMD_SIZE 128 + +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC176X) +#define CFG_DATA_SIZE 1024 +#elif defined(TARGET_LPC11U24) || defined(TARGET_LPC1114) || defined(TARGET_LPC11XX) +#define CFG_DATA_SIZE 256 +#elif defined(TARGET_LPC4088) || defined(TARGET_LPC408X) +#define CFG_DATA_SIZE 4096 +#elif defined(TARGET_KL25Z) +#define CFG_DATA_SIZE 512 +#endif + +#define CFG_HTTPD_HANDLER_NUM 10 +#define CFG_HTTPD_KEEPALIVE 10
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi_hal.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,221 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "GSwifi.h" + +void GSwifi::setReset (bool flg) { + if (flg) { + // low + _reset.output(); + _reset = 0; + } else { + // high z + _reset.input(); + _reset.mode(PullNone); + } +} + +void GSwifi::setAlarm (bool flg) { + if (_alarm == NULL) return; + + if (flg) { + // low + _alarm->output(); // low + _alarm->write(0); + } else { + // high + _alarm->input(); // high + _alarm->mode(PullUp); + } +} + +void GSwifi::isrUart () { + recvData(getUart()); +} + +int GSwifi::getUart () { +#ifdef CFG_UART_DIRECT + return _uart->RBR; +#else + return _gs.getc(); +#endif +} + +void GSwifi::putUart (char c) { +#ifdef CFG_UART_DIRECT + while(!(_uart->LSR & (1<<5))); + _uart->THR = c; +#else + _gs.putc(c); +#endif +} + +void GSwifi::setRts (bool flg) { + if (flg) { + // low + if (_flow == 1) { +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088) + _uart->MCR |= (1<<6); // RTSEN +#endif + } else + if (_flow == 2) { + if (_rts) { + _rts->write(0); // low + } + } + } else { + // high + if (_flow == 1) { +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088) + _uart->MCR &= ~(1<<6); // RTS off + _uart->MCR &= ~(1<<1); +#endif + } else + if (_flow == 2) { + if (_rts) { + _rts->write(1); // high + } + } + } +} + +int GSwifi::lockUart (int ms) { + Timer t; + + if (_state.mode != MODE_COMMAND) { + t.start(); + while (_state.mode != MODE_COMMAND) { + if (t.read_ms() >= ms) { + WARN("lock timeout (%d)\r\n", _state.mode); + return -1; + } + } + } + +#ifdef CFG_ENABLE_RTOS + if (_mutexUart.lock(ms) != osOK) return -1; +#endif + + if (_flow == 1) { +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088) + if (!(_uart->MSR & (1<<4))) { + // CTS check + t.start(); + while (!(_uart->MSR & (1<<4))) { + if (t.read_ms() >= ms) { + DBG("cts timeout\r\n"); + return -1; + } + } + } +#endif + } else + if (_flow == 2) { + if (_cts && _cts->read()) { + // CTS check + t.start(); + while (_cts->read()) { + if (t.read_ms() >= ms) { + DBG("cts timeout\r\n"); + return -1; + } + } + } + } + + setRts(false); + return 0; +} + +void GSwifi::unlockUart () { + setRts(true); +#ifdef CFG_ENABLE_RTOS + _mutexUart.unlock(); +#endif +} + +void GSwifi::initUart (PinName cts, PinName rts, PinName alarm, int baud) { + + _baud = baud; + if (_baud) _gs.baud(_baud); + _gs.attach(this, &GSwifi::isrUart, Serial::RxIrq); + + _cts = NULL; + _rts = NULL; + _flow = 0; +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) + _uart = LPC_UART1; + if (cts == p12) { // CTS input (P0_17) + _uart->MCR |= (1<<7); // CTSEN + LPC_PINCON->PINSEL1 &= ~(3 << 2); + LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS + } else + if (cts != NC) { + _cts = new DigitalIn(cts); + } + if (rts == P0_22) { // RTS output (P0_22) + _uart->MCR |= (1<<6); // RTSEN + LPC_PINCON->PINSEL1 &= ~(3 << 12); + LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS + _flow = 1; + } else + if (rts != NC) { + _rts = new DigitalOut(rts); + _flow = 2; + } +#elif defined(TARGET_LPC11U24) + _uart = LPC_USART; + if (cts == p21) { // CTS input (P0_7) + _uart->MCR |= (1<<7); // CTSEN + LPC_IOCON->PIO0_7 &= ~0x07; + LPC_IOCON->PIO0_7 |= 0x01; // UART CTS + } else + if (cts != NC) { + _cts = new DigitalIn(cts); + } + if (rts == p22) { // RTS output (P0_17) + _uart->MCR |= (1<<6); // RTSEN + LPC_IOCON->PIO0_17 &= ~0x07; + LPC_IOCON->PIO0_17 |= 0x01; // UART RTS + _flow = 1; + } else + if (rts != NC) { + _rts = new DigitalOut(rts); + _flow = 2; + } +#elif defined(TARGET_LPC4088) + _uart = (LPC_UART_TypeDef*)LPC_UART2; + if (cts != NC && rts != NC) { + _cts = new DigitalIn(cts); + _rts = new DigitalOut(rts); + _flow = 2; + } +#else + if (cts != NC && rts != NC) { + _cts = new DigitalIn(cts); + _rts = new DigitalOut(rts); + _flow = 2; + } +#endif + + if (alarm != NC) { + _alarm = new DigitalInOut(alarm); + } else { + _alarm = NULL; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi_http.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,182 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "GSwifi.h" + +int GSwifi::httpGet (const char *host, int port, const char *uri, bool ssl, const char *user, const char *pwd, void(*func)(int)) { + char ip[17]; + int cid; + + if (!isAssociated() || _state.status != STAT_READY) return -1; + + if (getHostByName(host, ip)) return -1; + if (! port) { + if (ssl) { + port = 443; + } else { + port = 80; + } + } + + if (cmdHTTPCONF(3, "close")) return -1; // Connection + cmdHTTPCONFDEL(5); + cmdHTTPCONFDEL(7); + cmdHTTPCONF(11, host); // Host + if (user && pwd) { + char tmp[CFG_CMD_SIZE], tmp2[CFG_CMD_SIZE]; + snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd); + base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2)); + sprintf(tmp, "Basic %s", tmp2); + cmdHTTPCONF(2, tmp); // Authorization + } else { + cmdHTTPCONFDEL(2); + } + + _state.cid = -1; + if (cmdHTTPOPEN(ip, port, ssl)) return -1; + if (_state.cid < 0) return -1; + cid = _state.cid; + _con[cid].protocol = PROTO_HTTPGET; + _con[cid].type = TYPE_CLIENT; + _con[cid].func = func; + + cmdHTTPSEND(cid, false, uri); // GET + return cid; +} + +int GSwifi::httpPost (const char *host, int port, const char *uri, const char *body, bool ssl, const char *user, const char *pwd, void(*func)(int)) { + char cmd[CFG_CMD_SIZE]; + char ip[17]; + int cid, len; + + if (!isAssociated() || _state.status != STAT_READY) return -1; + + if (getHostByName(host, ip)) return -1; + if (! port) { + if (ssl) { + port = 443; + } else { + port = 80; + } + } + len = strlen(body); + + if (cmdHTTPCONF(3, "close")) return -1; // Connection + sprintf(cmd, "%d", len); + cmdHTTPCONF(5, cmd); // Content-Length + cmdHTTPCONF(7, "application/x-www-form-urlencoded"); // Content-type + cmdHTTPCONF(11, host); // Host + if (user && pwd) { + char tmp[CFG_CMD_SIZE], tmp2[CFG_CMD_SIZE]; + snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd); + base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2)); + sprintf(tmp, "Basic %s", tmp2); + cmdHTTPCONF(2, tmp); // Authorization + } else { + cmdHTTPCONFDEL(2); + } + + _state.cid = -1; + if (cmdHTTPOPEN(ip, port, ssl)) return -1; + if (_state.cid < 0) return -1; + cid = _state.cid; + _con[cid].protocol = PROTO_HTTPPOST; + _con[cid].type = TYPE_CLIENT; + _con[cid].func = func; + + cmdHTTPSEND(cid, true, uri, len); // POST + sprintf(cmd, "\x1bH%X", cid); + sendData(body, len, DEFAULT_WAIT_RESP_TIMEOUT, cmd); + return cid; +} + + +/* base64encode code from + * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + */ +int GSwifi::base64encode (const char *input, int length, char *output, int len) { + static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + unsigned int c, c1, c2, c3; + + if (len < ((((length-1)/3)+1)<<2)) return -1; + for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) { + c1 = ((((unsigned char)*((unsigned char *)&input[i])))); + c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0; + c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0; + + c = ((c1 & 0xFC) >> 2); + output[j+0] = base64[c]; + c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4); + output[j+1] = base64[c]; + c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6); + output[j+2] = (length>i+1)?base64[c]:'='; + c = (c3 & 0x3F); + output[j+3] = (length>i+2)?base64[c]:'='; + } + output[(((length-1)/3)+1)<<2] = '\0'; + return 0; +} + + +/* urlencode code from + * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + */ +int GSwifi::urlencode (const char *str, char *buf, int len) { +// char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf; + const char *pstr = str; + char *pbuf = buf; + + if (len < (strlen(str) * 3 + 1)) return -1; + while (*pstr) { + if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') + *pbuf++ = *pstr; + else if (*pstr == ' ') + *pbuf++ = '+'; + else + *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15); + pstr++; + } + *pbuf = '\0'; + return 0; +} + +/* urldecode code from + * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + */ +int GSwifi::urldecode (const char *str, char *buf, int len) { +// char *pstr = str, *buf = (char*)malloc(strlen(str) + 1), *pbuf = buf; + const char *pstr = str; + char *pbuf = buf; + + if (len < (strlen(str) / 3 - 1)) return -1; + while (*pstr) { + if (*pstr == '%') { + if (pstr[1] && pstr[2]) { + *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]); + pstr += 2; + } + } else if (*pstr == '+') { + *pbuf++ = ' '; + } else { + *pbuf++ = *pstr; + } + pstr++; + } + *pbuf = '\0'; + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi_httpd.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,294 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "GSwifi.h" + +#ifdef CFG_ENABLE_HTTPD + +int GSwifi::httpd (int port) { + int i; + + if (!isAssociated() || _state.status != STAT_READY) return -1; + + memset(&_httpd, 0, sizeof(_httpd)); + for (i = 0; i < 16; i ++) { + _httpd[i].mode = HTTPDMODE_REQUEST; + } + _handler_count = 0; + + _httpd_cid = listen(PROTO_TCP, port); + if (_httpd_cid < 0) return -1; + + _con[_httpd_cid].protocol = PROTO_HTTPD; + return _httpd_cid; +} + +void GSwifi::httpdRecvData (int cid, char c) { + + switch (_httpd[cid].mode) { + case HTTPDMODE_REQUEST: + if (_con[cid].buf == NULL) + _con[cid].buf = new CircBuffer<char>(CFG_DATA_SIZE); + _httpd[cid].buf = _con[cid].buf; + _httpd[cid].buf->flush(); + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { + _httpd[cid].buf->queue(c); + _httpd[cid].mode = HTTPDMODE_REQUEST_STR; + } + break; + case HTTPDMODE_REQUEST_STR: + switch (c) { + case 0: + case 0x0d: // CR + break; + case 0x0a: // LF + if (httpdParseRequest(cid)) { + _httpd[cid].mode = HTTPDMODE_REQUEST_STR; + } else { + _httpd[cid].mode = HTTPDMODE_HEADER; + } + _httpd[cid].enter = 0; + break; + default: + _httpd[cid].buf->queue(c); + break; + } + break; + case HTTPDMODE_HEADER: + switch (c) { + case 0: + case 0x0d: // CR + break; + case 0x0a: // LF + if (_httpd[cid].buf->available() == 0) { +// if ((_httpd[cid].enter == 0x0d && c == 0x0a) || (_httpd[cid].enter == 0x0a && c == 0x0a)) { + if (_httpd[cid].enter == 0x0a && c == 0x0a) { + _httpd[cid].buf->flush(); +#ifdef CFG_ENABLE_WEBSOCKET + if (_httpd[cid].websocket) { + INFO("MODE_WEBSOCKET"); + wsAccept(cid); + _httpd[cid].mode = HTTPDMODE_WEBSOCKET; + } else +#endif + if (_httpd[cid].length) { + INFO("MODE_BODY"); + _httpd[cid].mode = HTTPDMODE_BODY; + } else { + INFO("MODE_ENTER"); + _httpd[cid].mode = HTTPDMODE_ENTER; + _con[cid].received = true; + } + } + _httpd[cid].buf->flush(); + _httpd[cid].enter = c; + break; + } + + httpdParseHeader(cid); + _httpd[cid].enter = c; + break; + default: + _httpd[cid].buf->queue(c); + _httpd[cid].enter = 0; + break; + } + break; + case HTTPDMODE_BODY: + _httpd[cid].buf->queue(c); + if (_httpd[cid].buf->available() >= _httpd[cid].length) { + _httpd[cid].mode = HTTPDMODE_ENTER; + _con[cid].received = true; + } + break; +#ifdef CFG_ENABLE_WEBSOCKET + case HTTPDMODE_WEBSOCKET: + case HTTPDMODE_WEBSOCKET_MASK: + case HTTPDMODE_WEBSOCKET_BODY: + wsRecvData(cid, c); + break; +#endif + } +} + +void GSwifi::httpdPoll () { + for (int cid = 0; cid < 16; cid ++) { + if (isConnected(cid) && _con[cid].protocol == PROTO_HTTPD) { + + if (_httpd[cid].mode == HTTPDMODE_ENTER) { + int i = httpdGetHandler(_httpd[cid].uri); + if (i >= 0) { + if (_httpd_handler[i].dir) { + // file + httpdFile(cid, _httpd_handler[i].dir); + } else + if (_httpd_handler[i].func) { + // cgi + _httpd_handler[i].func(cid); +// _httpd[cid].keepalive = 0; + } else { + httpdError(cid, 403); + } + } else { + httpdError(cid, 404); + } + + if (_httpd[cid].keepalive) { + DBG("keepalive %d", _httpd[cid].keepalive); + _httpd[cid].keepalive --; + } else { + close(cid); + } + _httpd[cid].mode = HTTPDMODE_REQUEST; +#ifdef CFG_ENABLE_WEBSOCKET + } else + if (_httpd[cid].mode == HTTPDMODE_WEBSOCKET_ENTER) { + wsParseRequest(cid); + _httpd[cid].mode = HTTPDMODE_WEBSOCKET; +#endif + } + + } + } +} + +int GSwifi::httpdParseRequest (int cid) { + int i, j, len; + char buf[CFG_CMD_SIZE]; + + for (len = 0; len < sizeof(buf); len++) { + if (_httpd[cid].buf->dequeue(&buf[len]) == false) break; + } + buf[len] = 0; + + if (strnicmp(buf, "GET ", 4) == 0) { + _httpd[cid].req = REQ_HTTPGET; + j = 4; + } else + if (strnicmp(buf, "POST ", 5) == 0) { + _httpd[cid].req = REQ_HTTPPOST; + j = 5; + } else { + return -1; + } + + if (_httpd[cid].uri == NULL) + _httpd[cid].uri = (char*)malloc(CFG_CMD_SIZE); + + for (i = 0; i < len - j; i ++) { + _httpd[cid].uri[i] = buf[i + j]; + if (buf[i + j] == ' ' || i >= CFG_CMD_SIZE - 1) { + _httpd[cid].uri[i] = 0; + INFO("URI %d '%s'", _httpd[cid].req, _httpd[cid].uri); + _httpd[cid].mode = HTTPDMODE_HEADER; + _httpd[cid].buf->flush(); + _httpd[cid].length = 0; + _httpd[cid].n = 0; + _httpd[cid].filename = NULL; + _httpd[cid].querystring = NULL; +#ifdef CFG_ENABLE_WEBSOCKET + _httpd[cid].websocket = 0; +#endif + break; + } + } + + i = httpdGetHandler(_httpd[cid].uri); + if (i >= 0) { + _httpd[cid].filename = &_httpd[cid].uri[strlen(_httpd_handler[i].uri)]; + for (i = 0; i < strlen(_httpd[cid].filename); i ++) { + if (_httpd[cid].filename[i] == '?') { + _httpd[cid].filename[i] = 0; + _httpd[cid].querystring = _httpd[cid].filename + i + 1; + break; + } + } + INFO("FILE '%s' QUERY '%s'", _httpd[cid].filename, _httpd[cid].querystring); + } + return 0; +} + +#define HEADER_TABLE_NUM 5 +int GSwifi::httpdParseHeader (int cid) { + int i; + char buf[CFG_CMD_SIZE]; + static const struct HEADER_TABLE { + const char header[24]; + void (GSwifi::*func)(int id, const char*); + } header_table[HEADER_TABLE_NUM] = { + {"Content-Length:", &GSwifi::reqContentLength}, + {"Connection:", &GSwifi::reqConnection}, + {"Upgrade: websocket", &GSwifi::reqUpgrade}, + {"Sec-WebSocket-Version:", &GSwifi::reqWebSocketVersion}, + {"Sec-WebSocket-Key:", &GSwifi::reqWebSocketKey}, + }; + for (i = 0; i < sizeof(buf); i++) { + if (_httpd[cid].buf->dequeue(&buf[i]) == false) break; + } + buf[i] = 0; + + for (i = 0; i < HEADER_TABLE_NUM; i ++) { + if (strnicmp(buf, header_table[i].header, strlen(header_table[i].header)) == 0) { + DBG("parse header %d '%s'\r\n", i, buf); + if (header_table[i].func != NULL) { + (this->*(header_table[i].func))(cid, buf); + } + return 0; + } + } + + return -1; +} + +void GSwifi::reqContentLength (int cid, const char *buf) { + _httpd[cid].length = atoi(&buf[16]); +} + +void GSwifi::reqConnection (int cid, const char *buf) { + if (strnicmp(&buf[12], "Keep-Alive", 10) == 0 && _httpd[cid].keepalive == 0) { + _httpd[cid].keepalive = CFG_HTTPD_KEEPALIVE; + } else { + _httpd[cid].keepalive = 0; + } +} + +#ifdef CFG_ENABLE_WEBSOCKET +void GSwifi::reqUpgrade (int cid, const char *buf) { + if (! _httpd[cid].websocket) _httpd[cid].websocket = 1; +} + +void GSwifi::reqWebSocketVersion (int cid, const char *buf) { + _httpd[cid].websocket = atoi(&buf[23]); +} + +void GSwifi::reqWebSocketKey (int cid, const char *buf) { + if (_httpd[cid].websocket_key == NULL) { + _httpd[cid].websocket_key = (char*)malloc(30); + } + strncpy(_httpd[cid].websocket_key, &buf[19], 30); +} +#else +void GSwifi::reqUpgrade (int cid, const char *buf) { +} +void GSwifi::reqWebSocketVersion (int cid, const char *buf) { +} +void GSwifi::reqWebSocketKey (int cid, const char *buf) { +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi_httpd_util.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,196 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "GSwifi.h" + +#ifdef CFG_ENABLE_HTTPD + +int GSwifi::httpdFile (int cid, char *dir) { + FILE *fp; + int i, len; + char buf[CFG_DATA_SIZE]; + char file[CFG_CMD_SIZE]; + + INFO("httpdFile %d %s", cid, dir); + + strcpy(file, dir); + strcat(file, _httpd[cid].filename); + if (file[strlen(file) - 1] == '/') { + strcat(file, "index.html"); + } + DBG("file: %s\r\n", file); + + fp = fopen(file, "r"); + if (fp) { + strcpy(buf, "HTTP/1.1 200 OK\r\n"); + send(cid, buf, strlen(buf)); + { + // file size + i = ftell(fp); + fseek(fp, 0, SEEK_END); + len = ftell(fp); + fseek(fp, i, SEEK_SET); + } + + strcpy(buf, "Server: GSwifi httpd\r\n"); + send(cid, buf, strlen(buf)); + if (_httpd[cid].keepalive) { + strcpy(buf, "Connection: Keep-Alive\r\n"); + } else { + strcpy(buf, "Connection: close\r\n"); + } + send(cid, buf, strlen(buf)); + sprintf(buf, "Content-Type: %s\r\n", mimetype(file)); + send(cid, buf, strlen(buf)); + sprintf(buf, "Content-Length: %d\r\n\r\n", len); + send(cid, buf, strlen(buf)); + + for (;;) { + i = fread(buf, sizeof(char), sizeof(buf), fp); + if (i <= 0) break; + send(cid, buf, i); +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) + if (feof(fp)) break; +#endif + } + fclose(fp); + return 0; + } + + httpdError(cid, 404); + return -1; +} + +void GSwifi::httpdError (int cid, int err) { + char buf[CFG_CMD_SIZE], msg[30]; + + switch (err) { + case 400: + strcpy(msg, "Bad Request"); + break; + case 403: + strcpy(msg, "Forbidden"); + break; + case 404: + strcpy(msg, "Not Found"); + break; + case 500: + default: + strcpy(msg, "Internal Server Error"); + break; + } + DBG("httpd error: %d %d %s\r\n", cid, err, msg); + + sprintf(buf, "HTTP/1.1 %d %s\r\n", err, msg); + send(cid, buf, strlen(buf)); + strcpy(buf, "Content-Type: text/html\r\n\r\n"); + send(cid, buf, strlen(buf)); + + sprintf(buf, "<html><head><title>%d %s</title></head>\r\n", err, msg); + send(cid, buf, strlen(buf)); + sprintf(buf, "<body><h1>%s</h1></body></html>\r\n", msg); + send(cid, buf, strlen(buf)); + wait_ms(100); + close(cid); +// WARN("%d.%d.%d.%d ", _httpd[cid].host.getIp()[0], _httpd[cid].host.getIp()[1], _httpd[cid].host.getIp()[2], _httpd[cid].host.getIp()[3]); +// WARN("%s %s %d %d -\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length, err); +} + +int GSwifi::httpdGetHandler (const char *uri) { + int i; + + for (i = 0; i < _handler_count; i ++) { + if (strncmp(uri, _httpd_handler[i].uri, strlen(_httpd_handler[i].uri)) == NULL) { + // found + return i; + } + } + return -1; +} + +int GSwifi::httpdAttach (const char *uri, const char *dir) { + if (_handler_count < CFG_HTTPD_HANDLER_NUM) { + _httpd_handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1); + strcpy(_httpd_handler[_handler_count].uri, uri); + _httpd_handler[_handler_count].dir = (char*)malloc(strlen(dir) + 1); + strcpy(_httpd_handler[_handler_count].dir, dir); + _httpd_handler[_handler_count].func = NULL; + DBG("httpdAttach %s %s\r\n", _httpd_handler[_handler_count].uri, _httpd_handler[_handler_count].dir); + _handler_count ++; + return 0; + } else { + return -1; + } +} + +int GSwifi::httpdAttach (const char *uri, void (*funcCgi)(int)) { + if (_handler_count < CFG_HTTPD_HANDLER_NUM) { + _httpd_handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1); + strcpy(_httpd_handler[_handler_count].uri, uri); + _httpd_handler[_handler_count].dir = NULL; + _httpd_handler[_handler_count].func = funcCgi; + DBG("httpdAttach %s %08x\r\n", _httpd_handler[_handler_count].uri, _httpd_handler[_handler_count].func); + _handler_count ++; + return 0; + } else { + return -1; + } +} + + +#define MIMETABLE_NUM 9 +char *GSwifi::mimetype (char *file) { + static const struct MIMETABLE { + const char ext[5]; + const char type[24]; + } mimetable[MIMETABLE_NUM] = { + {"txt", "text/plain"}, // default + {"html", "text/html"}, + {"htm", "text/html"}, + {"css", "text/css"}, + {"js", "application/javascript"}, + {"jpg", "image/jpeg"}, + {"png", "image/png"}, + {"gif", "image/gif"}, + {"ico", "image/x-icon"}, + }; + int i, j; + + for (i = 0; i < MIMETABLE_NUM; i ++) { + j = strlen(mimetable[i].ext); + if (file[strlen(file) - j - 1] == '.' && + strnicmp(&file[strlen(file) - j], mimetable[i].ext, j) == NULL) { + return (char*)mimetable[i].type; + } + } + return (char*)mimetable[0].type; +} + +int GSwifi::strnicmp (const char *p1, const char *p2, int n) { + int i, r = -1; + char c1, c2; + + for (i = 0; i < n; i ++) { + c1 = (p1[i] >= 'a' && p1[i] <= 'z') ? p1[i] - ('a' - 'A'): p1[i]; + c2 = (p2[i] >= 'a' && p2[i] <= 'z') ? p2[i] - ('a' - 'A'): p2[i]; + r = c1 - c2; + if (r) break; + } + return r; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi_httpd_ws.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,300 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "GSwifi.h" + +#ifdef CFG_ENABLE_WEBSOCKET + +#include "sha1.h" + +int GSwifi::wsOpen (const char *host, int port, const char *uri, const char *user, const char *pwd) { + int cid; + char cmd[CFG_CMD_SIZE], tmp[CFG_CMD_SIZE]; + char ip[17]; + + if (!isAssociated() || _state.status != STAT_READY) return -1; + + if (getHostByName(host, ip)) return -1; + if (! port) { + port = 80; + } + + cid = open(PROTO_TCP, ip, port); + if (cid < 0) return -1; + DBG("ws cid %d\r\n", cid); + + // request + snprintf(cmd, sizeof(cmd), "GET %d HTTP/1.1\r\n", uri); + send(cid, cmd, strlen(cmd)); + if (host) { + snprintf(cmd, sizeof(cmd), "Host: %s\r\n", host); + send(cid, cmd, strlen(cmd)); + } + if (user && pwd) { + snprintf(cmd, sizeof(cmd), "%s:%s", user, pwd); + base64encode(cmd, strlen(cmd), tmp, sizeof(tmp)); + snprintf(cmd, sizeof(cmd), "Authorization: Basic %s\r\n", tmp); + send(cid, cmd, strlen(cmd)); + } + strcpy(cmd, "Upgrade: websocket\r\n"); + send(cid, cmd, strlen(cmd)); + strcpy(cmd, "Connection: Upgrade\r\n"); + send(cid, cmd, strlen(cmd)); + getMacAddress(tmp); + memcpy(&tmp[6], host, 10); + base64encode(tmp, 16, cmd, sizeof(cmd)); + snprintf(cmd, sizeof(cmd), "Sec-WebSocket-Key: %s\r\n", tmp); + send(cid, cmd, strlen(cmd)); + strcpy(cmd, "Sec-WebSocket-Version: 13\r\n\r\n"); + send(cid, cmd, strlen(cmd)); + + if (wsWait(cid, 101)) { + close(cid); + return -1; + } + wsWait(cid, 0); + return cid; +} + +int GSwifi::wsWait (int cid, int code) { + Timer timeout; + int i, n, len; + char buf[CFG_DATA_SIZE], data[CFG_CMD_SIZE]; + + if (code == 0) { + // dummy read + timeout.start(); + while (timeout.read_ms() < CFG_TIMEOUT) { + wait_ms(10); + if (!readable(cid)) break; + n = recv(cid, buf, sizeof(buf)); + if (n <= 0) break; + } + timeout.stop(); + return 0; + } + + // wait responce + len = 0; + timeout.start(); + while (timeout.read_ms() < CFG_TIMEOUT) { + wait_ms(10); + n = recv(cid, buf, sizeof(buf)); + for (i = 0; i < n; i ++) { + if (buf[i] == '\r') continue; + if (buf[i] == '\n') { + if (len == 0) continue; + goto next; + } else + if (len < sizeof(data) - 1) { + data[len] = buf[i]; + len ++; + } + } + } +next: + data[len] = 0; + timeout.stop(); + DBG("ws: %s\r\n", data); + + // check return code + if (strncmp(data, "HTTP/1.1 ", 9) != 0) return -1; + i = atoi(&data[9]); + DBG("ws status %d\r\n", i); + return i == code ? 0 : -1; +} + +int GSwifi::wsSend (int cid, const char *buf, int len, const char *mask) { + int i = 0, r; + char tmp[10]; + + tmp[i++] = 0x81; // single, text frame + if (len < 126) { + tmp[i++] = (mask == NULL ? 0 : 0x80) | len; + } else { + tmp[i++] = (mask == NULL ? 0 : 0x80) | 126; + tmp[i++] = (len >> 8) & 0xff; + tmp[i++] = len & 0xff; + } + if (mask) { + memcpy(&tmp[i], mask, 4); + i += 4; + } + r = send(cid, tmp, strlen(tmp)); + + if (r == 0) { + if (mask) { + char tmp2[len]; + for (i = 0; i < len; i ++) { + tmp2[i] = buf[i] ^ mask[i & 0x03]; + } + r = send(cid, tmp2, len); + } else { + r = send(cid, buf, len); + } + } + return r; +} + +#ifdef CFG_ENABLE_HTTPD + +void GSwifi::wsRecvData (int cid, char c) { + + switch (_httpd[cid].mode) { + case HTTPDMODE_WEBSOCKET: + if (_httpd[cid].n == 0) { + // flag + _httpd[cid].websocket_opcode = c & 0x0f; + _httpd[cid].websocket_flg = c << 8; + _httpd[cid].n ++; + } else + if (_httpd[cid].n == 1) { + // length 7bit + _httpd[cid].websocket_flg |= c; + _httpd[cid].length = c & 0x7f; + _httpd[cid].n ++; + if (_httpd[cid].length < 126) { + _httpd[cid].n = 0; + if (_httpd[cid].length) { + if (_httpd[cid].websocket_flg & 0x0080) { + _httpd[cid].mode = HTTPDMODE_WEBSOCKET_MASK; + } else { + _httpd[cid].mode = HTTPDMODE_WEBSOCKET_BODY; + } + } else { + _httpd[cid].mode = HTTPDMODE_WEBSOCKET_ENTER; + } + DBG("ws length %d\r\n", _httpd[cid].length); + } + } else { + // length 16bit,64bit + if (_httpd[cid].n == 2) { + _httpd[cid].length = c; + _httpd[cid].n ++; + } else + if (_httpd[cid].n < 9 && (_httpd[cid].websocket_flg & 0x7f) == 127) { + // 64bit + _httpd[cid].length = (_httpd[cid].length << 8) | c; + _httpd[cid].n ++; + } else { + // end + _httpd[cid].length = (_httpd[cid].length << 8) | c; + _httpd[cid].n = 0; + if (_httpd[cid].websocket_flg & 0x0080) { + _httpd[cid].mode = HTTPDMODE_WEBSOCKET_MASK; + } else { + _httpd[cid].mode = HTTPDMODE_WEBSOCKET_BODY; + } + DBG("ws length2 %d\r\n", _httpd[cid].length); + } + } + break; + case HTTPDMODE_WEBSOCKET_MASK: + // masking key + _httpd[cid].websocket_mask[_httpd[cid].n] = c; + _httpd[cid].n ++; + if (_httpd[cid].n >= 4) { + _httpd[cid].n = 0; + _httpd[cid].mode = HTTPDMODE_WEBSOCKET_BODY; + DBG("ws mask\r\n"); + } + break; + case HTTPDMODE_WEBSOCKET_BODY: + // payload + if (_httpd[cid].websocket_flg & 0x0080) { + // un-mask + _httpd[cid].buf->queue(c ^ _httpd[cid].websocket_mask[_httpd[cid].n & 0x03]); + } else { + _httpd[cid].buf->queue(c); + } + _httpd[cid].n ++; + if (_httpd[cid].n >= _httpd[cid].length) { + _httpd[cid].mode = HTTPDMODE_WEBSOCKET_ENTER; + _con[cid].received = true; + } + break; + } +} + +int GSwifi::wsParseRequest (int cid) { + int i; + + DBG("ws opcode %d\r\n", _httpd[cid].websocket_opcode); + switch (_httpd[cid].websocket_opcode) { + case 0x00: // continuation + break; + case 0x01: // text + case 0x02: // binary + i = httpdGetHandler(_httpd[cid].uri); + if (i >= 0) { + if (_httpd_handler[i].func) { + // cgi + _httpd_handler[i].func(cid); + } + } + break; + case 0x08: // close + close(cid); + break; + case 0x09: // ping + { + char pong[_httpd[cid].n + 2]; + pong[0] = 0x8a; + pong[1] = 0x04; + for (i = 0; i < _httpd[cid].length; i ++) { + if (_httpd[cid].buf->dequeue(&pong[i + 2]) == false) break; + } + send(cid, pong, _httpd[cid].length + 2); + } + break; + case 0x0a: // pong + break; + default: + break; + } + _httpd[cid].n = 0; + _httpd[cid].length = 0; + return 0; +} + +int GSwifi::wsAccept (int cid) { + char buf[CFG_CMD_SIZE], buf2[CFG_CMD_SIZE]; + + DBG("websocket accept: %d\r\n", cid); + + strcpy(buf, "HTTP/1.1 101 Switching Protocols\r\n"); + send(cid, buf, strlen(buf)); + strcpy(buf, "Upgrade: websocket\r\n"); + send(cid, buf, strlen(buf)); + strcpy(buf, "Connection: Upgrade\r\n"); + send(cid, buf, strlen(buf)); + + strcpy(buf, "Sec-WebSocket-Accept: "); + send(cid, buf, strlen(buf)); + strcpy(buf, _httpd[cid].websocket_key); + strcat(buf, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); + sha1(buf, strlen(buf), buf2); + base64encode(buf2, 20, buf, sizeof(buf)); + send(cid, buf, strlen(buf)); + strcpy(buf, "\r\n\r\n"); + send(cid, buf, strlen(buf)); + return 0; +} + +#endif +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi_msg.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,555 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "GSwifi.h" + +#ifdef CFG_ENABLE_RTOS +#undef DBG +#define DBG(x, ...) +#endif + +void GSwifi::recvData (char c) { + static int cid, sub, len, count; + +#ifdef DEBUG_DUMP + if (c < 0x20) { + DBG("%02x_", c); + } else { + DBG("%c_", c); + } +#endif + switch (_state.mode) { + case MODE_COMMAND: + switch (c) { + case 0: + case 0x0a: // LF + case 0x0d: // CR + break; + case 0x1b: // ESC + _state.buf->flush(); + _state.mode = MODE_ESCAPE; + break; + default: + _state.buf->flush(); + _state.buf->queue(c); + _state.mode = MODE_CMDRESP; + break; + } + break; + + case MODE_CMDRESP: + switch (c) { + case 0: + break; + case 0x0a: // LF + case 0x0d: // CR +// _state.buf->queue(c); + parseMessage(); + _state.mode = MODE_COMMAND; + break; + case 0x1b: // ESC + _state.mode = MODE_ESCAPE; + break; + default: + _state.buf->queue(c); + break; + } + break; + + case MODE_ESCAPE: + sub = 0; + switch (c) { + case 'H': + _state.mode = MODE_DATA_RXHTTP; + break; + case 'u': + _state.mode = MODE_DATA_RXUDP; + break; + case 'y': + _state.mode = MODE_DATA_RXUDP_BULK; + break; + case 'Z': + _state.mode = MODE_DATA_RX_BULK; + break; + case 'S': + _state.mode = MODE_DATA_RX; + break; + case ':': + _state.mode = MODE_DATA_RAW; + break; + case 'O': + _state.mode = MODE_COMMAND; + _state.ok = true; + return; + case 'F': + _state.mode = MODE_COMMAND; + _state.failure = true; + return; + default: + _state.mode = MODE_COMMAND; + return; + } + break; + + case MODE_DATA_RX: + case MODE_DATA_RXUDP: + switch (sub) { + case 0: + // cid + cid = x2i(c); + sub ++; + count = 0; + if (_state.mode == MODE_DATA_RX) { + sub = 3; + } + break; + case 1: + // ip + if ((c >= '0' && c <= '9') || c == '.') { + _con[cid].ip[count] = c; + count ++; + } else { + _con[cid].ip[count] = 0; + _con[cid].port = 0; + sub ++; + } + break; + case 2: + // port + if (c >= '0' && c <= '9') { + _con[cid].port = (_con[cid].port * 10) + (c - '0'); + } else { + sub ++; + count = 0; + } + break; + default: + // data + if (_state.escape) { + if (c == 'E') { + DBG("recv ascii %d %d/a\r\n", cid, count); + _con[cid].received = true; + _state.mode = MODE_COMMAND; + } else { + if (_con[cid].buf != NULL) { + _con[cid].buf->queue(0x1b); + _con[cid].buf->queue(c); + } + count += 2; + } + _state.escape = false; + } else + if (c == 0x1b) { + _state.escape = true; + } else { + if (_con[cid].buf != NULL) { + _con[cid].buf->queue(c); + if (_con[cid].buf->available() > CFG_DATA_SIZE - 16) { + setRts(false); + _con[cid].received = true; + WARN("buf full"); + } + } + count ++; + } + break; + } + break; + + case MODE_DATA_RX_BULK: + case MODE_DATA_RXUDP_BULK: + case MODE_DATA_RXHTTP: + switch (sub) { + case 0: + // cid + cid = x2i(c); + sub ++; + len = 0; + count = 0; + if (_state.mode != MODE_DATA_RXUDP_BULK) { + sub = 3; + } + break; + case 1: + // ip + if ((c >= '0' && c <= '9') || c == '.') { + _con[cid].ip[count] = c; + count ++; + } else { + _con[cid].ip[count] = 0; + _con[cid].port = 0; + sub ++; + } + break; + case 2: + // port + if (c >= '0' && c <= '9') { + _con[cid].port = (_con[cid].port * 10) + (c - '0'); + } else { + sub ++; + count = 0; + } + break; + case 3: + // length + len = (len * 10) + (c - '0'); + count ++; + if (count >= 4) { + sub ++; + count = 0; + } + break; + default: + // data +#ifdef CFG_ENABLE_HTTPD + if (_con[cid].protocol == PROTO_HTTPD) { + httpdRecvData(cid, c); + } else +#endif + if (_con[cid].buf != NULL) { + _con[cid].buf->queue(c); + if (_con[cid].buf->available() > CFG_DATA_SIZE - 16) { + setRts(false); + _con[cid].received = true; + WARN("buf full"); + } + } + count ++; + if (count >= len) { + DBG("recv bulk %d %d/%d\r\n", cid, count, len); + _con[cid].received = true; + _state.mode = MODE_COMMAND; + } + break; + } + break; + } +} + +#define MSG_TABLE_NUM 15 +#define RES_TABLE_NUM 11 +int GSwifi::parseMessage () { + int i; + char buf[256]; + static const struct MSG_TABLE { + const char msg[24]; + void (GSwifi::*func)(const char*); + } msg_table[MSG_TABLE_NUM] = { + {"OK", &GSwifi::msgOk}, + {"ERROR", &GSwifi::msgError}, + {"INVALID INPUT", &GSwifi::msgError}, + {"CONNECT ", &GSwifi::msgConnect}, + {"DISCONNECT ", &GSwifi::msgDisconnect}, + {"DISASSOCIATED", &GSwifi::msgDisassociated}, + {"Disassociated", &GSwifi::msgDisassociated}, + {"Disassociation Event", &GSwifi::msgDisassociated}, + {"Serial2WiFi APP", &GSwifi::msgReset}, + {"UnExpected Warm Boot", &GSwifi::msgReset}, + {"APP Reset-APP SW Reset", &GSwifi::msgReset}, + {"APP Reset-Wlan Except", &GSwifi::msgReset}, + {"Out of StandBy-Timer", &GSwifi::msgOutofStandby}, + {"Out of StandBy-Alarm", &GSwifi::msgOutofStandby}, + {"Out of Deep Sleep", &GSwifi::msgOutofDeepsleep}, + }; + static const struct RES_TABLE { + const Response res; + void (GSwifi::*func)(const char*); + } res_table[RES_TABLE_NUM] = { + {RES_NULL, NULL}, + {RES_CONNECT, &GSwifi::resConnect}, + {RES_WPAPSK, &GSwifi::resWpapsk}, + {RES_WPS, &GSwifi::resWps}, + {RES_MACADDRESS, &GSwifi::resMacAddress}, + {RES_DHCP, &GSwifi::resIp}, + {RES_DNSLOOKUP, &GSwifi::resLookup}, + {RES_HTTP, &GSwifi::resHttp}, + {RES_RSSI, &GSwifi::resRssi}, + {RES_TIME, &GSwifi::resTime}, + {RES_STATUS, &GSwifi::resStatus}, + }; + + for (i = 0; i < sizeof(buf); i++) { + if (_state.buf->dequeue(&buf[i]) == false) break; + } + buf[i] = 0; + + if (_state.res != RES_NULL) { + for (i = 0; i < RES_TABLE_NUM; i ++) { + if (res_table[i].res == _state.res) { + DBG("parse res %d '%s'\r\n", i, buf); + if (res_table[i].func != NULL) { + (this->*(res_table[i].func))(buf); + } + } + } + } + + for (i = 0; i < MSG_TABLE_NUM; i ++) { + if (strncmp(buf, msg_table[i].msg, strlen(msg_table[i].msg)) == 0) { + DBG("parse msg %d '%s'\r\n", i, buf); + if (msg_table[i].func != NULL) { + (this->*(msg_table[i].func))(buf); + } + return 0; + } + } + + return -1; +} + +void GSwifi::msgOk (const char *buf) { + _state.ok = true; + if (_state.status == STAT_DEEPSLEEP) { + _state.status = STAT_READY; + } +} + +void GSwifi::msgError (const char *buf) { + _state.failure = true; +} + +void GSwifi::msgConnect (const char *buf) { + int i, count; + int cid, acid; + + if (buf[8] < '0' || buf[8] > 'F' || buf[9] != ' ') return; + + cid = x2i(buf[8]); + acid = x2i(buf[10]); + DBG("forked %d -> %d\r\n", cid, acid); + // ip + count = 0; + for (i = 12; i < strlen(buf); i ++) { + if ((buf[i] >= '0' && buf[i] <= '9') || buf[i] == '.') { + _con[acid].ip[count] = buf[i]; + count ++; + } else { + _con[acid].ip[count] = 0; + break; + } + } + // port + _con[acid].port = 0; + count = 0; + for (; i < strlen(buf); i ++) { + if (buf[i] >= '0' && buf[i] <= '9') { + _con[acid].port = (_con[acid].port * 10) + (buf[i] - '0'); + } else { + break; + } + } + + // initialize + initCon(acid, true); + _con[acid].protocol = _con[cid].protocol; + _con[acid].type = _con[cid].type; + _con[acid].parent = cid; + _con[acid].func = _con[cid].func; + _con[acid].accept = true; +} + +void GSwifi::msgDisconnect (const char *buf) { + int cid; + + if (buf[11] < '0' || buf[11] > 'F') return; + + cid = x2i(buf[11]); + DBG("disconnect %d\r\n", cid); + _con[cid].connected = false; +} + +void GSwifi::msgDisassociated (const char *buf) { + int i; + DBG("disassociate\r\n"); + _state.associated = false; + for (i = 0; i < 16; i ++) { + _con[i].connected = false; + } +#ifdef CFG_ENABLE_RTOS + if (_threadPoll) + _threadPoll->signal_set(1); +#endif +} + +void GSwifi::msgReset (const char *buf) { + DBG("reset\r\n"); + _state.initialized = false; + _state.mode = MODE_COMMAND; + _state.status = STAT_READY; + msgDisassociated(NULL); + clearFlags(); +#ifdef CFG_ENABLE_RTOS + if (_threadPoll) { + _threadPoll->terminate(); + delete _threadPoll; + } +#endif +} + +void GSwifi::msgOutofStandby (const char *buf) { + DBG("OutofStandby\r\n"); + _state.status = STAT_WAKEUP; +} + +void GSwifi::msgOutofDeepsleep (const char *buf) { + DBG("OutofDeepsleep\r\n"); + _state.status = STAT_READY; +} + +void GSwifi::resConnect (const char *buf) { + int cid; + + // udp/tcp listen socket + if (strncmp(buf, "CONNECT ", 8) == 0 && buf[9] == 0) { + cid = x2i(buf[8]); + DBG("connect %d\r\n", cid); + // initialize + initCon(cid, true); + _state.cid = cid; + _state.res = RES_NULL; + } +} + +void GSwifi::resWpapsk (const char *buf) { + if (strncmp(buf, "Computing PSK from SSID and PassPhrase", 38) == 0) { + _state.res = RES_NULL; + DBG("wpapsk\r\n"); + } +} + +void GSwifi::resWps (const char *buf) { + if (_state.n == 0 && strncmp(buf, "SSID", 4) == 0) { + strncpy(_state.ssid, &buf[5], sizeof(_state.ssid)); + _state.n ++; + } else + if (_state.n == 1 && strncmp(buf, "CHANNEL", 7) == 0) { + _state.n ++; + } else + if (_state.n == 2 && strncmp(buf, "PASSPHRASE", 10) == 0) { + strncpy(_state.pass, &buf[11], sizeof(_state.pass)); + _state.n ++; + _state.res = RES_NULL; + DBG("wps %s %s\r\n", _state.ssid, _state.pass); + } +} + +void GSwifi::resMacAddress (const char *buf) { + if (buf[2] == ':' && buf[5] == ':') { + strncpy(_state.mac, buf, sizeof(_state.mac)); + _state.mac[17] = 0; + _state.res = RES_NULL; + DBG("mac %s\r\n", _state.mac); + } +} + +void GSwifi::resIp (const char *buf) { + const char *tmp, *tmp2; + + if (_state.n == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) { + _state.n ++; + } else + if (_state.n == 1) { + tmp = buf + 1; + tmp2 = strstr(tmp, ":"); + strncpy(_state.ip, tmp, tmp2 - tmp); + tmp = tmp2 + 2; + tmp2 = strstr(tmp, ":"); + strncpy(_state.netmask, tmp, tmp2 - tmp); + tmp = tmp2 + 2; + strncpy(_state.gateway, tmp, sizeof(_state.gateway)); + _state.n ++; + _state.res = RES_NULL; + DBG("ip: %s\r\nnetmask: %s\r\ngateway: %s", _state.ip, _state.netmask, _state.gateway); + } +} + +void GSwifi::resLookup (const char *buf) { + if (strncmp(buf, "IP:", 3) == 0) { + strncpy(_state.resolv, &buf[3], sizeof(_state.resolv)); + _state.res = RES_NULL; + DBG("resolv: %s\r\n", _state.resolv); + } +} + +void GSwifi::resRssi (const char *buf) { + if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) { + _state.rssi = atoi(buf); + _state.res = RES_NULL; + DBG("rssi: %d\r\n", _state.rssi); + } +} + +void GSwifi::resTime (const char *buf) { + int year, month, day, hour, min, sec; + struct tm t; + if (buf[0] >= '0' && buf[0] <= '9') { + 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; + _state.time = mktime(&t); + _state.res = RES_NULL; + } +} + +void GSwifi::resChannel (const char *buf) { +} + +void GSwifi::resStatus (const char *buf) { + if (_state.n == 0 && strncmp(buf, "NOT ASSOCIATED", 14) == 0) { + msgDisassociated(NULL); + _state.res = RES_NULL; + } + + if (_state.n == 0 && strncmp(buf, "MODE:", 5) == 0) { + _state.n ++; + } else + if (_state.n == 1 && strncmp(buf, "BSSID:", 6) == 0) { + const char *tmp = strstr(buf, "SECURITY:") + 2; + if (strncmp(tmp, "WEP (OPEN)", 10) == NULL) { + _state.sec = SEC_OPEN; + } else + if (strncmp(tmp, "WEP (SHARED)", 12) == NULL) { + _state.sec = SEC_WEP; + } else + if (strncmp(tmp, "WPA-PERSONAL", 12) == NULL) { + _state.sec = SEC_WPA_PSK; + } else + if (strncmp(tmp, "WPA2-PERSONAL", 13) == NULL) { + _state.sec = SEC_WPA2_PSK; + } + _state.res = RES_NULL; + } +} + +void GSwifi::resHttp (const char *buf) { + int cid; + + // http client socket + if (buf[0] >= '0' && buf[0] <= 'F' && buf[1] == 0) { + cid = x2i(buf[0]); + DBG("connect %d\r\n", cid); + // initialize + initCon(cid, true); + _state.cid = cid; + _state.res = RES_NULL; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi_smtp.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,145 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "GSwifi.h" + +#ifdef CFG_ENABLE_SMTP + +int GSwifi::mail (const char *host, int port, const char *to, const char *from, const char *subject, const char *mesg, const char *user, const char *pwd) { + int ret = -1; + int cid; + char cmd[CFG_DATA_SIZE]; + char ip[17]; + + if (!isAssociated() || _state.status != STAT_READY) return -1; + + if (getHostByName(host, ip)) return -1; + if (! port) { + port = 25; + } + + cid = open(PROTO_TCP, ip, port); + if (cid < 0) return -1; + DBG("cid %d\r\n", cid); + + if (smtpWait(cid ,220)) goto exit; + + // send request + snprintf(cmd, sizeof(cmd), "EHLO %s\r\n", _state.name); + send(cid, cmd, strlen(cmd)); + wait_ms(100); + if (smtpWait(cid ,250)) goto quit; + smtpWait(cid ,0); + + if (user && pwd) { + // smtp auth + int len; + snprintf(cmd, sizeof(cmd), "%s%c%s%c%s", user, 0, user, 0, pwd); + len = strlen(user) * 2 + strlen(pwd) + 2; + char tmp[len + (len / 2)]; + base64encode(cmd, len, tmp, sizeof(tmp)); + snprintf(cmd, sizeof(cmd), "AUTH PLAIN %s\r\n", tmp); + send(cid, cmd, strlen(cmd)); + if (smtpWait(cid ,235)) goto quit; + } + + snprintf(cmd, sizeof(cmd), "MAIL FROM: %s\r\n", from); + send(cid, cmd, strlen(cmd)); + if (smtpWait(cid ,250)) goto quit; + + snprintf(cmd, sizeof(cmd), "RCPT TO: %s\r\n", to); + send(cid, cmd, strlen(cmd)); + if (smtpWait(cid ,250)) goto quit; + + strcpy(cmd, "DATA\r\n"); + send(cid, cmd, strlen(cmd)); + if (smtpWait(cid ,354)) goto quit; + + // mail data + snprintf(cmd, sizeof(cmd), "From: %s\r\n", from); + send(cid, cmd, strlen(cmd)); + snprintf(cmd, sizeof(cmd), "To: %s\r\n", to); + send(cid, cmd, strlen(cmd)); + snprintf(cmd, sizeof(cmd), "Subject: %s\r\n\r\n", subject); + send(cid, cmd, strlen(cmd)); + + send(cid, mesg, strlen(mesg)); + strcpy(cmd, "\r\n.\r\n"); + send(cid, cmd, strlen(cmd)); + if (smtpWait(cid ,250)) goto quit; + ret = 0; + + INFO("Mail, from: %s, to: %s %d\r\n", from, to, strlen(mesg)); + +quit: + strcpy(cmd, "QUIT\r\n"); + send(cid, cmd, strlen(cmd)); + smtpWait(cid ,221); +exit: + close(cid); + return ret; +} + +int GSwifi::smtpWait (int cid, int code) { + Timer timeout; + int i, n, len = 0; + char buf[CFG_CMD_SIZE], data[CFG_CMD_SIZE]; + + if (code == 0) { + // dummy read + timeout.start(); + while (timeout.read_ms() < CFG_TIMEOUT) { + wait_ms(10); + if (!readable(cid)) break; + n = recv(cid, buf, sizeof(buf)); + if (n <= 0) break; + } + timeout.stop(); + return 0; + } + + // wait responce + len = 0; + timeout.start(); + while (timeout.read_ms() < CFG_TIMEOUT) { + wait_ms(10); + n = recv(cid, buf, sizeof(buf)); + for (i = 0; i < n; i ++) { + if (buf[i] == '\r') continue; + if (buf[i] == '\n') { + if (len == 0) continue; + goto next; + } else + if (len < sizeof(data) - 1) { + data[len] = buf[i]; + len ++; + } + } + } +next: + data[len] = 0; + DBG("smtp: %s\r\n", data); + timeout.stop(); + + // check return code + i = atoi(data); + DBG("smtp status %d\r\n", i); + return i == code ? 0 : -1; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi_sock.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,201 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "GSwifi.h" + +int GSwifi::getHostByName(const char * host, char * ip) +{ + int i, flg = 0; + + if (!isAssociated() || _state.status != STAT_READY) return -1; + + 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 0; + } + + if (cmdDNSLOOKUP(host)) { + // retry + wait_ms(1000); + if (cmdDNSLOOKUP(host)) return -1; + } + strncpy(ip, _state.resolv, 16); + return 0; +} + +int GSwifi::open (Protocol proto, const char *ip, int port, int src, void(*func)(int)) { + int cid; + + if (!isAssociated() || _state.status != STAT_READY) return -1; + + _state.cid = -1; + if (proto == PROTO_TCP) { + if (cmdNCTCP(ip, port)) return -1; + } else { + if (cmdNCUDP(ip, port, src)) return -1; + } + if (_state.cid < 0) return -1; + cid = _state.cid; + _con[cid].protocol = proto; + _con[cid].type = TYPE_CLIENT; + _con[cid].func = func; + return cid; +} + +int GSwifi::listen (Protocol proto, int port, void(*func)(int)) { + int cid; + + if (!isAssociated() || _state.status != STAT_READY) return -1; + + _state.cid = -1; + if (proto == PROTO_TCP) { + if (cmdNSTCP(port)) return -1; + } else { + if (cmdNSUDP(port)) return -1; + } + if (_state.cid < 0) return -1; + cid = _state.cid; + _con[cid].protocol = proto; + _con[cid].type = TYPE_SERVER; + _con[cid].func = func; + return cid; +} + +int GSwifi::close (int cid) { + + if (!isConnected(cid)) return -1; + + _con[cid].connected = false; + return cmdNCLOSE(cid); +} + +int GSwifi::send (int cid, const char *buf, int len) { + char cmd[CFG_CMD_SIZE]; + + if (!isConnected(cid)) return -1; + + if ((_con[cid].protocol == PROTO_TCP) || + (_con[cid].protocol == PROTO_UDP && _con[cid].type == TYPE_CLIENT) || + (_con[cid].protocol == PROTO_HTTPD)) { + if (len > CFG_DATA_SIZE) len = CFG_DATA_SIZE; + sprintf(cmd, "\x1bZ%X%04d", cid, len); + return sendData(buf, len, CFG_TIMEOUT, cmd); + } else { + return -1; + } +} + +int GSwifi::sendto (int cid, const char *buf, int len, const char *ip, int port) { + char cmd[CFG_CMD_SIZE]; + + if (!isConnected(cid)) return -1; + + if ((_con[cid].protocol == PROTO_UDP && _con[cid].type == TYPE_SERVER)) { + if (len > CFG_DATA_SIZE) len = CFG_DATA_SIZE; + sprintf(cmd, "\x1bY%X%s:%d:%04d", cid, ip, port, len); + return sendData(buf, len, CFG_TIMEOUT, cmd); + } else { + return -1; + } +} + +int GSwifi::recv (int cid, char *buf, int len) { + int i; + + if (!isConnected(cid)) return -1; + + if (_con[cid].buf == NULL) return 0; + while (!_con[cid].received && _state.mode != MODE_COMMAND); + _con[cid].received = false; + for (i = 0; i < len; i ++) { + if (_con[cid].buf->dequeue(&buf[i]) == false) break; + } + setRts(true); + return i; +} + +int GSwifi::recvfrom (int cid, char *buf, int len, char *ip, int *port) { + int i; + + if (!isConnected(cid)) return -1; + + if (_con[cid].buf == NULL) return 0; + while (!_con[cid].received && _state.mode != MODE_COMMAND); + _con[cid].received = false; + for (i = 0; i < len; i ++) { + if (_con[cid].buf->dequeue(&buf[i]) == false) break; + } + strncpy(ip, _con[cid].ip, 16); + *port = _con[cid].port; + setRts(true); + return i; +} + +int GSwifi::readable (int cid) { + if (!isConnected(cid)) return -1; + + if (_con[cid].buf == NULL) return -1; + return _con[cid].buf->available(); +} + +bool GSwifi::isConnected (int cid) { + if (cid < 0 || cid >= 16) return false; + + return _con[cid].connected; +} + +int GSwifi::accept (int cid) { + int i; + + if (!isConnected(cid)) return -1; + + for (i = 0; i < 16; i ++) { + if (_con[i].connected && _con[i].accept && _con[i].parent == cid) { + _con[i].accept = false; + return i; + } + } + return -1; +} + +int GSwifi::getRemote(int cid, char **ip, int *port) { + + if (!isConnected(cid)) return -1; + + *ip = _con[cid].ip; + *port = _con[cid].port; + return 0; +} + +void GSwifi::initCon (int cid, bool connected) { + _con[cid].parent = -1; + _con[cid].func = NULL; + _con[cid].accept = false; + if (_con[cid].buf == NULL) { + _con[cid].buf = new CircBuffer<char>(CFG_DATA_SIZE); + if (_con[cid].buf == NULL) error("Can't allocate memory"); + } + _con[cid].buf->flush(); + _con[cid].connected = connected; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/GSwifi_util.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,177 @@ +/* Copyright (C) 2013 gsfan, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "GSwifi.h" + +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; +} + +int GSwifi::from_hex (int ch) { + return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; +} + +int GSwifi::to_hex (int code) { + static char hex[] = "0123456789abcdef"; + return hex[code & 15]; +} + + +int GSwifi::setRegion (int reg) { + return cmdWREGDOMAIN(reg); +} + +int GSwifi::getRssi () { + cmdWRSSI(); + return _state.rssi; +} + +int GSwifi::powerSave (int active, int save) { + cmdWRXACTIVE(active); + return cmdWRXPS(save); +} + +int GSwifi::setRfPower (int power) { + if (power < 0 || power > 7) return false; + return cmdWP(power); +} + +int GSwifi::setTime (time_t time) { + char dmy[16], hms[16]; + struct tm *t = localtime(&time); + + sprintf(dmy, "%d/%d/%d", t->tm_mday, t->tm_mon + 1, t->tm_year + 1900); + sprintf(hms, "%d:%d:%d", t->tm_hour, t->tm_min, t->tm_sec); + return cmdSETTIME(dmy, hms); +} + +time_t GSwifi::getTime () { + cmdGETTIME(); + return _state.time; +} + +int GSwifi::ntpdate (char *host, int sec) { + char ip[17]; + + if (!isAssociated() || _state.status != STAT_READY) return -1; + + if (getHostByName(host, ip)) return -1; + return cmdNTIMESYNC(true, ip, sec); +} + +int GSwifi::setGpio (int port, int out) { + return cmdDGPIO(port, out); +} + +int GSwifi::provisioning (char *user, char *pass) { + + if (!isAssociated() || _state.status != STAT_READY) return -1; + + return cmdWEBPROV(user, pass); +} + +int GSwifi::standby (int msec) { + switch (_state.status) { + case STAT_READY: + cmdNCLOSEALL(); + for (int i = 0; i < 16; i ++) { + _con[i].connected = false; + } + cmdSTORENWCONN(); +// cmdWRXACTIVE(false); + break; + case STAT_WAKEUP: + if (cmdE(false)) return -1; + if (_flow) { + cmdR(true); + } + break; + default: + return -1; + } + + _state.status = STAT_STANDBY; + return cmdPSSTBY(msec, 0); +} + + +int GSwifi::deepSleep () { + if (_state.status != STAT_READY) return -1; + + _state.status = STAT_DEEPSLEEP; + return cmdPSDPSLEEP(); // go deep sleep +} + +int GSwifi::wakeup () { + int r; + + if (_state.status == STAT_STANDBY) { + Timer timeout; + setAlarm(true); + timeout.start(); + while (timeout.read() < CFG_TIMEOUT) { + if (_state.status == STAT_WAKEUP) break; + } + timeout.stop(); + setAlarm(false); + } + + switch (_state.status) { + case STAT_WAKEUP: + if (cmdE(false)) return -1; + if (_flow) { + cmdR(true); + } + cmdBDATA(true); + r = cmdRESTORENWCONN(); + if (!r) { + wait_ms(100); +// cmdWRXACTIVE(true); + _state.status = STAT_READY; + } + return r; + case STAT_DEEPSLEEP: + r = cmdAT(); + if (!r) { + _state.status = STAT_READY; + } + return r; + default: + break; + } + return -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/sha1.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,364 @@ +/* + * source from http://www.ipa.go.jp/security/rfc/RFC3174JA.html + */ +#include "sha1.h" + +/* + * Define the SHA1 circular left shift macro + */ +#define SHA1CircularShift(bits,word) \ + (((word) << (bits)) | ((word) >> (32-(bits)))) + +/* Local Function Prototyptes */ +void SHA1PadMessage(SHA1Context *); +void SHA1ProcessMessageBlock(SHA1Context *); + +/* + * SHA1Reset + * + * Description: + * This function will initialize the SHA1Context in preparation + * for computing a new SHA1 message digest. + * + * Parameters: + * context: [in/out] + * The context to reset. + * + * Returns: + * sha Error Code. + * + */ +int SHA1Reset(SHA1Context *context) +{ + if (!context) + { + return shaNull; + } + + context->Length_Low = 0; + context->Length_High = 0; + context->Message_Block_Index = 0; + + context->Intermediate_Hash[0] = 0x67452301; + context->Intermediate_Hash[1] = 0xEFCDAB89; + context->Intermediate_Hash[2] = 0x98BADCFE; + context->Intermediate_Hash[3] = 0x10325476; + context->Intermediate_Hash[4] = 0xC3D2E1F0; + + context->Computed = 0; + context->Corrupted = 0; + + return shaSuccess; +} + +/* + * SHA1Result + * + * Description: + * This function will return the 160-bit message digest into the + * Message_Digest array provided by the caller. + * NOTE: The first octet of hash is stored in the 0th element, + * the last octet of hash in the 19th element. + * + * Parameters: + * context: [in/out] + * The context to use to calculate the SHA-1 hash. + * Message_Digest: [out] + * Where the digest is returned. + * + * Returns: + * sha Error Code. + * + */ +int SHA1Result( SHA1Context *context, + uint8_t Message_Digest[SHA1HashSize]) +{ + int i; + + if (!context || !Message_Digest) + { + return shaNull; + } + + if (context->Corrupted) + { + return context->Corrupted; + } + + if (!context->Computed) + { + SHA1PadMessage(context); + for(i=0; i<64; ++i) + { + /* message may be sensitive, clear it out */ + context->Message_Block[i] = 0; + } + context->Length_Low = 0; /* and clear length */ + context->Length_High = 0; + context->Computed = 1; + } + + for(i = 0; i < SHA1HashSize; ++i) + { + Message_Digest[i] = context->Intermediate_Hash[i>>2] + >> 8 * ( 3 - ( i & 0x03 ) ); + } + + return shaSuccess; +} + +/* + * SHA1Input + * + * Description: + * This function accepts an array of octets as the next portion + * of the message. + * + * Parameters: + * context: [in/out] + * The SHA context to update + * message_array: [in] + * An array of characters representing the next portion of + * the message. + * length: [in] + * The length of the message in message_array + * + * Returns: + * sha Error Code. + * + */ +int SHA1Input( SHA1Context *context, + const uint8_t *message_array, + unsigned length) +{ + if (!length) + { + return shaSuccess; + } + + if (!context || !message_array) + { + return shaNull; + } + + if (context->Computed) + { + context->Corrupted = shaStateError; + return shaStateError; + } + + if (context->Corrupted) + { + return context->Corrupted; + } + while(length-- && !context->Corrupted) + { + context->Message_Block[context->Message_Block_Index++] = + (*message_array & 0xFF); + + context->Length_Low += 8; + if (context->Length_Low == 0) + { + context->Length_High++; + if (context->Length_High == 0) + { + /* Message is too long */ + context->Corrupted = 1; + } + } + + if (context->Message_Block_Index == 64) + { + SHA1ProcessMessageBlock(context); + } + + message_array++; + } + + return shaSuccess; +} + +/* + * SHA1ProcessMessageBlock + * + * Description: + * This function will process the next 512 bits of the message + * stored in the Message_Block array. + * + * Parameters: + * None. + * + * Returns: + * Nothing. + * + * Comments: + * Many of the variable names in this code, especially the + * single character names, were used because those were the + * names used in the publication. + * + * + */ +void SHA1ProcessMessageBlock(SHA1Context *context) +{ + const uint32_t K[] = { /* Constants defined in SHA-1 */ + 0x5A827999, + 0x6ED9EBA1, + 0x8F1BBCDC, + 0xCA62C1D6 + }; + int t; /* Loop counter */ + uint32_t temp; /* Temporary word value */ + uint32_t W[80]; /* Word sequence */ + uint32_t A, B, C, D, E; /* Word buffers */ + + /* + * Initialize the first 16 words in the array W + */ + for(t = 0; t < 16; t++) + { + W[t] = context->Message_Block[t * 4] << 24; + W[t] |= context->Message_Block[t * 4 + 1] << 16; + W[t] |= context->Message_Block[t * 4 + 2] << 8; + W[t] |= context->Message_Block[t * 4 + 3]; + } + + for(t = 16; t < 80; t++) + { + W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); + } + + A = context->Intermediate_Hash[0]; + B = context->Intermediate_Hash[1]; + C = context->Intermediate_Hash[2]; + D = context->Intermediate_Hash[3]; + E = context->Intermediate_Hash[4]; + + for(t = 0; t < 20; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 20; t < 40; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 40; t < 60; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 60; t < 80; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + context->Intermediate_Hash[0] += A; + context->Intermediate_Hash[1] += B; + context->Intermediate_Hash[2] += C; + context->Intermediate_Hash[3] += D; + context->Intermediate_Hash[4] += E; + + context->Message_Block_Index = 0; +} + + +/* + * SHA1PadMessage + * + * Description: + * According to the standard, the message must be padded to an even + * 512 bits. The first padding bit must be a '1'. The last 64 + * bits represent the length of the original message. All bits in + * between should be 0. This function will pad the message + * according to those rules by filling the Message_Block array + * accordingly. It will also call the ProcessMessageBlock function + * provided appropriately. When it returns, it can be assumed that + * the message digest has been computed. + * + * Parameters: + * context: [in/out] + * The context to pad + * ProcessMessageBlock: [in] + * The appropriate SHA*ProcessMessageBlock function + * Returns: + * Nothing. + * + */ + +void SHA1PadMessage(SHA1Context *context) +{ + /* + * Check to see if the current message block is too small to hold + * the initial padding bits and length. If so, we will pad the + * block, process it, and then continue padding into a second + * block. + */ + if (context->Message_Block_Index > 55) + { + context->Message_Block[context->Message_Block_Index++] = 0x80; + while(context->Message_Block_Index < 64) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + + SHA1ProcessMessageBlock(context); + + while(context->Message_Block_Index < 56) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + } + else + { + context->Message_Block[context->Message_Block_Index++] = 0x80; + while(context->Message_Block_Index < 56) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + } + + /* + * Store the message length as the last 8 octets + */ + context->Message_Block[56] = context->Length_High >> 24; + context->Message_Block[57] = context->Length_High >> 16; + context->Message_Block[58] = context->Length_High >> 8; + context->Message_Block[59] = context->Length_High; + context->Message_Block[60] = context->Length_Low >> 24; + context->Message_Block[61] = context->Length_Low >> 16; + context->Message_Block[62] = context->Length_Low >> 8; + context->Message_Block[63] = context->Length_Low; + + SHA1ProcessMessageBlock(context); +} + +void sha1 (const char *input, int len, char *output) { + SHA1Context sha; + + SHA1Reset(&sha); + SHA1Input(&sha, (unsigned char*)input, len); + SHA1Result(&sha, (uint8_t*)output); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifi/sha1.h Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,78 @@ +/* + * source from http://www.ipa.go.jp/security/rfc/RFC3174JA.html + */ +/* + * sha1.h + * + * Description: + * This is the header file for code which implements the Secure + * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published + * April 17, 1995. + * + * Many of the variable names in this code, especially the + * single character names, were used because those were the names + * used in the publication. + * + * Please read the file sha1.c for more information. + * + */ + +#ifndef _SHA1_H_ +#define _SHA1_H_ + +#include "mbed.h" +/* + * If you do not have the ISO standard stdint.h header file, then you + * must typdef the following: + * name meaning + * uint32_t unsigned 32 bit integer + * uint8_t unsigned 8 bit integer (i.e., unsigned char) + * int_least16_t integer of >= 16 bits + * + */ + +#ifndef _SHA_enum_ +#define _SHA_enum_ +enum +{ + shaSuccess = 0, + shaNull, /* Null pointer parameter */ + shaInputTooLong, /* input data too long */ + shaStateError /* called Input after Result */ +}; +#endif +#define SHA1HashSize 20 + +/* + * This structure will hold context information for the SHA-1 + * hashing operation + */ +typedef struct SHA1Context +{ + uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ + + uint32_t Length_Low; /* Message length in bits */ + uint32_t Length_High; /* Message length in bits */ + + /* Index into message block array */ + int_least16_t Message_Block_Index; + uint8_t Message_Block[64]; /* 512-bit message blocks */ + + int Computed; /* Is the digest computed? */ + int Corrupted; /* Is the message digest corrupted? */ +} SHA1Context; + +/* + * Function Prototypes + */ + +int SHA1Reset( SHA1Context *); +int SHA1Input( SHA1Context *, + const uint8_t *, + unsigned int); +int SHA1Result( SHA1Context *, + uint8_t Message_Digest[SHA1HashSize]); + + +void sha1 (const char *input, int len, char *output); +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifiInterface.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,59 @@ +/* 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, PinName alarm, int baud) : + GSwifi(tx, rx, cts, rts, reset, alarm, baud) +{ +} + +int GSwifiInterface::init(const char* name) +{ + return setAddress(name); +} + +int GSwifiInterface::init(const char* ip, const char* netmask, const char* gateway, const char* name) +{ + return setAddress(ip, netmask, gateway, name); +} + +int GSwifiInterface::connect(Security sec, const char* ssid, const char* phrase, WiFiMode mode) +{ + setSsid(sec, ssid, phrase); + switch (mode) { + case WM_INFRASTRUCTURE: + return join(); + case WM_ADHOCK: + return adhock(); + case WM_LIMITEDAP: + return limitedap(); + } + return -1; +} + +int GSwifiInterface::disconnect() +{ + return GSwifi::dissociate(); +} + +char * GSwifiInterface::getMACAddress() +{ + return _state.mac; +} + +char * GSwifiInterface::getIPAddress() +{ + return _state.ip; +} + +char * GSwifiInterface::getGateway() +{ + return _state.gateway; +} + +char * GSwifiInterface::getNetworkMask() +{ + return _state.netmask; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/GSwifiInterface.h Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,107 @@ +/* GSwifiInterface.h */ +/* EthernetInterface.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 alarm alarm pin of the wifi module (default: NC) + * \param baud baud rate of Serial interface (default: 9600) + */ + GSwifiInterface(PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, PinName alarm = NC, int baud = 9600); + + /** 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(const char* name = NULL); //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, const char* name = NULL); + + /** Connect + * Bring the interface up, start DHCP if needed. + * \param sec the Wi-Fi security type + * \param ssid the Wi-Fi SSID + * \param phrase the Wi-Fi passphrase or security key + * \param mode the Wi-Fi mode + * \return 0 on success, a negative number on failure + */ + int connect(Security sec, const char* ssid, const char* phrase, WiFiMode mode = WM_INFRASTRUCTURE); + + /** Disconnect + * Bring the interface down + * \return 0 on success, a negative number on failure + */ + int disconnect(); + + /** Get the MAC address of your Ethernet interface + * \return a pointer to a string containing the MAC address + */ + char* getMACAddress(); + + /** Get the IP address of your Ethernet interface + * \return a pointer to a string containing the IP address + */ + char* getIPAddress(); + + /** Get the Gateway address of your Ethernet interface + * \return a pointer to a string containing the Gateway address + */ + char* getGateway(); + + /** Get the Network mask of your Ethernet interface + * \return a pointer to a string containing the Network mask + */ + char* getNetworkMask(); + +}; + +#include "TCPSocketConnection.h" +#include "TCPSocketServer.h" + +#include "Endpoint.h" +#include "UDPSocket.h" + +#endif /* GSWIFIINTERFACE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/Helper/def.h Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,28 @@ +/* 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 DEF_H +#define DEF_H + +#include "cmsis.h" +#define htons(x) __REV16(x) +#define ntohs(x) __REV16(x) +#define htonl(x) __REV(x) +#define ntohl(x) __REV(x) + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/Socket/Endpoint.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +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. + */ +/* 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); +} + +char* Endpoint::get_address() { + return _ipAddress; +} + +int Endpoint::get_port() { + return _port; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/Socket/Endpoint.h Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +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. + */ +/* 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/Socket/Socket.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +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. + */ +/* 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() { + if (_cid < 0) return 0; + + _wifi->close(_cid); + _cid = -1; + return 0; +} + +Socket::~Socket() { + close(); //Don't want to leak +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/Socket/Socket.h Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +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. + */ +/* 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_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/Socket/TCPSocketConnection.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,136 @@ +/* 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) +{ + if (set_address(host, port) != 0) return -1; + + _server = false; + _cid = _wifi->open(GSwifi::PROTO_TCP, get_address(), get_port()); + if (_cid < 0) return -1; + + return 0; +} + +bool TCPSocketConnection::is_connected(void) +{ + bool _is_connected = _wifi->isConnected(_cid); + if (!_is_connected) _cid = -1; + return _is_connected; +} + +int TCPSocketConnection::send(char* data, int length) +{ + if (_cid < 0 || !is_connected()) return -1; + + // TCP Client/Server + return _wifi->send(_cid, data, length); +} + +// -1 if unsuccessful, else number of bytes written +int TCPSocketConnection::send_all(char* data, int length) +{ + Timer tmr; + int idx = 0; + + if (_cid < 0 || !is_connected()) return -1; + + tmr.start(); + // TCP Client/Server + while ((tmr.read_ms() < _timeout) || _blocking) { + + idx += _wifi->send(_cid, &data[idx], length - idx); + if (idx < 0) 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 (_cid < 0 || !is_connected()) return -1; + + if (_blocking) { + tmr.start(); + while (time < _timeout + 20) { + if (_wifi->readable(_cid)) { + DBG("receive readable"); + break; + } + time = tmr.read_ms(); + } + if (time >= _timeout + 20) { + DBG("receive timeout"); + return 0; + } + } + + int nb_available = _wifi->recv(_cid, data, length); + + return nb_available; +} + + +// -1 if unsuccessful, else number of bytes received +int TCPSocketConnection::receive_all(char* data, int length) +{ + Timer tmr; + int idx = 0; + int time = -1; + + if (_cid < 0 || !is_connected()) return -1; + + tmr.start(); + + while (time < _timeout || _blocking) { + + idx += _wifi->recv(_cid, &data[idx], length - idx); + if (idx < 0) return -1; + + if (idx == length) + break; + + time = tmr.read_ms(); + } + + return (idx == 0) ? -1 : idx; +} + +void TCPSocketConnection::acceptCID (int cid) { + char *ip; + int port; + _server = true; + _cid = cid; + if (!_wifi->getRemote(_cid, &ip, &port)) { + set_address(ip, port); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/Socket/TCPSocketConnection.h Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +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. + */ +/* 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 acceptCID (int cid); +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/Socket/TCPSocketServer.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +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. + */ +/* 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) { + _server = true; + if (_cid < 0) { + // Socket open + _server = false; + _cid = _wifi->listen(GSwifi::PROTO_TCP, _port); + if (_cid < 0) return -1; + } + + if (backlog != 1) + return -1; + return 0; +} + + +int TCPSocketServer::accept(TCPSocketConnection& connection) { + int acid = -1; + while (1) { + while (acid < 0) { + acid = _wifi->accept(_cid); + } + if (acid >= 0) { + connection.acceptCID(acid); + return 0; + } + } + return -1; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/Socket/TCPSocketServer.h Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,55 @@ +/* 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 TCPSOCKETSERVER_H +#define TCPSOCKETSERVER_H + +#include "Socket/Socket.h" +#include "TCPSocketConnection.h" + +/** TCP Server. + */ +class TCPSocketServer : public Socket { + public: + /** Instantiate a TCP Server. + */ + TCPSocketServer(); + + /** Bind a 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); + + /** Start listening for incoming connections. + \param backlog number of pending connections that can be queued up at any + one time [Default: 1]. + \return 0 on success, -1 on failure. + */ + int listen(int backlog=1); + + /** Accept a new connection. + \param connection A TCPSocketConnection instance that will handle the incoming connection. + \return 0 on success, -1 on failure. + */ + int accept(TCPSocketConnection& connection); +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/Socket/UDPSocket.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -0,0 +1,140 @@ +/* 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; + + if (_cid < 0 && _wifi->isAssociated()) { + // Socket open + if (_server) { + _cid = _wifi->listen(GSwifi::PROTO_UDP, _port); + } else { + _cid = _wifi->open(GSwifi::PROTO_UDP, remote.get_address(), remote.get_port(), _port); + } + if (_cid < 0) return -1; + } + + tmr.start(); + + while ((tmr.read_ms() < _timeout) || _blocking) { + + if (_server) { + idx += _wifi->sendto(_cid, packet, length, remote.get_address(), remote.get_port()); + } else { + idx += _wifi->send(_cid, packet, length); + } + if (idx < 0) { + if (!_wifi->isConnected(_cid)) _cid = -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 time = -1; + char ip[16]; + int port; + + if (_cid < 0 && _wifi->isAssociated()) { + // Socket open + if (_server) { + _cid = _wifi->listen(GSwifi::PROTO_UDP, _port); + } else { + _cid = _wifi->open(GSwifi::PROTO_UDP, remote.get_address(), remote.get_port(), _port); + } + if (_cid < 0) return -1; + } + + if (_blocking) { + tmr.start(); + while (time < _timeout + 20) { + if (_wifi->readable(_cid)) { + break; + } + time = tmr.read_ms(); + } + if (time >= _timeout + 20) { + return -1; + } + } + + tmr.reset(); + time = -1; + tmr.start(); + + while (time < _timeout) { + + if (_server) { + idx += _wifi->recvfrom(_cid, &buffer[idx], length - idx, ip, &port); + } else { + idx += _wifi->recv(_cid, &buffer[idx], length - idx); + } + if (idx < 0) { + if (!_wifi->isConnected(_cid)) _cid = -1; + return -1; + } + + if (idx == length) { + break; + } + + time = tmr.read_ms(); + } + + if (_server) { + remote.set_address(ip, port); + } + return (idx == 0) ? -1 : idx; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GSwifiInterface/Socket/UDPSocket.h Wed Nov 27 08:18:45 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. + */ +/* 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; + +}; + +#include "def.h" + +#endif
--- a/main.cpp Tue Aug 20 04:34:57 2013 +0000 +++ b/main.cpp Wed Nov 27 08:18:45 2013 +0000 @@ -5,7 +5,7 @@ #define INTERVAL 60 #define CT (3000 / 330 / 0.98) -#define SECURE GSwifi::GSSEC_WPA_PSK +#define SECURE GSwifi::SEC_WPA_PSK #define SSID "SSID" #define PASS "passkey" @@ -13,8 +13,8 @@ #define FEED_ID "000000" #define API_KEY "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -//GSwifi gs(p13, p14, p20); // LPC1768, LPC11U24 -GSwifi gs(PTD3, PTD2, PTA13); // FRDM KL25Z +//GSwifi gs(p13, p14, NC, NC, p20); // LPC1768, LPC11U24 +GSwifi gs(PTD3, PTD2, NC, NC, PTA13); // FRDM KL25Z Serial pc(USBTX, USBRX); DigitalOut led1(LED1), led2(LED2), led3(LED3); AnalogIn ad0(PTB0), ad1(PTB3), ad2(PTC2); @@ -22,8 +22,7 @@ float ref; volatile int count = 0; volatile double sum1 = 0, sum2 = 0; -volatile int busy = 1; -volatile int status = 1; +volatile int busy = 1, status = 1, timeout = 0; extern "C" void HardFault_Handler() { @@ -34,13 +33,12 @@ int xively (char *data) { int i; - Host host; int cid; char buf[128]; + char ip[17]; - host.setName(FEED_HOST); - host.setPort(80); - cid = gs.open(host, GSwifi::GSPROT_TCP); + if (gs.getHostByName(FEED_HOST, ip)) return -1; + cid = gs.open(GSwifi::PROTO_TCP, ip, 80); if (cid < 0) return -1; sprintf(buf, "PUT /v2/feeds/" FEED_ID ".csv HTTP/1.1\r\n"); @@ -68,17 +66,27 @@ } void isr_ticker () { - float a1, a2; + static int w = 0, x = 0; + double a1, a2; - if (status) { - status ++; - if (status & 0x200) { - led1 = ! led1; + w ++; + if (w >= (SAMPLES / 10)) { + if (status) { + led1 = x < 5 ? 0 : 1; + } else { + led1 = 1; + } + + w = 0; + x ++; + if (x >= 10) { + x = 0; + led1 = (timeout & 1) ? 0 : 1; + if (timeout) timeout --; } } if (busy) return; - a1 = ad1 - ref; a2 = ad2 - ref; sum1 += (a1 * a1); @@ -87,37 +95,38 @@ } int main () { - IpAddr ipaddr, netmask, gateway, nameserver; + char ipaddr[17], netmask[17], gateway[17]; Ticker ticker; - Timer timer; int num = 0; char buf[128]; - led1 = led2 = led3 = 1; + led1 = 0; + led2 = led3 = 1; pc.baud(115200); pc.printf("Xively\r\n"); ticker.attach(isr_ticker, 1.0f / SAMPLES); pc.printf("connect\r\n"); NVIC_SetPriority(UART2_IRQn, 1); - if (gs.connect(SECURE, SSID, PASS, 1, 60)) { + gs.setAddress("wattmeter"); + gs.setSsid(SECURE, SSID, PASS); + if (gs.join()) { return -1; } - gs.getAddress(ipaddr, netmask, gateway, nameserver); - pc.printf("ip %d.%d.%d.%d\r\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); + gs.getAddress(ipaddr, netmask, gateway); + pc.printf("ip %s\r\n", ipaddr); ref = ad0; status = 0; busy = 0; - led1 = 0; + timeout = 2; - timer.start(); for (;;) { gs.poll(); - if (timer.read() >= INTERVAL) { - float a1, a2; - float f1, f2; + if (timeout == 0) { + double a1, a2; + double f1, f2; int c; busy = 1; @@ -127,7 +136,7 @@ count = 0; sum1 = 0; sum2 = 0; - timer.reset(); + timeout = INTERVAL; num ++; ref = ad0; if (c) { @@ -146,7 +155,7 @@ led2 = 0; led3 = 1; - sprintf(buf, "L1,%0.3f\r\nL2,%0.3f\r\nUptime,%d\r\n", f1, f2, num); + sprintf(buf, "Total,%0.0f\r\nL1,%0.2f\r\nL2,%0.2f\r\nUptime,%d\r\n", (f1 + f2) * 100, f1, f2, num); if (xively(buf)) led3 = 0; pc.printf("L1=%0.3f, L2=%0.3f, Uptime=%d, ref=%0.2f\r\n", f1, f2, num, ref); led2 = 1;
--- a/mbed.bld Tue Aug 20 04:34:57 2013 +0000 +++ b/mbed.bld Wed Nov 27 08:18:45 2013 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/9c8f0e3462fb \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/f37f3b9c9f0b \ No newline at end of file