see http://mbed.org/users/okini3939/notebook/wattmeter-shield-on-mbed/

Dependencies:   mbed

Fork of GSwifi_xively by gs fan

Revision:
4:9a2415f2ab07
--- /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;
+}
+