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/

Files at this revision

API Documentation at this revision

Comitter:
gsfan
Date:
Thu Nov 08 01:28:45 2012 +0000
Parent:
19:cad912f5a6ba
Child:
21:1270827d431a
Commit message:
suport httpd cgi handler

Changed in this revision

GSwifi.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi.h Show annotated file Show diff for this revision Revisions of this file
GSwifi_httpd.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi_net.h Show annotated file Show diff for this revision Revisions of this file
GSwifi_smtp.cpp Show annotated file Show diff for this revision Revisions of this file
dbg.h Show annotated file Show diff for this revision Revisions of this file
--- a/GSwifi.cpp	Tue Nov 06 08:54:19 2012 +0000
+++ b/GSwifi.cpp	Thu Nov 08 01:28:45 2012 +0000
@@ -496,7 +496,7 @@
     disconnect();
     command("AT+WM=0", GSRES_NORMAL); // infrastructure
     wait_ms(100);
-    if (dhcp) {
+    if (dhcp && sec != GSSEC_WPS_BUTTON) {
         command("AT+NDHCP=1", GSRES_NORMAL);
     } else {
         command("AT+NDHCP=0", GSRES_NORMAL);
@@ -506,7 +506,11 @@
     case GSSEC_NONE:
         command("AT+WAUTH=0", GSRES_NORMAL);
         sprintf(cmd, "AT+WA=%s", ssid);
-        r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
+        r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
+        if (r) {
+            DBG("retry\r\n");
+            r = command(cmd, GSRES_DHCP, GS_TIMEOUT2); // retry
+        }
         break;
     case GSSEC_OPEN:
     case GSSEC_WEP:
@@ -517,6 +521,10 @@
         wait_ms(100);
         sprintf(cmd, "AT+WA=%s", ssid);
         r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
+        if (r) {
+            DBG("retry\r\n");
+            r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
+        }
         break;
     case GSSEC_WPA_PSK:
     case GSSEC_WPA2_PSK:
@@ -528,6 +536,10 @@
         wait_ms(100);
         sprintf(cmd, "AT+WA=%s", ssid);
         r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
+        if (r) {
+            DBG("retry\r\n");
+            r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
+        }
         break;
     case GSSEC_WPS_BUTTON:
         command("AT+WAUTH=0", GSRES_NORMAL);
@@ -602,7 +614,7 @@
     return r;
 }
 
-int GSwifi::limitedap (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask) {
+int GSwifi::limitedap (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask, bool prov) {
     int r;
     char cmd[GS_CMD_SIZE];
     
@@ -625,7 +637,7 @@
     command("AT+NDHCP=0", GSRES_NORMAL);
     setAddress(ipaddr, netmask, ipaddr, ipaddr);
     if (command("AT+DHCPSRVR=1", GSRES_NORMAL)) return -1;
-    if (command("AT+DNS=1,setup", GSRES_NORMAL)) return -1;
+    if (command("AT+DNS=1,setup.local", GSRES_NORMAL)) return -1;
 
     switch (sec) {
     case GSSEC_NONE:
@@ -649,6 +661,10 @@
         break;
     }
 
+    if (r == 0 && prov) {
+        command("AT+WEBPROV=admin,password", GSRES_NORMAL);
+    }
+
     if (r == 0) _connect = true;
     return r;
 }
@@ -903,9 +919,11 @@
                 tmp = strstr(tmp, " ") + 1;
                 _gs_sock[acid].host.setPort(atoi(tmp));
 
+#ifdef GS_USE_HTTPD
                 if (_gs_sock[acid].protocol == GSPROT_HTTPD) {
                     poll_httpd(acid, 0);
                 } else
+#endif
                 if (_gs_sock[acid].onGsReceive != NULL) {
                     _gs_sock[acid].onGsReceive(acid, 0); // event connected
                 }
@@ -916,9 +934,11 @@
             DBG("disconnect %d\r\n", cid);
             _gs_sock[cid].connect = false;
 
+#ifdef GS_USE_HTTPD
             if (_gs_sock[cid].protocol == GSPROT_HTTPD) {
                 poll_httpd(cid, 0);
             } else
+#endif
             if (_gs_sock[cid].onGsReceive != NULL) {
                 _gs_sock[cid].onGsReceive(cid, 0); // event disconnected
             }
@@ -959,12 +979,14 @@
         if (_gs_sock[i].received && _gs_sock[i].data->use()) {
             // recv interrupt
             _gs_sock[i].received = 0;
+#ifdef GS_USE_HTTPD
             if (_gs_sock[i].protocol == GSPROT_HTTPD) {
                 for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) {
                     if (! _gs_sock[i].connect || ! _gs_sock[i].data->use()) break;
                     poll_httpd(i, _gs_sock[i].data->use());
                 }
             } else
+#endif
             if (_gs_sock[i].onGsReceive != NULL) {
                 for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) {
                     if (! _gs_sock[i].connect || ! _gs_sock[i].data->use()) break;
@@ -1055,14 +1077,14 @@
         _gs.printf("\x1bZ%X%04d", cid, len);
         for (i = 0; i < len; i ++) {
             _gs_putc(buf[i]);
-            DBG("%c", buf[i]);
+//            DBG("%c", buf[i]);
         }
 #else
         _gs.printf("\x1bS%X", cid);
         for (i = 0; i < len; i ++) {
             if (buf[i] >= 0x20 && buf[i] < 0x7f) {
                 _gs_putc(buf[i]);
-                DBG("%c", buf[i]);
+//                DBG("%c", buf[i]);
             }
         }
         _gs_putc(0x1b);
@@ -1092,7 +1114,7 @@
         _gs.printf("%04d", len);
         for (i = 0; i < len; i ++) {
             _gs_putc(buf[i]);
-            DBG("%c", buf[i]);
+//            DBG("%c", buf[i]);
         }
 #else
         _gs.printf("\x1bU%X", cid);
@@ -1100,7 +1122,7 @@
         for (i = 0; i < len; i ++) {
             if (buf[i] >= 0x20 && buf[i] < 0x7f) {
                 _gs_putc(buf[i]);
-                DBG("%c", buf[i]);
+//                DBG("%c", buf[i]);
             }
         }
         _gs_putc(0x1b);
@@ -1302,23 +1324,52 @@
     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::urlencode (char *str, char *buf, int len) {
     // code from 
     // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
-    static const char to_hex[] = "0123456789ABCDEF";
-//    char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
+//  char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
     char *pstr = str, *pbuf = buf;
 
     if (len < (strlen(str) * 3 + 1)) return -1;
     while (*pstr) {
-        if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') {
+        if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
             *pbuf++ = *pstr;
-        } else if (*pstr == ' ') {
+        else if (*pstr == ' ') 
             *pbuf++ = '+';
-        } else { 
-            *pbuf++ = '%';
-            *pbuf++ = to_hex[(*pstr >> 4) & 0x0f];
-            *pbuf++ = to_hex[*pstr & 0x0f];
+        else 
+            *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
+        pstr++;
+    }
+    *pbuf = '\0';
+    return 0;
+}
+
+int GSwifi::urldecode (char *str, char *buf, int len) {
+    // code from 
+    // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+//  char *pstr = str, *buf = (char*)malloc(strlen(str) + 1), *pbuf = buf;
+    char *pstr = str, *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++;
     }
--- a/GSwifi.h	Tue Nov 06 08:54:19 2012 +0000
+++ b/GSwifi.h	Thu Nov 08 01:28:45 2012 +0000
@@ -165,7 +165,7 @@
      * @retval -1 failure
      * firmware: s2w-secureweb, s2w-web, s2w-wpsweb
      */
-    int limitedap (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask);
+    int limitedap (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask, bool prov = false);
     /**
      * unassociate
      */
@@ -324,6 +324,7 @@
      */
     int certAdd (const char *name, const char *cert, int len);
 
+#ifdef GS_USE_SMTP
     /**
      * send mail (smtp)
      * @param host SMTP server
@@ -337,7 +338,9 @@
      * @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
     /**
      * start http server
      * @param port
@@ -355,6 +358,7 @@
      * attach uri to cgi handler
      */
     int attach_httpd (const char *uri, onHttpdCgiFunc ponHttpCgi);
+#endif
 
     /**
      * base64 encode
@@ -364,6 +368,10 @@
      * url encode
      */
     int urlencode (char *str, char *buf, int len);
+    /**
+     * url decode
+     */
+    int urldecode (char *str, char *buf, int len);
 
 #ifdef DEBUF
     void test ();
@@ -378,16 +386,19 @@
     char i2x (int i);
     void isr_recv ();
     void newSock (int cid, GSTYPE type, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive);
+    int from_hex (int ch);
+    int to_hex (int code);
 
-    // send mail (smtp)
+#ifdef GS_USE_SMTP
     int wait_smtp (int cid, int code);
+#endif
 
-    // http server
+#ifdef GS_USE_HTTPD
     int httpd_request (int cid, GS_httpd *gshttpd, char *dir);
     char *mimetype (char *file);
+#endif
 
 private:
-    void poll_httpd (int cid, int len);
     Serial _gs;
     bool _rts;
     volatile bool _connect;
@@ -404,9 +415,13 @@
     struct GS_Socket _gs_sock[16];
     time_t _time;
     
+#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);
+#endif
 };
 
 #endif
--- a/GSwifi_httpd.cpp	Tue Nov 06 08:54:19 2012 +0000
+++ b/GSwifi_httpd.cpp	Thu Nov 08 01:28:45 2012 +0000
@@ -2,18 +2,21 @@
 #include "mbed.h"
 #include "GSwifi.h"
 
+#ifdef GS_USE_HTTPD
+
 #define HTTPD_REQUEST 0
 #define HTTPD_HEAD 1
 #define HTTPD_SPACE 2
 #define HTTPD_BODY 3
 #define HTTPD_ERROR 4
 
-#define MIMETABLE_NUM 6
+#define MIMETABLE_NUM 7
 struct {
-    char ext[5];
-    char type[24];
+    char ext[6];
+    char type[20];
 } mimetable[MIMETABLE_NUM] = {
     {".txt", "text/plain"},
+    {".html", "text/html"},
     {".htm", "text/html"},
     {".css", "text/css"},
     {".jpg", "image/jpeg"},
@@ -78,7 +81,7 @@
     if (j >= len) return;
     if (_httpd[cid].len < HTTPD_BUF_SIZE) {
         _httpd[cid].buf[_httpd[cid].len] = 0;
-        DBG("httpd: %d %s (%d)\r\n", _httpd[cid].mode, _httpd[cid].buf, _httpd[cid].len);
+        DBG("httpd %d: %d %s (%d)\r\n", cid, _httpd[cid].mode, _httpd[cid].buf, _httpd[cid].len);
     }
 
     switch (_httpd[cid].mode) {
@@ -116,7 +119,7 @@
             _httpd[cid].mode = HTTPD_BODY;
             if (_httpd[cid].length == 0) flg = 1; // no body
         } else
-        if (strncmp(_httpd[cid].buf, "Content-length: ", 16) == 0) {
+        if (strncmp(_httpd[cid].buf, "Content-Length: ", 16) == 0) {
             _httpd[cid].length = atoi(&_httpd[cid].buf[16]);
         } else
         if (strncmp(_httpd[cid].buf, "Connection: Keep-Alive", 22) == 0) {
@@ -148,7 +151,7 @@
                 _httpd[cid].query = NULL;
                 for (; j < strlen(_httpd[cid].uri); j ++) {
                     if (_httpd[cid].uri[j] == '?') {
-                        // query_string
+                        // query string
                         _httpd[cid].uri[j] = 0;
                         _httpd[cid].query = &_httpd[cid].uri[j + 1];
                         break;
@@ -164,6 +167,8 @@
                     // cgi
                     _handler[i].onHttpCgi(cid, &_httpd[cid]);
                     _httpd[cid].keepalive = 0;
+                    LOG("%d.%d.%d.%d ", _httpd[cid].host.getIp()[0], _httpd[cid].host.getIp()[1], _httpd[cid].host.getIp()[2], _httpd[cid].host.getIp()[3]);
+                    LOG("%s %s %d 200 -\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length);
                     flg = 1;
                 }
                 break;
@@ -194,29 +199,30 @@
 
 int GSwifi::httpd_request (int cid, GS_httpd *gshttpd, char *dir) {
     FILE *fp;
-    int i, j;
-    char buf[100];
+    int i, len;
+    char buf[HTTPD_BUF_SIZE];
+    char file[HTTPD_URI_SIZE];
 
-    strcpy(buf, dir);
-    strcat(buf, gshttpd->file);
-    if (buf[strlen(buf) - 1] == '/') {
-        strcat(buf, "index.htm");
+    strcpy(file, dir);
+    strcat(file, gshttpd->file);
+    if (file[strlen(file) - 1] == '/') {
+        strcat(file, "index.htm");
     }
-    DBG("file: %s\r\n", buf);
+    DBG("file: %s\r\n", file);
     
-    fp = fopen(buf, "r");
+    fp = fopen(file, "r");
     if (fp) {
         send(cid, "HTTP/1.1 200 OK\r\n", 17);
         {
             // file size
-            j = ftell(fp);
+            i = ftell(fp);
             fseek(fp, 0, SEEK_END);
-            i = ftell(fp);
-            fseek(fp, j, SEEK_SET);
+            len = ftell(fp);
+            fseek(fp, i, SEEK_SET);
         }
-        sprintf(buf, "Content-Length: %d\r\n", i);
+        sprintf(buf, "Content-Length: %d\r\n", len);
         send(cid, buf, strlen(buf));
-        sprintf(buf, "Content-Type: %s\r\n", mimetype(gshttpd->file));
+        sprintf(buf, "Content-Type: %s\r\n", mimetype(file));
         send(cid, buf, strlen(buf));
         if (gshttpd->keepalive) {
             strcpy(buf, "Connection: Keep-Alive\r\n");
@@ -230,11 +236,15 @@
 
         for (;;) {
             i = fread(buf, sizeof(char), sizeof(buf), fp);
-            if (i == 0) break;
+            if (i <= 0) break;
             send(cid, buf, i);
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
             if (feof(fp)) break;
+#endif
         }
         fclose(fp);
+        LOG("%d.%d.%d.%d ", _httpd[cid].host.getIp()[0], _httpd[cid].host.getIp()[1], _httpd[cid].host.getIp()[2], _httpd[cid].host.getIp()[3]);
+        LOG("%s %s %d 200 %d\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length, len);
         return 0;
     }
 
@@ -245,6 +255,7 @@
 char *GSwifi::mimetype (char *file) {
     int i, j;
 
+    DBG("<%s>\r\n", file);
     for (i = 0; i < MIMETABLE_NUM; i ++) {
         j = strlen(mimetable[i].ext);
         if (strncmp(&file[strlen(file) - j], mimetable[i].ext, j) == NULL) {
@@ -285,6 +296,8 @@
     sprintf(buf, "<body><h1>%s</h1></body></html>\r\n", msg);
     send(cid, buf, strlen(buf));
     close(cid);
+    LOG("%d.%d.%d.%d ", _httpd[cid].host.getIp()[0], _httpd[cid].host.getIp()[1], _httpd[cid].host.getIp()[2], _httpd[cid].host.getIp()[3]);
+    LOG("%s %s %d %d -\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length, err);
 }
 
 int GSwifi::attach_httpd (const char *uri, const char *dir) {
@@ -313,3 +326,5 @@
         return -1;
     }
 }
+
+#endif
--- a/GSwifi_net.h	Tue Nov 06 08:54:19 2012 +0000
+++ b/GSwifi_net.h	Thu Nov 08 01:28:45 2012 +0000
@@ -16,15 +16,35 @@
 #include "mbed.h"
 #include "host.h"
 
+#define GS_USE_HTTPD  // comment out if not use httpd
+#define GS_USE_SMTP  // comment out if not use smtp
+#define GS_SYSLOG
+
+
+#ifdef GS_SYSLOG
+#define LOG(...) printf("" __VA_ARGS__) 
+#else 
+#define LOG(...) 
+#endif 
+
 // GSwifi_smtp.cpp
+#ifdef GS_USE_SMTP
+
 #define SMTP_TIMEOUT 15000
 
+#endif
+
+
 // GSwifi_httpd.cpp
+#ifdef GS_USE_HTTPD
+
 #define HTTPD_TIMEOUT 15000
 #define HTTPD_HANDLE 10
-#define HTTPD_BUF_SIZE 100
+
+#define HTTPD_BUF_SIZE 200
 #define HTTPD_URI_SIZE 50
-#define HTTPD_KEEPALIVE 5
+
+#define HTTPD_KEEPALIVE 10 // request count
 
 struct GS_httpd {
     int mode;
@@ -48,3 +68,5 @@
 };
 
 #endif
+
+#endif
--- a/GSwifi_smtp.cpp	Tue Nov 06 08:54:19 2012 +0000
+++ b/GSwifi_smtp.cpp	Thu Nov 08 01:28:45 2012 +0000
@@ -2,6 +2,8 @@
 #include "mbed.h"
 #include "GSwifi.h"
 
+#ifdef GS_USE_SMTP
+
 int GSwifi::mail (Host &host, const char *to, const char *from, const char *subject, const char *mesg, const char *user, const char *pwd) {
     int ret = -1;
     int cid;
@@ -72,7 +74,7 @@
 int GSwifi::wait_smtp (int cid, int code) {
     Timer timeout;
     int i, n, len = 0;
-    char buf[500], data[100];
+    char buf[200], data[100];
 
     // wait responce
     timeout.start();
@@ -105,3 +107,5 @@
  
     return -1;
 }
+
+#endif
--- a/dbg.h	Tue Nov 06 08:54:19 2012 +0000
+++ b/dbg.h	Thu Nov 08 01:28:45 2012 +0000
@@ -1,4 +1,4 @@
-//#define DEBUG
+#define DEBUG
 
 #ifdef DEBUG 
 #define DBG(...) printf("" __VA_ARGS__)