Kazushi Mukaiyama / GSwifi

Fork of GSwifi_old by gs fan

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GSwifi.cpp Source File

GSwifi.cpp

Go to the documentation of this file.
00001 /**
00002  * Gainspan wi-fi module library for mbed
00003  * Copyright (c) 2012 gsfan
00004  * Released under the MIT License: http://mbed.org/license/mit
00005  */
00006 
00007 /** @file
00008  * @brief Gainspan wi-fi module library for mbed
00009  * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
00010  * module configuration: ATB=115200
00011  */
00012 
00013 #include "dbg.h"
00014 #include "mbed.h"
00015 #include "GSwifi.h"
00016 #include <ctype.h>
00017 
00018 
00019 GSwifi::GSwifi (PinName p_tx, PinName p_rx, int baud) : _gs(p_tx, p_rx), _buf_cmd(GS_CMD_SIZE) {
00020     _connect = false;
00021     _status = GSSTAT_READY;
00022     _escape = 0;
00023     _response = GSRES_NONE;
00024     _gs_mode = GSMODE_COMMAND;
00025     _ssid = NULL;
00026     _reconnect = 0;
00027     _reconnect_count = 0;
00028 
00029     _gs.baud(baud);
00030     _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
00031     _rts = false;
00032 }
00033 
00034 GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts, int baud) : _gs(p_tx, p_rx), _buf_cmd(GS_CMD_SIZE) {
00035     _connect = false;
00036     _status = GSSTAT_READY;
00037     _escape = 0;
00038     _response = GSRES_NONE;
00039     _gs_mode = GSMODE_COMMAND;
00040     _ssid = NULL;
00041     _reconnect = 0;
00042     _reconnect_count = 0;
00043 
00044     _gs.baud(baud);
00045     _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
00046 
00047 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00048     if (p_cts == p12) { // CTS input (P0_17)
00049         LPC_UART1->MCR |= (1<<7); // CTSEN
00050         LPC_PINCON->PINSEL1 &= ~(3 << 2);
00051         LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS
00052     }
00053     if (p_rts == P0_22) { // RTS output (P0_22)
00054         LPC_UART1->MCR |= (1<<6); // RTSEN
00055         LPC_PINCON->PINSEL1 &= ~(3 << 12);
00056         LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS
00057         _rts = true;
00058     } else {
00059         _rts = false;
00060     }
00061 #elif defined(TARGET_LPC11U24)
00062     if (p_cts == p21) { // CTS input (P0_7)
00063         LPC_USART->MCR |= (1<<7); // CTSEN
00064         LPC_IOCON->PIO0_7 &= ~0x07;
00065         LPC_IOCON->PIO0_7 |= 0x01; // UART CTS
00066     }
00067     if (p_rts == p22) { // RTS output (P0_17)
00068         LPC_USART->MCR |= (1<<6); // RTSEN
00069         LPC_IOCON->PIO0_17 &= ~0x07;
00070         LPC_IOCON->PIO0_17 |= 0x01; // UART RTS
00071         _rts = true;
00072     } else {
00073         _rts = false;
00074     }
00075 #endif
00076 }
00077 
00078 // uart interrupt
00079 void GSwifi::isr_recv () {
00080     static int len, mode;
00081     static char tmp[20];
00082     char flg, dat;
00083     
00084 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00085     flg = LPC_UART1->LSR;
00086 #elif defined(TARGET_LPC11U24)
00087     flg = LPC_USART->LSR;
00088 #endif
00089     dat = _gs_getc();
00090     
00091     if (flg & ((1 << 7)|(1 << 3)|(1 << 4))) return;
00092 #ifdef DEBUG_VIEW
00093 //    DBG("%02x_", dat);
00094 #endif
00095 /*
00096     if (dat >= 0x20 && dat < 0x7f) {
00097         DBG("_%c", dat);
00098     } else {
00099         DBG("_%02x", dat);
00100     }
00101 */
00102     switch (_gs_mode) {
00103     case GSMODE_COMMAND: // command responce
00104         if (_escape) {
00105             // esc
00106             switch (dat) {
00107             case 'O':
00108                 DBG("ok\r\n");
00109                 _gs_ok = 1;
00110                 break;
00111             case 'F':
00112                 DBG("failure\r\n");
00113                 _gs_failure = 1;
00114                 break;
00115             case 'S':
00116                 DBG("GSMODE_DATA_RX\r\n");
00117                 _gs_mode = GSMODE_DATA_RX;
00118                 mode = 0;
00119                 break;
00120             case 'u':
00121                 DBG("GSMODE_DATA_RXUDP\r\n");
00122                 _gs_mode = GSMODE_DATA_RXUDP;
00123                 mode = 0;
00124                 break;
00125             case 'Z':
00126             case 'H':
00127                 DBG("GSMODE_DATA_RX_BULK\r\n");
00128                 _gs_mode = GSMODE_DATA_RX_BULK;
00129                 mode = 0;
00130                 break;
00131             case 'y':
00132                 DBG("GSMODE_DATA_RXUDP_BULK\r\n");
00133                 _gs_mode = GSMODE_DATA_RXUDP_BULK;
00134                 mode = 0;
00135                 break;
00136             default:
00137                 DBG("unknown [ESC] %02x\r\n", dat);
00138                 break;
00139             }
00140             _escape = 0;
00141         } else {
00142             if (dat == 0x1b) {
00143                 _escape = 1;
00144             } else
00145             if (dat != '\r') {
00146                 // command
00147                 _buf_cmd.put(dat);
00148                 if (dat == '\n') {
00149                     _gs_enter ++;
00150                     if (_response == GSRES_NONE && _connect) {
00151                         DBG("poll_cmd\r\n");
00152                         poll_cmd();
00153                     }
00154                 }
00155             }
00156         }
00157         break;
00158 
00159     case GSMODE_DATA_RX:
00160     case GSMODE_DATA_RXUDP:
00161         if (mode == 0) {
00162             // cid
00163             _cid = x2i(dat);
00164             _gs_sock[_cid].received = 0;
00165             mode ++;
00166             if (_gs_mode == GSMODE_DATA_RX) {
00167                 mode = 3;
00168             }
00169             len = 0;
00170         } else
00171         if (mode == 1) {
00172             // ip
00173             if ((dat < '0' || dat > '9') && dat != '.') {
00174                 int ip1, ip2, ip3, ip4;
00175                 tmp[len] = 0;
00176                 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00177                 _from.setIp(IpAddr(ip1, ip2, ip3, ip4));
00178                 mode ++;
00179                 len = 0;
00180                 break;
00181             }
00182             tmp[len] = dat;    
00183             len ++;        
00184         } else
00185         if (mode == 2) {
00186             // port
00187             if (dat < '0' || dat > '9') {
00188                 tmp[len] = 0;
00189                 _from.setPort(atoi(tmp));
00190                 mode ++;
00191                 len = 0;
00192                 break;
00193             }
00194             tmp[len] = dat;            
00195             len ++;        
00196         } else
00197         if (_escape) {
00198             // esc
00199             switch (dat) {
00200             case 'E':
00201                 DBG("recv ascii %d\r\n", _cid);
00202                 _gs_sock[_cid].received = 1;
00203                 _gs_mode = GSMODE_COMMAND;
00204                 // recv interrupt
00205                 if (_gs_sock[_cid].protocol == GSPROT_HTTPGET && _gs_sock[_cid].onGsReceive != NULL) {
00206                     _gs_sock[_cid].onGsReceive(_cid, _gs_sock[_cid].data->use());
00207                     _gs_sock[_cid].received = 0;
00208                 }
00209                 break;
00210             default:
00211                 DBG("unknown <ESC> %02x\r\n", dat);
00212                 break;
00213             }
00214             _escape = 0;
00215         } else {
00216             if (dat == 0x1b) {
00217                 _escape = 1;
00218             } else {
00219                 // data
00220                 _gs_sock[_cid].data->put(dat);
00221                 len ++;
00222                 if (len < GS_DATA_SIZE && _gs_sock[_cid].data->available() == 0) {
00223                     // buffer full
00224                     if (_gs_sock[_cid].onGsReceive != NULL) {
00225                         _gs_sock[_cid].onGsReceive(_cid, _gs_sock[_cid].data->use());
00226                     }
00227                 }
00228             }
00229         }
00230         break;
00231 
00232     case GSMODE_DATA_RX_BULK:
00233     case GSMODE_DATA_RXUDP_BULK:
00234 //        DBG("%c", dat);
00235         if (mode == 0) {
00236             // cid
00237             _cid = x2i(dat);
00238             _gs_sock[_cid].received = 0;
00239             mode ++;
00240             if (_gs_mode == GSMODE_DATA_RX_BULK) {
00241                 mode = 3;
00242             }
00243             len = 0;
00244         } else
00245         if (mode == 1) {
00246             // ip
00247             if ((dat < '0' || dat > '9') && dat != '.') {
00248                 int ip1, ip2, ip3, ip4;
00249                 tmp[len] = 0;
00250                 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00251                 _from.setIp(IpAddr(ip1, ip2, ip3, ip4));
00252                 mode ++;
00253                 len = 0;
00254                 break;
00255             }
00256             tmp[len] = dat;    
00257             len ++;        
00258         } else
00259         if (mode == 2) {
00260             // port
00261             if (dat < '0' || dat > '9') {
00262                 tmp[len] = 0;
00263                 _from.setPort(atoi(tmp));
00264                 mode ++;
00265                 len = 0;
00266                 break;
00267             }
00268             tmp[len] = dat;            
00269             len ++;        
00270         } else
00271         if (mode == 3) {
00272             // length
00273             tmp[len] = dat;            
00274             len ++;        
00275             if (len >= 4) {
00276                 tmp[len] = 0;
00277                 len = atoi(tmp);
00278                 mode ++;
00279                 break;
00280             }
00281         } else
00282         if (mode == 4) {
00283             // data
00284             if (_gs_sock[_cid].data != NULL) {
00285                 _gs_sock[_cid].data->put(dat);
00286             }
00287             len  --;
00288             if (len && _gs_sock[_cid].data->available() == 0) {
00289                 // buffer full
00290                 if (_gs_sock[_cid].onGsReceive != NULL) {
00291                     _gs_sock[_cid].onGsReceive(_cid, _gs_sock[_cid].data->use());
00292                 }
00293             }
00294             if (len == 0) {
00295                 DBG("recv binary %d\r\n", _cid);
00296                 _gs_sock[_cid].received = 1;
00297                 _escape = 0;
00298                 _gs_mode = GSMODE_COMMAND;
00299                 // recv interrupt
00300                 if (_gs_sock[_cid].protocol == GSPROT_HTTPGET && _gs_sock[_cid].onGsReceive != NULL) {
00301                     _gs_sock[_cid].onGsReceive(_cid, _gs_sock[_cid].data->use());
00302                     _gs_sock[_cid].received = 0;
00303                 }
00304             }
00305         }
00306         break;
00307 
00308     }
00309 }
00310 
00311 int GSwifi::command (const char *cmd, GSRESPONCE res, int timeout) {
00312     int i, r = 0;
00313 
00314     if (! cmd) {
00315         // dummy CR+LF
00316         _gs.printf("\r\n");
00317         for (i = 0; i < 10; i ++) {
00318             wait_ms(10);
00319             poll_cmd();
00320             _buf_cmd.clear();
00321         }
00322         return 0;
00323     }
00324 
00325     _response = res;
00326     _buf_cmd.clear();
00327     _gs_ok = 0;
00328     _gs_failure = 0;
00329     _gs_enter = 0;
00330     for (i = 0; i < strlen(cmd); i ++) {
00331         _gs_putc(cmd[i]);
00332     }
00333     _gs_putc('\r');
00334     _gs_putc('\n');
00335     DBG("command: %s\r\n", cmd);
00336     if (strlen(cmd) == 0) return 0;
00337 //    wait_ms(10);
00338     if (timeout) {
00339         r = cmdResponse(res, timeout);
00340     }
00341     _response = GSRES_NONE;
00342     return r;
00343 }
00344 
00345 int GSwifi::cmdResponse (GSRESPONCE res, int ms) {
00346     int i, n = 0, flg = 0;
00347     char buf[GS_CMD_SIZE];
00348     Timer timeout;
00349 
00350     timeout.start();
00351     for (;;) {
00352         // recv response
00353         i = 0;
00354         while (i < sizeof(buf)) {
00355             if (_buf_cmd.use()) {
00356                 _buf_cmd.get(&buf[i]);
00357                 if (buf[i] == '\n') {
00358                     break;
00359                 }
00360                 i ++;
00361             }
00362             if (timeout.read_ms() > ms) {
00363                 timeout.stop();
00364                 DBG("timeout\r\n");
00365                 return -1;
00366             }
00367         }
00368         _gs_enter = 0;
00369         if (i == 0) continue;
00370         buf[i] = 0;
00371         DBG("response: %s\r\n", buf);
00372         timeout.stop();
00373 
00374         if (strcmp(buf, "OK") == 0) {
00375             _gs_ok = 1;
00376         } else
00377         if (strncmp(buf, "ERROR", 5) == 0) {
00378             _gs_failure = 1;
00379         }
00380 
00381         switch(res) {
00382         case GSRES_NORMAL:
00383             flg = 1;
00384             break;
00385         case GSRES_WPS:
00386             if (n == 0 && strncmp(buf, "SSID", 4) == 0) {
00387                 n ++;
00388             } else
00389             if (n == 1 && strncmp(buf, "CHANNEL", 7) == 0) {
00390                 n ++;
00391             } else
00392             if (n == 2 && strncmp(buf, "PASSPHRASE", 10) == 0) {
00393                 n ++;
00394                 flg = 1;
00395             }
00396             break;
00397         case GSRES_CONNECT:
00398             if (strncmp(buf, "CONNECT ", 8) == 0) {
00399                 _cid = x2i(buf[8]);
00400                 flg = 1;
00401             }
00402             break;
00403         case GSRES_DHCP:
00404             if (n == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) {
00405                 n ++;
00406             } else
00407             if (n == 1) {
00408                 int ip1, ip2, ip3, ip4;
00409                 char *tmp = buf + 1;
00410                 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00411                 _ipaddr = IpAddr(ip1, ip2, ip3, ip4);
00412                 tmp = strstr(tmp, ":") + 2;
00413                 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00414                 _netmask = IpAddr(ip1, ip2, ip3, ip4);
00415                 tmp = strstr(tmp, ":") + 2;
00416                 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00417                 _gateway = IpAddr(ip1, ip2, ip3, ip4);
00418                 n ++;
00419                 flg = 1;
00420             }
00421             break;
00422         case GSRES_MACADDRESS:
00423             if (buf[2] == ':' && buf[5] == ':') {
00424                 int mac1, mac2, mac3, mac4, mac5, mac6;
00425                 sscanf(buf, "%x:%x:%x:%x:%x:%x", &mac1, &mac2, &mac3, &mac4, &mac5, &mac6);
00426                 _mac[0] = mac1;
00427                 _mac[1] = mac2;
00428                 _mac[2] = mac3;
00429                 _mac[3] = mac4;
00430                 _mac[4] = mac5;
00431                 _mac[5] = mac6;
00432                 flg = 1;
00433             }
00434             break;
00435         case GSRES_DNSLOOKUP:
00436             if (strncmp(buf, "IP:", 3) == 0) {
00437                 int ip1, ip2, ip3, ip4;
00438                 sscanf(&buf[3], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00439                 _resolv = IpAddr(ip1, ip2, ip3, ip4);
00440                 flg = 1;
00441             }
00442             break;
00443         case GSRES_HTTP:
00444             if (buf[0] >= '0' && buf[0] <= 'F') {
00445                 _cid = x2i(buf[0]);
00446                 flg = 1;
00447             }
00448             break;
00449         case GSRES_RSSI:
00450             if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) {
00451                 _rssi = atoi(buf);
00452                 flg = 1;
00453             }
00454             break;
00455         case GSRES_TIME:
00456             if (buf[0] >= '0' && buf[0] <= '9') {
00457                 int year, month, day, hour, min, sec;
00458                 struct tm t;
00459                 sscanf(buf, "%d/%d/%d,%d:%d:%d", &day, &month, &year, &hour, &min, &sec);
00460                 t.tm_sec = sec;
00461                 t.tm_min = min;
00462                 t.tm_hour = hour;
00463                 t.tm_mday = day;
00464                 t.tm_mon = month - 1;
00465                 t.tm_year = year - 1900;   
00466                 _time = mktime(&t);            
00467                 flg = 1;
00468             }
00469             break;
00470         }
00471         
00472         if ((flg && _gs_ok) || _gs_failure) break;
00473         timeout.reset();
00474         timeout.start();
00475     }
00476 
00477     if (_gs_failure || flg == 0) {
00478         return -1;
00479     } else {
00480         return 0;
00481     }
00482 }
00483 
00484 int GSwifi::connect (GSSECURITY sec, const char *ssid, const char *pass, int dhcp, int reconnect) {
00485     int r;
00486     char cmd[GS_CMD_SIZE];
00487     
00488     if (_connect || _status != GSSTAT_READY) return -1;
00489 
00490     command(NULL, GSRES_NORMAL);
00491     if (command("ATE0", GSRES_NORMAL)) return -1;
00492     if (_rts) {
00493         command("AT&K0", GSRES_NORMAL);
00494         command("AT&R1", GSRES_NORMAL);
00495     }
00496     command("AT+NMAC=?", GSRES_MACADDRESS);
00497 #ifdef GS_BULK
00498     command("AT+BDATA=1", GSRES_NORMAL);
00499 #endif
00500 
00501     disconnect();
00502     command("AT+WREGDOMAIN=" GS_WREGDOMAIN, GSRES_NORMAL);
00503     command("AT+WM=0", GSRES_NORMAL); // infrastructure
00504     wait_ms(100);
00505     if (dhcp && sec != GSSEC_WPS_BUTTON) {
00506         command("AT+NDHCP=1", GSRES_NORMAL);
00507     } else {
00508         command("AT+NDHCP=0", GSRES_NORMAL);
00509     }
00510 
00511     switch (sec) {
00512     case GSSEC_NONE:
00513     case GSSEC_OPEN:
00514     case GSSEC_WEP:
00515         sprintf(cmd, "AT+WAUTH=%d", sec);
00516         command(cmd, GSRES_NORMAL);
00517         if (sec != GSSEC_NONE) {
00518             sprintf(cmd, "AT+WWEP1=%s", pass);
00519             command(cmd, GSRES_NORMAL);
00520             wait_ms(100);
00521         }
00522         sprintf(cmd, "AT+WA=%s", ssid);
00523         r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
00524         if (r) {
00525             DBG("retry\r\n");
00526             r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
00527         }
00528         break;
00529     case GSSEC_WPA_PSK:
00530     case GSSEC_WPA2_PSK:
00531         command("AT+WAUTH=0", GSRES_NORMAL);
00532 //        sprintf(cmd, "AT+WWPA=%s", pass);
00533 //        command(cmd, GSRES_NORMAL);
00534         sprintf(cmd, "AT+WPAPSK=%s,%s", ssid, pass);
00535         command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
00536         wait_ms(100);
00537         sprintf(cmd, "AT+WA=%s", ssid);
00538         r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
00539         if (r) {
00540             DBG("retry\r\n");
00541             r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
00542         }
00543         break;
00544     case GSSEC_WPS_BUTTON:
00545         command("AT+WAUTH=0", GSRES_NORMAL);
00546         r = command("AT+WWPS=1", GSRES_WPS, GS_TIMEOUT2);
00547         if (r) break;
00548         if (dhcp) {
00549             r = command("AT+NDHCP=1", GSRES_DHCP, GS_TIMEOUT2);
00550         }
00551         break;
00552     default:
00553         DBG("Can't use security\r\n");
00554         r = -1;
00555         break;
00556     }
00557 
00558     if (r == 0 && !dhcp) {
00559         sprintf(cmd, "AT+DNSSET=%d.%d.%d.%d",
00560             _gateway[0], _gateway[1], _gateway[2], _gateway[3]);
00561         command(cmd, GSRES_NORMAL);
00562     }
00563 
00564     if (r == 0) {
00565         _connect = true;
00566         _reconnect = reconnect;
00567         _reconnect_count = 0;
00568         if (!_ssid) _ssid = new char[sizeof(ssid) + 1];
00569         strcpy(_ssid, ssid);
00570     }
00571     return r;
00572 }
00573 
00574 int GSwifi::adhock (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask) {
00575     int r;
00576     char cmd[GS_CMD_SIZE];
00577 
00578     if (_connect || _status != GSSTAT_READY) return -1;
00579 
00580     command(NULL, GSRES_NORMAL);
00581     if (command("ATE0", GSRES_NORMAL)) return -1;
00582     if (_rts) {
00583         command("AT&K0", GSRES_NORMAL);
00584         command("AT&R1", GSRES_NORMAL);
00585     }
00586     disconnect();
00587     command("AT+NMAC=?", GSRES_MACADDRESS);
00588 #ifdef GS_BULK
00589     command("AT+BDATA=1", GSRES_NORMAL);
00590 #endif
00591 
00592     command("AT+WREGDOMAIN=" GS_WREGDOMAIN, GSRES_NORMAL);
00593     command("AT+WM=1", GSRES_NORMAL); // adhock
00594     wait_ms(100);
00595     command("AT+NDHCP=0", GSRES_NORMAL);
00596     setAddress(ipaddr, netmask, ipaddr, ipaddr);
00597 
00598     switch (sec) {
00599     case GSSEC_NONE:
00600     case GSSEC_OPEN:
00601     case GSSEC_WEP:
00602         sprintf(cmd, "AT+WAUTH=%d", sec);
00603         command(cmd, GSRES_NORMAL);
00604         if (sec != GSSEC_NONE) {
00605             sprintf(cmd, "AT+WWEP1=%s", pass);
00606             command(cmd, GSRES_NORMAL);
00607             wait_ms(100);
00608         }
00609         sprintf(cmd, "AT+WA=%s", ssid);
00610         r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
00611         break;
00612     default:
00613         DBG("Can't use security\r\n");
00614         r = -1;
00615         break;
00616     }
00617 
00618     if (r == 0) _connect = true;
00619     return r;
00620 }
00621 
00622 int GSwifi::limitedap (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask, char *dns) {
00623     int r;
00624     char cmd[GS_CMD_SIZE];
00625     
00626     if (_connect || _status != GSSTAT_READY) return -1;
00627 
00628     command(NULL, GSRES_NORMAL);
00629     if (command("ATE0", GSRES_NORMAL)) return -1;
00630     if (_rts) {
00631         command("AT&K0", GSRES_NORMAL);
00632         command("AT&R1", GSRES_NORMAL);
00633     }
00634     disconnect();
00635     command("AT+NMAC=?", GSRES_MACADDRESS);
00636 #ifdef GS_BULK
00637     command("AT+BDATA=1", GSRES_NORMAL);
00638 #endif
00639 
00640     command("AT+WREGDOMAIN=" GS_WREGDOMAIN, GSRES_NORMAL);
00641     command("AT+WM=2", GSRES_NORMAL); // limited ap
00642     wait_ms(1000);
00643     command("AT+NDHCP=0", GSRES_NORMAL);
00644     setAddress(ipaddr, netmask, ipaddr, ipaddr);
00645     if (command("AT+DHCPSRVR=1", GSRES_NORMAL)) return -1;
00646     if (dns) {
00647         sprintf(cmd, "AT+DNS=1,%s", dns);
00648     } else {
00649         strcpy(cmd, "AT+DNS=1," GS_DNSNAME);
00650     }
00651     if (command(cmd, GSRES_NORMAL)) return -1;
00652 
00653     switch (sec) {
00654     case GSSEC_NONE:
00655     case GSSEC_OPEN:
00656     case GSSEC_WEP:
00657         sprintf(cmd, "AT+WAUTH=%d", sec);
00658         command(cmd, GSRES_NORMAL);
00659         if (sec != GSSEC_NONE) {
00660             sprintf(cmd, "AT+WWEP1=%s", pass);
00661             command(cmd, GSRES_NORMAL);
00662             wait_ms(100);
00663         }
00664         sprintf(cmd, "AT+WA=%s", ssid);
00665         r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
00666         break;
00667     default:
00668         DBG("Can't use security\r\n");
00669         r = -1;
00670         break;
00671     }
00672 
00673     if (r == 0) _connect = true;
00674     return r;
00675 }
00676 
00677 int GSwifi::disconnect () {
00678     int i;
00679 
00680     _connect = false;
00681     for (i = 0; i < 16; i ++) {
00682         _gs_sock[i].connect = false;
00683     }
00684     command("AT+NCLOSEALL", GSRES_NORMAL);
00685     command("AT+WD", GSRES_NORMAL);
00686     command("AT+NDHCP=0", GSRES_NORMAL);
00687     wait_ms(100);
00688     return 0;
00689 }
00690 
00691 int GSwifi::setAddress () {
00692 
00693     if (command("AT+NDHCP=1", GSRES_DHCP), GS_TIMEOUT2) return -1;
00694     if (_ipaddr.isNull()) return -1;
00695     return 0;
00696 }
00697 
00698 int GSwifi::setAddress (IpAddr ipaddr, IpAddr netmask, IpAddr gateway, IpAddr nameserver) {
00699     int r;
00700     char cmd[GS_CMD_SIZE];
00701 
00702     command("AT+NDHCP=0", GSRES_NORMAL);
00703     wait_ms(100);
00704 
00705     sprintf(cmd, "AT+NSET=%d.%d.%d.%d,%d.%d.%d.%d,%d.%d.%d.%d",
00706         ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3],
00707         netmask[0], netmask[1], netmask[2], netmask[3],
00708         gateway[0], gateway[1], gateway[2], gateway[3]);
00709     r = command(cmd, GSRES_NORMAL);
00710     if (r) return -1;
00711     _ipaddr = ipaddr;
00712     _netmask = netmask;
00713     _gateway = gateway;
00714 
00715     if (ipaddr != nameserver) {
00716         sprintf(cmd, "AT+DNSSET=%d.%d.%d.%d",
00717             nameserver[0], nameserver[1], nameserver[2], nameserver[3]);
00718         r = command(cmd, GSRES_NORMAL);
00719         _nameserver = nameserver;
00720     }
00721     return r;
00722 }
00723 
00724 int GSwifi::getAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) {
00725     ipaddr = _ipaddr;
00726     netmask = _netmask;
00727     gateway = _gateway;
00728     nameserver = _nameserver;
00729     return 0;
00730 }
00731 
00732 int GSwifi::getHostByName (const char* name, IpAddr &addr) {
00733     char cmd[GS_CMD_SIZE];
00734 
00735     if (! _connect || _status != GSSTAT_READY) return -1;
00736 
00737     sprintf(cmd, "AT+DNSLOOKUP=%s", name);
00738     if (command(cmd, GSRES_DNSLOOKUP)) return -1;
00739 
00740     addr = _resolv;
00741     return 0;
00742 }
00743 
00744 int GSwifi::getHostByName (Host &host) {
00745     char cmd[GS_CMD_SIZE];
00746 
00747     if (! _connect || _status != GSSTAT_READY) return -1;
00748 
00749     sprintf(cmd, "AT+DNSLOOKUP=%s", host.getName());
00750     if (command(cmd, GSRES_DNSLOOKUP)) return -1;
00751 
00752     host.setIp(_resolv);
00753     return 0;
00754 }
00755 
00756 int GSwifi::setRFPower (int power) {
00757     char cmd[GS_CMD_SIZE];
00758 
00759     if (power < 0 || power > 7) return -1;
00760 
00761     sprintf(cmd, "AT+WP=%d", power);
00762     return command(cmd, GSRES_NORMAL);
00763 }
00764 
00765 int GSwifi::powerSave (int active, int save) {
00766     char cmd[GS_CMD_SIZE];
00767 
00768     if (_status != GSSTAT_READY) return -1;
00769 
00770     sprintf(cmd, "AT+WRXACTIVE=%d", active);
00771     command(cmd, GSRES_NORMAL);
00772     sprintf(cmd, "AT+WRXPS=%d", save);
00773     return command(cmd, GSRES_NORMAL);
00774 }
00775 
00776 int GSwifi::standby (int msec) {
00777     char cmd[GS_CMD_SIZE];
00778 
00779     if (_status != GSSTAT_READY && _status != GSSTAT_WAKEUP) return -1;
00780 
00781     if (_status != GSSTAT_WAKEUP) {
00782         command("AT+WRXACTIVE=0", GSRES_NORMAL);
00783         command("AT+STORENWCONN", GSRES_NORMAL);
00784     } else {
00785         command("ATE0", GSRES_NORMAL);
00786         if (_rts) {
00787             command("AT&K0", GSRES_NORMAL);
00788             command("AT&R1", GSRES_NORMAL);
00789         }
00790     }
00791     _status = GSSTAT_STANDBY;
00792     sprintf(cmd, "AT+PSSTBY=%d,0,0,0", msec); // go standby
00793     return command(cmd, GSRES_NORMAL, 0);
00794 }
00795 
00796 int GSwifi::wakeup () {
00797 
00798     if (_status == GSSTAT_WAKEUP) {
00799         _status = GSSTAT_READY;
00800         command("ATE0", GSRES_NORMAL);
00801         if (_rts) {
00802             command("AT&K0", GSRES_NORMAL);
00803             command("AT&R1", GSRES_NORMAL);
00804         }
00805 #ifdef GS_BULK
00806         command("AT+BDATA=1", GSRES_NORMAL);
00807 #endif
00808         command("AT+RESTORENWCONN", GSRES_NORMAL);
00809         wait_ms(100);
00810         return command("AT+WRXACTIVE=1", GSRES_NORMAL);
00811     } else
00812     if (_status == GSSTAT_DEEPSLEEP) {
00813         _status = GSSTAT_READY;
00814         return command("AT", GSRES_NORMAL);
00815     }
00816     return -1;
00817 }
00818 
00819 int GSwifi::deepSleep () {
00820 
00821     if (_status != GSSTAT_READY) return -1;
00822 
00823     _status = GSSTAT_DEEPSLEEP;
00824     return command("AT+PSDPSLEEP", GSRES_NORMAL, 0); // go deep sleep
00825 }
00826 
00827 bool GSwifi::isConnected () {
00828     return _connect;
00829 }
00830 
00831 GSSTATUS GSwifi::getStatus () {
00832     return _status;
00833 }
00834 
00835 int GSwifi::getRssi () {
00836     if (command("AT+WRSSI=?", GSRES_RSSI)) {
00837         return 0;
00838     }
00839     return _rssi;
00840 }
00841 
00842 int GSwifi::ntpdate (Host host, int sec) {
00843     char cmd[GS_CMD_SIZE];
00844 
00845     if (! _connect || _status != GSSTAT_READY) return -1;
00846 
00847     if (host.getIp().isNull()) {
00848         if (getHostByName(host)) {
00849             if (getHostByName(host)) return -1;
00850         }
00851     }
00852 
00853     if (sec) {
00854         sprintf(cmd, "AT+NTIMESYNC=1,%d.%d.%d.%d,%d,1,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3],
00855           GS_TIMEOUT / 1000, sec);
00856     } else {
00857         sprintf(cmd, "AT+NTIMESYNC=1,%d.%d.%d.%d,%d,0", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3],
00858           GS_TIMEOUT / 1000);
00859     }
00860     return command(cmd, GSRES_NORMAL);
00861 }
00862 
00863 int GSwifi::setTime (time_t time) {
00864     char cmd[GS_CMD_SIZE];
00865     struct tm *t;
00866 
00867     if (_status != GSSTAT_READY) return -1;
00868 
00869     t = localtime(&time);
00870     sprintf(cmd, "AT+SETTIME=%d/%d/%d,%d:%d:%d", t->tm_mday, t->tm_mon + 1, t->tm_year + 1900, t->tm_hour, t->tm_min, t->tm_sec);
00871     return command(cmd, GSRES_NORMAL);
00872 }
00873 
00874 time_t GSwifi::getTime () {
00875 
00876     if (command("AT+GETTIME=?", GSRES_TIME)) {
00877         return 0;
00878     }
00879     return _time;
00880 }
00881 
00882 int GSwifi::gpioOut (int port, int out) {
00883     char cmd[GS_CMD_SIZE];
00884 
00885     if (_status != GSSTAT_READY) return -1;
00886 
00887     sprintf(cmd, "AT+DGPIO=%d,%d", port, out);
00888     return command(cmd, GSRES_NORMAL);
00889 }
00890 
00891 void GSwifi::poll_cmd () {
00892     int i;
00893 
00894     while (_gs_enter) {
00895         // received "\n"
00896         char buf[GS_CMD_SIZE];
00897 
00898 //        wait_ms(10);
00899         _gs_enter --;
00900         i = 0;
00901         while (_buf_cmd.use() && i < sizeof(buf)) {
00902             _buf_cmd.get(&buf[i]);
00903             if (buf[i] == '\n') {
00904                 break;
00905             }
00906             i ++;
00907         }
00908         buf[i] = 0;
00909         DBG("poll: %d %s\r\n", _gs_enter, buf);
00910 
00911         if (i == 0) {
00912         } else
00913         if (strncmp(buf, "CONNECT", 7) == 0 && buf[8] >= '0' && buf[8] <= 'F') {
00914             int cid = x2i(buf[8]);
00915             if (_gs_sock[cid].type == GSTYPE_SERVER) {
00916                 int acid, ip1, ip2, ip3, ip4;
00917                 char *tmp = buf + 12;
00918 
00919                 acid = x2i(buf[10]);
00920                 DBG("connect %d -> %d\r\n", cid, acid);
00921                 newSock(acid, _gs_sock[cid].type, _gs_sock[cid].protocol, _gs_sock[cid].onGsReceive);
00922                 _gs_sock[acid].lcid = cid;
00923                 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00924                 _gs_sock[acid].host.setIp(IpAddr(ip1, ip2, ip3, ip4));
00925                 tmp = strstr(tmp, " ") + 1;
00926                 _gs_sock[acid].host.setPort(atoi(tmp));
00927 
00928 #ifdef GS_USE_HTTPD
00929                 if (_gs_sock[acid].protocol == GSPROT_HTTPD) {
00930                     poll_httpd(acid, 0);
00931                 } else
00932 #endif
00933                 if (_gs_sock[acid].onGsReceive != NULL) {
00934                     _gs_sock[acid].onGsReceive(acid, 0); // event connected
00935                 }
00936             }
00937         } else
00938         if (strncmp(buf, "DISCONNECT", 10) == 0) {
00939             int cid = x2i(buf[11]);
00940             DBG("disconnect %d\r\n", cid);
00941             _gs_sock[cid].connect = false;
00942 
00943 #ifdef GS_USE_HTTPD
00944             if (_gs_sock[cid].protocol == GSPROT_HTTPD) {
00945                 poll_httpd(cid, 0);
00946             } else
00947 #endif
00948             if (_gs_sock[cid].onGsReceive != NULL) {
00949                 _gs_sock[cid].onGsReceive(cid, 0); // event disconnected
00950             }
00951         } else
00952         if (strncmp(buf, "DISASSOCIATED", 13) == 0 ||
00953           strncmp(buf, "Disassociated", 13) == 0 ||
00954           strncmp(buf, "Disassociation Event", 20) == 0 ||
00955           strncmp(buf, "UnExpected Warm Boot", 20) == 0) {
00956             _connect = false;
00957             for (i = 0; i < 16; i ++) {
00958                 _gs_sock[i].connect = false;
00959             }
00960         } else
00961         if (strncmp(buf, "Out of StandBy-Timer", 20) == 0 ||
00962           strncmp(buf, "Out of StandBy-Alarm", 20) == 0) {
00963 //            if (_status == GSSTAT_STANDBY) {
00964                 _status = GSSTAT_WAKEUP;
00965 //            }
00966         } else 
00967         if (strncmp(buf, "Out of Deep Sleep", 17) == 0 ) {
00968 //            if (_status == GSSTAT_DEEPSLEEP) {
00969                 _status = GSSTAT_READY;
00970 //            }
00971         } else 
00972         if (strncmp(buf, "Out of", 6) == 0) {
00973         }
00974         DBG("status: %d\r\n", _status);
00975     }
00976 }
00977 
00978 void GSwifi::poll () {
00979     int i, j;
00980 
00981     poll_cmd();
00982 
00983     for (i = 0; i < 16; i ++) {
00984 //        if (_gs_sock[i].connect && _gs_sock[i].received) {
00985         if (_gs_sock[i].received && _gs_sock[i].data->use()) {
00986             // recv interrupt
00987             _gs_sock[i].received = 0;
00988 #ifdef GS_USE_HTTPD
00989             if (_gs_sock[i].protocol == GSPROT_HTTPD) {
00990                 for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) {
00991                     if (! _gs_sock[i].connect || ! _gs_sock[i].data->use()) break;
00992                     poll_httpd(i, _gs_sock[i].data->use());
00993                 }
00994             } else
00995 #endif
00996             if (_gs_sock[i].onGsReceive != NULL) {
00997                 for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) {
00998                     if (! _gs_sock[i].connect || ! _gs_sock[i].data->use()) break;
00999                     _gs_sock[i].onGsReceive(i, _gs_sock[i].data->use());
01000                 }
01001             }
01002         }
01003     }
01004     
01005     if (!_connect && _reconnect_count < _reconnect && _ssid) {
01006         // re-connrct
01007         int r;
01008         char cmd[GS_CMD_SIZE];
01009         _reconnect_count ++;
01010         DBG("re-connect %d\r\n", _reconnect_count);
01011         sprintf(cmd, "AT+WA=%s", _ssid);
01012         r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
01013         if (r == 0) {
01014             _connect = true;
01015             _reconnect_count = 0;
01016         }
01017     }
01018 }
01019 
01020 void GSwifi::newSock (int cid, GSTYPE type, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
01021     _gs_sock[cid].type = type;
01022     _gs_sock[cid].protocol = pro;
01023     _gs_sock[cid].connect = true;
01024     if (_gs_sock[cid].data == NULL) {
01025         _gs_sock[cid].data = new RingBuffer(GS_DATA_SIZE);
01026     } else {
01027         _gs_sock[cid].data->clear();
01028     }
01029     _gs_sock[cid].lcid = 0;
01030     _gs_sock[cid].received = 0;
01031     _gs_sock[cid].onGsReceive = ponGsReceive;
01032 }
01033 
01034 int GSwifi::open (Host &host, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
01035     char cmd[GS_CMD_SIZE];
01036 
01037     if (! _connect || _status != GSSTAT_READY) return -1;
01038     if (host.getIp().isNull() || host.getPort() == 0) {
01039         return -1;
01040     }
01041 
01042     if (pro == GSPROT_UDP) {
01043         sprintf(cmd, "AT+NCUDP=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01044     } else {
01045         sprintf(cmd, "AT+NCTCP=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01046     }
01047     if (command(cmd, GSRES_CONNECT)) return -1;
01048 
01049     newSock(_cid, GSTYPE_CLIENT, pro, ponGsReceive);
01050     return _cid;
01051 }
01052 
01053 int GSwifi::listen (int port, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
01054     char cmd[GS_CMD_SIZE];
01055 
01056     if (! _connect || _status != GSSTAT_READY) return -1;
01057     if (port == 0) {
01058         return -1;
01059     }
01060 
01061     if (pro == GSPROT_UDP) {
01062         sprintf(cmd, "AT+NSUDP=%d", port);
01063     } else {
01064         sprintf(cmd, "AT+NSTCP=%d", port);
01065     }
01066     if (command(cmd, GSRES_CONNECT)) return -1;
01067 
01068     newSock(_cid, GSTYPE_SERVER, pro, ponGsReceive);
01069     return _cid;
01070 }
01071 
01072 int GSwifi::close (int cid) {
01073     char cmd[GS_CMD_SIZE];
01074 
01075     if (! _gs_sock[cid].connect) return -1;
01076 
01077     _gs_sock[cid].connect = false;
01078 //    delete _gs_sock[cid].data;
01079 //    _gs_sock[cid].data = NULL;
01080     sprintf(cmd, "AT+NCLOSE=%X", cid);
01081     return command(cmd, GSRES_NORMAL);    
01082 }
01083 
01084 int GSwifi::send (int cid, const char *buf, int len) {
01085     int i;
01086     Timer timeout;
01087 
01088     if (! _gs_sock[cid].connect) return -1;
01089 
01090     if ((_gs_sock[cid].protocol == GSPROT_TCP) ||
01091       (_gs_sock[cid].protocol == GSPROT_UDP && _gs_sock[cid].type == GSTYPE_CLIENT) ||
01092       (_gs_sock[cid].protocol == GSPROT_HTTPD)) {
01093         // TCP Client, TCP Server, UDP Client
01094         _gs_ok = 0;
01095         _gs_failure = 0;
01096 #ifdef GS_BULK
01097         _gs.printf("\x1bZ%X%04d", cid, len);
01098         for (i = 0; i < len; i ++) {
01099             _gs_putc(buf[i]);
01100 #ifdef DEBUG_VIEW
01101             DBG("%c", buf[i]);
01102 #endif
01103         }
01104 #else
01105         _gs.printf("\x1bS%X", cid);
01106         for (i = 0; i < len; i ++) {
01107             if (buf[i] >= 0x20 && buf[i] < 0x7f) {
01108                 _gs_putc(buf[i]);
01109 #ifdef DEBUG_VIEW
01110                 DBG("%c", buf[i]);
01111 #endif
01112             }
01113         }
01114         _gs_putc(0x1b);
01115         _gs_putc('E');
01116 #endif
01117     } else {
01118         return -1;
01119     }
01120     timeout.start();
01121     while (!_gs_ok && !_gs_failure && timeout.read_ms() < GS_TIMEOUT);
01122     return _gs_ok == 1 ? 0 : -1;
01123 }
01124 
01125 int GSwifi::send (int cid, const char *buf, int len, Host &host) {
01126     int i;
01127     Timer timeout;
01128 
01129     if (! _gs_sock[cid].connect) return -1;
01130 
01131     if ((_gs_sock[cid].protocol == GSPROT_UDP && _gs_sock[cid].type == GSTYPE_SERVER)) {
01132         // UDP Server
01133         _gs_ok = 0;
01134         _gs_failure = 0;
01135 #ifdef GS_BULK
01136         _gs.printf("\x1bY%X", cid);
01137         _gs.printf("%d.%d.%d.%d:%d:", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01138         _gs.printf("%04d", len);
01139         for (i = 0; i < len; i ++) {
01140             _gs_putc(buf[i]);
01141 #ifdef DEBUG_VIEW
01142             DBG("%c", buf[i]);
01143 #endif
01144         }
01145 #else
01146         _gs.printf("\x1bU%X", cid);
01147         _gs.printf("%d.%d.%d.%d:%d:", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01148         for (i = 0; i < len; i ++) {
01149             if (buf[i] >= 0x20 && buf[i] < 0x7f) {
01150                 _gs_putc(buf[i]);
01151 #ifdef DEBUG_VIEW
01152                 DBG("%c", buf[i]);
01153 #endif
01154             }
01155         }
01156         _gs_putc(0x1b);
01157         _gs_putc('E');
01158 #endif
01159     } else {
01160         return -1;
01161     }
01162     timeout.start();
01163     while (!_gs_ok && !_gs_failure && timeout.read_ms() < GS_TIMEOUT);
01164     return _gs_ok == 1 ? 0 : -1;
01165 }
01166 
01167 int GSwifi::recv (int cid, char *buf, int len) {
01168     int r;
01169     Timer timeout;
01170     
01171     if (_gs_sock[cid].data == NULL) return 0;
01172 
01173     timeout.start();
01174     while (_gs_sock[cid].data->use() == 0) {
01175         if (timeout.read_ms() > GS_TIMEOUT) return 0;
01176     }
01177     timeout.stop();
01178 
01179     r = _gs_sock[cid].data->get(buf, len);
01180     return r;
01181 }
01182 
01183 int GSwifi::recv (int cid, char *buf, int len, Host &host) {
01184     int r;
01185     Timer timeout;
01186     
01187     if (_gs_sock[cid].data == NULL) return 0;
01188 
01189     timeout.start();
01190     while (_gs_sock[cid].data->use() == 0) {
01191         if (timeout.read_ms() > GS_TIMEOUT) return 0;
01192     }
01193     timeout.stop();
01194 
01195     r = _gs_sock[cid].data->get(buf, len);
01196     host = _from;
01197     return r;
01198 }
01199 
01200 bool GSwifi::isConnected (int cid) {
01201     return _gs_sock[cid].connect;
01202 }
01203 
01204 int GSwifi::httpGet (Host &host, const char *uri, const char *user, const char *pwd, int ssl, onGsReceiveFunc ponGsReceive) {
01205     char cmd[GS_CMD_SIZE];
01206 
01207     if (! _connect || _status != GSSTAT_READY) return -1;
01208 
01209     if (host.getIp().isNull()) {
01210         if (getHostByName(host)) {
01211             if (getHostByName(host)) return -1;
01212         }
01213     }
01214     if (host.getPort() == 0) {
01215         if (ssl) {
01216             host.setPort(443);
01217         } else {
01218             host.setPort(80);
01219         }
01220     }
01221 
01222     command("AT+HTTPCONF=3,close", GSRES_NORMAL); // Connection:
01223     sprintf(cmd, "AT+HTTPCONF=11,%s", host.getName());  // Host:
01224     command(cmd, GSRES_NORMAL);
01225     if (user && pwd) {
01226         char tmp[GS_CMD_SIZE], tmp2[GS_CMD_SIZE];
01227         snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
01228         base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2));
01229         sprintf(cmd, "AT+HTTPCONF=2,Basic %s", tmp2);  // Authorization:
01230         command(cmd, GSRES_NORMAL);
01231     } else {
01232         command("AT+HTTPCONFDEL=2", GSRES_NORMAL);
01233     }
01234     command("AT+HTTPCONFDEL=5", GSRES_NORMAL);
01235     command("AT+HTTPCONFDEL=7", GSRES_NORMAL);
01236 
01237     sprintf(cmd, "AT+HTTPOPEN=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01238     if (ssl) {
01239         strcat(cmd, ",1");
01240     }
01241     if (command(cmd, GSRES_HTTP)) return -1;
01242     newSock(_cid, GSTYPE_CLIENT, GSPROT_HTTPGET, ponGsReceive);
01243 
01244     sprintf(cmd, "AT+HTTPSEND=%d,1,%d,%s", _cid, GS_TIMEOUT / 1000, uri);  // GET
01245     command(cmd, GSRES_NORMAL);
01246 
01247     return _cid;
01248 }
01249 
01250 int GSwifi::httpGet (Host &host, const char *uri, int ssl, onGsReceiveFunc ponGsReceive) {
01251     return httpGet (host, uri, NULL, NULL, ssl, ponGsReceive);
01252 }
01253 
01254 int GSwifi::httpPost (Host &host, const char *uri, const char *body, const char *user, const char *pwd, int ssl, onGsReceiveFunc ponGsReceive) {
01255     char cmd[GS_CMD_SIZE];
01256     int i, len;
01257 
01258     if (! _connect || _status != GSSTAT_READY) return -1;
01259 
01260     if (host.getIp().isNull()) {
01261         if (getHostByName(host)) {
01262             if (getHostByName(host)) return -1;
01263         }
01264     }
01265     if (host.getPort() == 0) {
01266         if (ssl) {
01267             host.setPort(443);
01268         } else {
01269             host.setPort(80);
01270         }
01271     }
01272     len = strlen(body);
01273 
01274     command("AT+HTTPCONF=3,close", GSRES_NORMAL); // Connection:
01275     sprintf(cmd, "AT+HTTPCONF=11,%s", host.getName());  // Host:
01276     command(cmd, GSRES_NORMAL);
01277     sprintf(cmd, "AT+HTTPCONF=5,%d", len);  // Content-Length:
01278     command(cmd, GSRES_NORMAL);
01279     command("AT+HTTPCONF=7,application/x-www-form-urlencoded", GSRES_NORMAL); // Content-type:
01280     if (user && pwd) {
01281         char tmp[GS_CMD_SIZE], tmp2[GS_CMD_SIZE];
01282         snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
01283         base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2));
01284         sprintf(cmd, "AT+HTTPCONF=2,Basic %s", tmp2);  // Authorization:
01285         command(cmd, GSRES_NORMAL);
01286     } else {
01287         command("AT+HTTPCONFDEL=2", GSRES_NORMAL);
01288     }
01289 
01290     sprintf(cmd, "AT+HTTPOPEN=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01291     if (ssl) {
01292         strcat(cmd, ",1");
01293     }
01294     if (command(cmd, GSRES_HTTP)) return -1;
01295     newSock(_cid, GSTYPE_CLIENT, GSPROT_HTTPPOST, ponGsReceive);
01296 
01297     sprintf(cmd, "AT+HTTPSEND=%d,3,%d,%s,%d", _cid, GS_TIMEOUT / 1000, uri, len);  // POST
01298     command(cmd, GSRES_NORMAL);
01299 
01300     _gs.printf("\x1bH%X", _cid);
01301     for (i = 0; i < len; i ++) {
01302         _gs_putc(body[i]);
01303         DBG("%c", body[i]);
01304     }
01305 
01306     return _cid;
01307 }
01308 
01309 int GSwifi::httpPost (Host &host, const char *uri, const char *body, int ssl, onGsReceiveFunc ponGsReceive) {
01310     return httpPost (host, uri, body, NULL, NULL, ssl, ponGsReceive);
01311 }
01312 
01313 int GSwifi::certAdd (const char *name, const char *cert, int len) {
01314     int i;
01315     char cmd[GS_CMD_SIZE];
01316 
01317     if (! _connect || _status != GSSTAT_READY) return -1;
01318 
01319     sprintf(cmd, "AT+TCERTADD=%s,1,%d,1", name, len);  // Hex, ram
01320     command(cmd, GSRES_NORMAL);
01321     
01322     _gs_putc(0x1b);
01323     _gs_putc('W');
01324     for (i = 0; i < len; i ++) {
01325         _gs_putc(cert[i]);
01326     }
01327     return cmdResponse(GSRES_NORMAL, GS_TIMEOUT);
01328 }
01329 
01330 int GSwifi::provisioning (char *user, char *pass) {
01331     char cmd[GS_CMD_SIZE];
01332 
01333     if (_status != GSSTAT_READY) return -1;
01334 
01335     sprintf(cmd, "AT+WEBPROV=%s,%s", user, pass);
01336     return command(cmd, GSRES_NORMAL);
01337 }
01338 
01339 int GSwifi::setBaud (int baud) {
01340 
01341     if (_status != GSSTAT_READY) return -1;
01342 
01343     _gs.printf("ATB=%d\r\n", baud);
01344     _gs.baud(baud);
01345     for (int i = 0; i < 10; i ++) {
01346         wait_ms(10);
01347         poll_cmd();
01348         _buf_cmd.clear();
01349     }
01350     return 0;
01351 }
01352 
01353 int GSwifi::base64encode (char *input, int length, char *output, int len) {
01354     // code from 
01355     // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
01356     static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
01357     unsigned int c, c1, c2, c3;
01358 
01359     if (len < ((((length-1)/3)+1)<<2)) return -1;
01360     for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
01361         c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
01362         c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
01363         c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0;
01364 
01365         c = ((c1 & 0xFC) >> 2);
01366         output[j+0] = base64[c];
01367         c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4);
01368         output[j+1] = base64[c];
01369         c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6);
01370         output[j+2] = (length>i+1)?base64[c]:'=';
01371         c = (c3 & 0x3F);
01372         output[j+3] = (length>i+2)?base64[c]:'=';
01373     }
01374     output[(((length-1)/3)+1)<<2] = '\0';
01375     return 0;
01376 }
01377 
01378 int GSwifi::from_hex (int ch) {
01379   return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
01380 }
01381 
01382 int GSwifi::to_hex (int code) {
01383   static char hex[] = "0123456789abcdef";
01384   return hex[code & 15];
01385 }
01386 
01387 int GSwifi::urlencode (char *str, char *buf, int len) {
01388     // code from 
01389     // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
01390 //  char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
01391     char *pstr = str, *pbuf = buf;
01392 
01393     if (len < (strlen(str) * 3 + 1)) return -1;
01394     while (*pstr) {
01395         if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
01396             *pbuf++ = *pstr;
01397         else if (*pstr == ' ') 
01398             *pbuf++ = '+';
01399         else 
01400             *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
01401         pstr++;
01402     }
01403     *pbuf = '\0';
01404     return 0;
01405 }
01406 
01407 int GSwifi::urldecode (char *str, char *buf, int len) {
01408     // code from 
01409     // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
01410 //  char *pstr = str, *buf = (char*)malloc(strlen(str) + 1), *pbuf = buf;
01411     char *pstr = str, *pbuf = buf;
01412 
01413     if (len < (strlen(str) / 3 - 1)) return -1;
01414     while (*pstr) {
01415         if (*pstr == '%') {
01416             if (pstr[1] && pstr[2]) {
01417                 *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
01418                 pstr += 2;
01419             }
01420         } else if (*pstr == '+') { 
01421             *pbuf++ = ' ';
01422         } else {
01423             *pbuf++ = *pstr;
01424         }
01425         pstr++;
01426     }
01427     *pbuf = '\0';
01428     return 0;
01429 }
01430 
01431 int GSwifi::x2i (char c) {
01432     if (c >= '0' && c <= '9') {
01433         return c - '0';
01434     } else
01435     if (c >= 'A' && c <= 'F') {
01436         return c - 'A' + 10;
01437     } else
01438     if (c >= 'a' && c <= 'f') {
01439         return c - 'a' + 10;
01440     }
01441     return 0;
01442 }
01443 
01444 char GSwifi::i2x (int i) {
01445     if (i >= 0 && i <= 9) {
01446         return i + '0';
01447     } else
01448     if (i >= 10 && i <= 15) {
01449         return i - 10 + 'A';
01450     }
01451     return 0;
01452 }
01453 
01454 #ifdef DEBUG
01455 // for test
01456 void GSwifi::dump () {
01457     int i;
01458     
01459     DBG("GS mode=%d, escape=%d, cid=%d\r\n", _gs_mode, _escape, _cid);
01460     for (i = 0; i < 16; i ++) {
01461         DBG("%d: connect=%d, type=%d, protocol=%d, len=%d\r\n", i, _gs_sock[i].connect, _gs_sock[i].type, _gs_sock[i].protocol, _gs_sock[i].data->use());
01462         if (_gs_sock[i].protocol == GSPROT_HTTPD) {
01463             DBG("  mode=%d, type=%d, len=%d\r\n", i, _httpd[i].mode, _httpd[i].type, _httpd[i].len);
01464         }
01465     }
01466 }
01467 
01468 void GSwifi::test () {
01469 /*
01470     command(NULL, GSRES_NORMAL);
01471     wait_ms(100);
01472     command("AT+NCLOSEALL", GSRES_NORMAL);
01473     _connect = true;
01474 */
01475     command("AT+WRXACTIVE=1", GSRES_NORMAL);
01476 }
01477 
01478 int GSwifi::getc() {
01479     char c;
01480     if (_buf_cmd.use()) {
01481         _buf_cmd.get(&c);
01482     }
01483 /*
01484     } else
01485     if (_gs_sock[0].data != NULL) {
01486         _gs_sock[0].data->get(&c);
01487     }
01488 */
01489     return c;
01490 }
01491 
01492 void GSwifi::putc(char c) {
01493     _gs_putc(c);
01494 }
01495 
01496 int GSwifi::readable() {
01497     return _buf_cmd.use();
01498 //    return _buf_cmd.use() || (_gs_sock[0].data != NULL && _gs_sock[0].data->use());
01499 }
01500 #endif