GSwifiInterface library (interface for GainSpan Wi-Fi GS1011 modules) Please see https://mbed.org/users/gsfan/notebook/GSwifiInterface/

Dependents:   GSwifiInterface_HelloWorld GSwifiInterface_HelloServo GSwifiInterface_UDPEchoServer GSwifiInterface_UDPEchoClient ... more

Fork of WiflyInterface by mbed official

GainSpan Wi-Fi library

The GS1011/GS2100 is an ultra low power 802.11b wireless module from GainSpan.

mbed RTOS supported.

/media/uploads/gsfan/gs_im_002.jpg /media/uploads/gsfan/gs1011m_2.jpg

ゲインスパン Wi-Fi モジュール ライブラリ

ゲインスパン社の低電力 Wi-Fiモジュール(無線LAN) GS1011/GS2100 シリーズ用のライブラリです。

mbed RTOS に対応しています。(mbed2.0)

GSwifi/GSwifi.cpp

Committer:
gsfan
Date:
2013-10-31
Revision:
8:64184a968e3b
Parent:
5:78943b3945b5
Child:
11:71d67fea5ace

File content as of revision 8:64184a968e3b:

/* Copyright (C) 2012 mbed.org, MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
/* Copyright (C) 2013 gsfan, MIT License
 *  port to the GainSpan Wi-FI module GS1011
 */

#include "mbed.h"
#include "GSwifi.h"
#include <string>
#include <algorithm>

GSwifi * GSwifi::_inst;

GSwifi::GSwifi(PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, PinName alarm, int baud):
    _gs(tx, rx), _reset(reset)
{
    _inst = this;
    memset(&_state, 0, sizeof(_state));
    memset(&_con, 0, sizeof(_con));
    _state.cid = -1;
    _state.acid = -1;
    _state.buf = new CircBuffer<char>(CFG_DATA_SIZE);
#ifdef RTOS_H
    for (int i = 0; i < 16; i ++) {
        _con[i].buf = new CircBuffer<char>(CFG_DATA_SIZE);
    }
    _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(Security sec, const char *ssid, const char *phrase)
{
    bool r = -1;

    _state.wm = WM_INFRASTRUCTURE;
    setSsid(sec, ssid, phrase);
    if (!strlen(_state.name)) {
        strncpy(_state.name, CFG_DHCPNAME, sizeof(_state.name));
    }
    clearFlags();
    sendCommand(NULL, RES_NULL, 0);
    if (cmdE(false)) return -1;
    if (_flow) {
        cmdR(true);
    }
    cmdBDATA(true);
    if (cmdNMAC()) return -1;
    cmdWM(0); // infrastructure
    wait_ms(100);

    switch (sec) {
    case SEC_NONE:
    case SEC_OPEN:
    case SEC_WEP:
        cmdNDHCP(_state.dhcp, _state.name, 0);
        cmdWAUTH(_state.sec);
        if (sec != SEC_NONE) {
            cmdWWEP(1, _state.pass);
            wait_ms(100);
        }
        r = cmdWA(_state.ssid);
        if (r) {
            DBG("retry\r\n");
            wait_ms(1000);
            r = cmdWA(_state.ssid);
        }
        break;
    case SEC_WPA_PSK:
    case SEC_WPA2_PSK:
        cmdNDHCP(_state.dhcp, _state.name, 0);
        cmdWAUTH(0);
        cmdWPAPSK(_state.ssid, _state.pass);
        wait_ms(100);
        r = cmdWA(_state.ssid);
        if (r) {
            DBG("retry\r\n");
            wait_ms(1000);
            r = cmdWA(_state.ssid);
        }
        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) {
        if (! _state.dhcp) {
            cmdDNSSET(_state.nameserver);
        }
        _state.associated = true;
#ifdef RTOS_H
        _threadPoll = new Thread(&threadPoll);
//        _threadPoll = new Thread(&threadPoll, NULL, osPriorityLow);
#endif
    }
    return r;
}

int GSwifi::adhock (Security sec, const char *ssid, const char *phrase)
{
    bool r = -1;

    _state.wm = WM_ADHOCK;
    setSsid(sec, ssid, phrase);
    clearFlags();
    sendCommand(NULL, RES_NULL, 0);
    if (cmdE(false)) return -1;
    if (_flow) {
        cmdR(true);
    }
    if (cmdNMAC()) return -1;
    cmdBDATA(true);
    cmdWM(1); // adhock
    wait_ms(100);

    cmdNDHCP(false);
    if (! _state.dhcp) {
        cmdNSET(_state.ip, _state.netmask, _state.ip);
    }

    switch (sec) {
    case SEC_NONE:
    case SEC_OPEN:
    case SEC_WEP:
        cmdWAUTH(_state.sec);
        if (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) {
        _state.associated = true;
    }
    return r;
}

int GSwifi::limitedap (Security sec, const char *ssid, const char *phrase)
{
    bool r = -1;

    _state.wm = WM_LIMITEDAP;
    setSsid(sec, ssid, phrase);
    if (!strlen(_state.name)) {
        strncpy(_state.name, CFG_DNSNAME, sizeof(_state.name));
    }
    clearFlags();
    sendCommand(NULL, RES_NULL, 0);
    if (cmdE(false)) return -1;
    if (_flow) {
        cmdR(true);
    }
    if (cmdNMAC()) return -1;
    cmdBDATA(true);
    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 (sec) {
    case SEC_NONE:
    case SEC_OPEN:
    case SEC_WEP:
        cmdWAUTH(_state.sec);
        if (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) {
        _state.associated = true;
    }
    return r;
}

int GSwifi::disconnect()
{
    int i;

    // if already disconnected, return
    if (!_state.associated)
        return 0;

#ifdef RTOS_H
    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::isConnected()
{
    return _state.associated;
}

void GSwifi::poll () {
    if (_state.wm == WM_INFRASTRUCTURE && (! isConnected()) && _state.ssid) {
        // Wi-Fi re-associate
        if (!cmdWA(_state.ssid)) {
            _state.associated = true;
        }
    }
}

#ifdef RTOS_H
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->isConnected()){
            _wifi->poll();
            Thread::wait(CFG_TIMEOUT);
        }
    }
}
#endif

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] = '$';
    }
    strncpy(_state.pass, phrase, sizeof(_state.pass));
    for (i = 0; i < strlen(_state.pass); i++) {
        if (_state.pass[i] == ' ')
            _state.pass[i] = '$';
    }
    return 0;
}

int GSwifi::standby (int msec) {
    switch (_state.status) {
    case STAT_READY:
        cmdSTORENWCONN();
        for (int i = 0; i < 16; i ++) {
            _con[i].connected = 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 () {
    if (_state.status == STAT_STANDBY) {
        Timer timeout;
        setAlarm(true);
        timeout.start();
        while (_state.status != STAT_WAKEUP && timeout.read() < CFG_TIMEOUT);
        timeout.stop();
        setAlarm(false);
    }

    switch (_state.status) {
    case STAT_WAKEUP:
        _state.status = STAT_READY;
        if (cmdE(false)) return -1;
        if (_flow) {
            cmdR(true);
        }
        cmdBDATA(true);
        int r = cmdRESTORENWCONN();
        wait_ms(100);
//        return cmdWRXACTIVE(true);
        return r;
    case STAT_DEEPSLEEP:
        _state.status = STAT_READY;
        return cmdAT();
    }
    return -1;
}