GainSpan Wi-Fi library see: http://mbed.org/users/gsfan/notebook/gainspan_wifi/

Dependents:   GSwifi_httpd GSwifi_websocket GSwifi_tcpclient GSwifi_tcpserver ... more

Fork of GSwifi by gs fan

GainSpan Wi-Fi library

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

see: http://mbed.org/users/gsfan/notebook/gainspan_wifi/

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

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

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

解説: http://mbed.org/users/gsfan/notebook/gainspan_wifi/

GSwifi.h

Committer:
gsfan
Date:
2013-02-22
Revision:
28:fbba4c58d14c
Parent:
26:b347ee3a1087
Child:
29:1c4419512941

File content as of revision 28:fbba4c58d14c:

/* 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.
 */
/** @file
 * @brief Gainspan wi-fi module library for mbed
 * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
 */

#ifndef _GSWIFI_H_
#define _GSWIFI_H_

#include "dbg.h"
#include "mbed.h"
#include "CBuffer.h"
#include "GSFunctionPointer.h"
#include "host.h"
#include "ipaddr.h"
#include "GSwifi_conf.h"
#include <ctype.h>


#ifdef GS_UART_DIRECT
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#define _gs_getc() LPC_UART1->RBR
#define _gs_putc(c) while(!(LPC_UART1->LSR & (1<<5))); LPC_UART1->THR = c
#elif defined(TARGET_LPC11U24)
#define _gs_getc() LPC_USART->RBR
#define _gs_putc(c) while(!(LPC_USART->LSR & (1<<5))); LPC_USART->THR = c
#endif
#else
#define _gs_getc() _gs.getc()
#define _gs_putc(c) _gs.putc(c)
#endif

#ifdef GS_SYSLOG
#define LOG(...) printf("" __VA_ARGS__) 
#else 
#define LOG(...) 
#endif 


/**
 * GSwifi class
 */
class GSwifi {
public:

/**
 * Wi-Fi security
 */
enum GSSECURITY {
    GSSEC_AUTO = 0,
    GSSEC_NONE = 0,
    GSSEC_OPEN = 1,
    GSSEC_WEP = 2,
    GSSEC_WPA_PSK = 4,
    GSSEC_WPA2_PSK = 8,
    GSSEC_WPA_ENT = 16,
    GSSEC_WPA2_ENT = 32,
    GSSEC_WPS_BUTTON = 64,
    GSSEC_WPS_PIN,
};

/**
 * TCP/IP protocol
 */
enum GSPROTOCOL {
    GSPROT_UDP = 0,
    GSPROT_TCP = 1,
    GSPROT_HTTPGET,
    GSPROT_HTTPPOST,
    GSPROT_HTTPD,
};

/**
 * Client/Server
 */
enum GSTYPE {
    GSTYPE_CLIENT = 0,
    GSTYPE_SERVER = 1,
};

enum GSRESPONCE {
    GSRES_NONE,
    GSRES_NORMAL,
    GSRES_CONNECT,
    GSRES_WPS,
    GSRES_MACADDRESS,
    GSRES_DHCP,
    GSRES_DNSLOOKUP,
    GSRES_HTTP,
    GSRES_RSSI,
    GSRES_TIME,
};

enum GSMODE {
    GSMODE_COMMAND,
    GSMODE_DATA_RX,
    GSMODE_DATA_RXUDP,
    GSMODE_DATA_RX_BULK,
    GSMODE_DATA_RXUDP_BULK,
    GSMODE_DATA_RXHTTP,
};

enum GSSTATUS {
    GSSTAT_READY,
    GSSTAT_STANDBY,
    GSSTAT_WAKEUP,
    GSSTAT_DEEPSLEEP,
};

/**
 * data receive callback function
 */
typedef void (*onGsReceiveFunc)(int cid, int len);

struct GS_Socket {
    GSTYPE type;
    GSPROTOCOL protocol;
    bool connect;
    Host host;
    CircBuffer<char> *data;
    int lcid;
    bool received;
//    onGsReceiveFunc onGsReceive;
    GSFunctionPointer onGsReceive;
};

#ifdef GS_USE_HTTPD
enum GSHTTPDMODE {
    GSHTTPDMODE_REQUEST,
    GSHTTPDMODE_HEAD,
    GSHTTPDMODE_SPACE,
    GSHTTPDMODE_BODY,
    GSHTTPDMODE_ERROR,
    GSHTTPDMODE_WEBSOCKET,
    GSHTTPDMODE_WEBSOCKET_MASK,
    GSHTTPDMODE_WEBSOCKET_BODY,
};

struct GS_httpd {
    GSHTTPDMODE mode;
    int type;
    char *buf;  // body
    int len;  // length of buf
    char *uri;
    char *file;
    char *query;
    int length;  // content-length
    int keepalive;
    Host host;
#ifdef GS_USE_WEBSOCKET
    int websocket;
    char *websocket_key;
    int websocket_flg;
    char websocket_mask[4];
    int websocket_payload;
#endif
};

typedef void (*onHttpdCgiFunc)(int cid, GS_httpd *gshttpd);

struct GS_httpd_handler {
    char *uri;
    char *dir;
    onHttpdCgiFunc onHttpCgi;
};
#endif // GS_USE_HTTPD

    // ----- GSwifi.cpp -----
    /**
     * default constructor
     */
    GSwifi (PinName p_tx, PinName p_rx, PinName p_reset, PinName p_alarm = NC, int baud = GS_BAUD);
    /**
     * Default constructor (with hardware fllow controll)
     */
    GSwifi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts, PinName p_reset, PinName p_alarm = NC, int baud = GS_BAUD);
    /**
     * reset module
     */
    void reset ();
    /**
     * send command
     */
    int command (const char *cmd, GSRESPONCE res, int timeout = GS_TIMEOUT);
    /**
     * reset recv responce
     */
    void resetResponse (GSRESPONCE res);
    /**
     * wait recv responce
     */
    int waitResponse (int ms);
    /**
     * associate infrastructure
     * @param sec GSSEC_OPEN, GSSEC_WEP, GSSEC_WPA_PSK, GSSEC_WPA2_PSK, GSSEC_WPS_BUTTON
     * @param ssid SSID
     * @param pass pass phrase
     * @param dhcp 0:static ip, 1:dhcp
     * @param reconnect auto re-connect
     * @retval 0 success
     * @retval -1 failure
     */
    int connect (GSSECURITY sec, const char *ssid, const char *pass, int dhcp = 1, int reconnect = 0);
    /**
     * adhock
     * @param sec GSSEC_OPEN or GSSEC_WEP
     * @param ssid SSID
     * @param pass 10 or 26 hexadecimal digits
     * @param ipaddr my ip address
     * @param netmask subnet mask
     * @retval 0 success
     * @retval -1 failure
     */
    int adhock (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask);
    /**
     * limited AP
     * @param sec GSSEC_OPEN or GSSEC_WEP
     * @param ssid SSID
     * @param pass 10 or 26 hexadecimal digits
     * @param ipaddr my ip address (dhcp start address)
     * @param netmask subnet mask
     * @retval 0 success
     * @retval -1 failure
     * firmware: s2w-secureweb, s2w-web, s2w-wpsweb
     */
    int limitedap (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask, char *dns = NULL);
    /**
     * unassociate
     */
    int disconnect ();
    /**
     * re-connect
     */
    int reconnect ();

    /**
     * use DHCP
     */
    int setAddress ();
    /**
     * use static ip address
     */
    int setAddress (IpAddr ipaddr, IpAddr netmask, IpAddr gateway, IpAddr nameserver);
    /**
     * get ip address
     */
    int getAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver);
    /**
     * get mac address
     */
    int getMac (char *mac);
    /**
     * resolv hostname
     * @param name hostname
     * @param addr resolved ip address
     */
    int getHostByName (const char* name, IpAddr &addr);
    /**
     * resolv hostname
     * @param host.name hostname
     * @param host.ipaddr resolved ip address
     */
    int getHostByName (Host &host);
    /**
     * RF power
     * @param power 0(high)-7(low)
     */
    int setRFPower (int power);
    /**
     * 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);
    /**
     * standby mode
     * @param msec wakeup after
     * wakeup after msec or alarm1/2
     * core off, save to RTC ram
     */
    int standby (int msec);
    /**
     * restore standby
     */
    int wakeup ();
    /**
     * deep sleep mode
     */
    int deepSleep ();
    /**
     * wifi connected
     */
    bool isConnected ();
    /**
     * status
     * @return GSSTATUS
     */
    GSSTATUS getStatus ();
    /**
     * RSSI
     * @return RSSI (dBm)
     */
    int getRssi ();
    /**
     * set NTP server
     * @param host SNTP server
     * @param sec time sync interval, 0:one time
     */
    int ntpdate (Host host, int sec = 0);
    /**
     * set system time
     * @param time date time (UTC)
     */
    int setTime (time_t time);
    /**
     * get RTC time
     * @return date time (UTC)
     */
    time_t getTime ();
    /**
     * GPIO output
     * @param port 10,11,30,31
     * @param out 0:set(high), 1:reset(low)
     */
    int gpioOut (int port, int out);
    /**
     * main polling
     */
    void poll();
    /**
     * Web server
     */
    int provisioning (char *user, char *pass);
    /**
     * change baud rate
     */
    int setBaud (int baud);
    /**
     * change radio region
     */
    int setRegion (int reg = GS_WREGDOMAIN);
    /**
     * certificate 
     */
    int certAdd (const char *name, const char *cert, int len);

// ----- GSwifi_sock.cpp -----
    /**
     * tcp/udp client
     * @return CID, -1:failure
     */
    int open (Host &host, GSPROTOCOL pro);

    int open (Host &host, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
        int cid = open(host, pro);
        if (cid >= 0) _gs_sock[cid].onGsReceive.attach(ponGsReceive);
        return cid;
    }
    template<typename T>
    int open (Host &host, GSPROTOCOL pro, T *object, void (T::*member)(int, int)) {
        int cid = open(host, pro);
        if (cid >= 0) _gs_sock[cid].onGsReceive.attach(object, member);
        return cid;
    }
    /**
     * tcp/udp server
     * @return CID, -1:failure
     */
    int listen (int port, GSPROTOCOL pro);

    int listen (int port, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
        int cid = listen(port, pro);
        if (cid >= 0) _gs_sock[cid].onGsReceive.attach(ponGsReceive);
        return cid;
    }
    template<typename T>
    int listen (int port, GSPROTOCOL pro, T *object, void (T::*member)(int, int)) {
        int cid = listen(port, pro);
        if (cid >= 0) _gs_sock[cid].onGsReceive.attach(object, member);
        return cid;
    }
    /**
     * 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 send (int cid, const char *buf, int len, Host &host);
    /**
     * recv data tcp(s/c), udp(c)
     * @return length
     */
    int recv (int cid, char *buf, int len);
    /**
     * recv data udp(s)
     * @return length
     */
    int recv (int cid, char *buf, int len, Host &host);
    /**
     * tcp/udp connected
     */
    bool isConnected (int cid);

// ----- GSwifi_http.cpp -----
    /**
     * http request (GET method)
     */
    int httpGet (Host &host, const char *uri, const char *user, const char *pwd, int ssl = 0, onGsReceiveFunc ponGsReceive = NULL);
    int httpGet (Host &host, const char *uri, int ssl = 0, onGsReceiveFunc ponGsReceive = NULL);
    /**
     * http request (POST method)
     */
    int httpPost (Host &host, const char *uri, const char *body, const char *user, const char *pwd, int ssl = 0, onGsReceiveFunc ponGsReceive = NULL);
    int httpPost (Host &host, const char *uri, const char *body, int ssl = 0, onGsReceiveFunc ponGsReceive = NULL);

    /**
     * base64 encode
     */
    int base64encode (char *input, int length, char *output, int len);
    /**
     * url encode
     */
    int urlencode (char *str, char *buf, int len);
    /**
     * url decode
     */
    int urldecode (char *str, char *buf, int len);

#ifdef GS_USE_SMTP
// ----- GSwifi_smtp.cpp -----
    /**
     * send mail (smtp)
     * @param host SMTP server
     * @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 (Host &host, const char *to, const char *from, const char *subject, const char *mesg, const char *user = NULL, const char *pwd = NULL);
#endif

#ifdef GS_USE_HTTPD
// ----- GSwifi_httpd.cpp -----
    /**
     * start http server
     * @param port
     */
    int httpd (int port = 80);
    /**
     * attach uri to dirctory handler
     */
    void send_httpd_error (int cid, int err);
    /**
     * attach uri to dirctory handler
     */
    int attach_httpd (const char *uri, const char *dir);
    /**
     * attach uri to cgi handler
     */
    int attach_httpd (const char *uri, onHttpdCgiFunc ponHttpCgi);
#ifdef GS_USE_WEBSOCKET
    int send_websocket (int cid, const char *buf, int len);
#endif
#endif

#ifdef DEBUG
    void dump ();
    void test ();
    int getc();
    void putc(char c);
    int readable();
#endif

protected:
    void parseResponse ();
    void parseCmdResponse (char *buf);

    int x2i (char c);
    char i2x (int i);
    void isr_recv ();
    int from_hex (int ch);
    int to_hex (int code);

    void newSock (int cid, GSTYPE type, GSPROTOCOL pro);

    void newSock (int cid, GSTYPE type, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
        newSock(cid, type, pro);
        _gs_sock[cid].onGsReceive.attach(ponGsReceive);
    }
    template<typename T>
    void newSock (int cid, GSTYPE type, GSPROTOCOL pro, T *object, void (T::*member)(int, int)) {
        newSock(cid, type, pro);
        _gs_sock[cid].onGsReceive.attach(object, member);
    }

#ifdef GS_USE_SMTP
    int wait_smtp (int cid, int code);
#endif

#ifdef GS_USE_HTTPD
    int get_handler (char *uri);
    int httpd_request (int cid, GS_httpd *gshttpd, char *dir);
    char *mimetype (char *file);
    int strnicmp (char *p1, char *p2, int n);
#endif

private:
    Serial _gs;
    bool _rts;
    DigitalInOut _reset;
    DigitalInOut *_alarm;
    volatile bool _connect;
    volatile GSSTATUS _status;
    volatile bool _gs_ok, _gs_failure;
    volatile int _gs_flg;
    volatile GSRESPONCE _gs_res;
    GSMODE _gs_mode;
    bool _escape;
    int _cid, _rssi;
    IpAddr _ipaddr, _netmask, _gateway, _nameserver, _resolv;
    Host _from, _to;
    char _mac[6];
    CircBuffer<char> _buf_cmd;
    struct GS_Socket _gs_sock[16];
    time_t _time;
    GSSECURITY _sec;
    char *_ssid, *_pass;
    int _reconnect, _reconnect_count;
    
#ifdef GS_USE_HTTPD
    struct GS_httpd _httpd[16];
    struct GS_httpd_handler _handler[10];
    int _handler_count;

    void poll_httpd (int cid, int len);
#ifdef GS_USE_WEBSOCKET
    void poll_websocket (int cid, int len);
    void send_websocket_accept (int cid);
#endif
#endif
};

#endif