gs fan / GSwifi_old

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     }
00720     return r;
00721 }
00722 
00723 int GSwifi::getAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) {
00724     ipaddr = _ipaddr;
00725     netmask = _netmask;
00726     gateway = _gateway;
00727     nameserver = _nameserver;
00728     return 0;
00729 }
00730 
00731 int GSwifi::getHostByName (const char* name, IpAddr &addr) {
00732     char cmd[GS_CMD_SIZE];
00733 
00734     if (! _connect || _status != GSSTAT_READY) return -1;
00735 
00736     sprintf(cmd, "AT+DNSLOOKUP=%s", name);
00737     if (command(cmd, GSRES_DNSLOOKUP)) return -1;
00738 
00739     addr = _resolv;
00740     return 0;
00741 }
00742 
00743 int GSwifi::getHostByName (Host &host) {
00744     char cmd[GS_CMD_SIZE];
00745 
00746     if (! _connect || _status != GSSTAT_READY) return -1;
00747 
00748     sprintf(cmd, "AT+DNSLOOKUP=%s", host.getName());
00749     if (command(cmd, GSRES_DNSLOOKUP)) return -1;
00750 
00751     host.setIp(_resolv);
00752     return 0;
00753 }
00754 
00755 int GSwifi::setRFPower (int power) {
00756     char cmd[GS_CMD_SIZE];
00757 
00758     if (power < 0 || power > 7) return -1;
00759 
00760     sprintf(cmd, "AT+WP=%d", power);
00761     return command(cmd, GSRES_NORMAL);
00762 }
00763 
00764 int GSwifi::powerSave (int active, int save) {
00765     char cmd[GS_CMD_SIZE];
00766 
00767     if (_status != GSSTAT_READY) return -1;
00768 
00769     sprintf(cmd, "AT+WRXACTIVE=%d", active);
00770     command(cmd, GSRES_NORMAL);
00771     sprintf(cmd, "AT+WRXPS=%d", save);
00772     return command(cmd, GSRES_NORMAL);
00773 }
00774 
00775 int GSwifi::standby (int msec) {
00776     char cmd[GS_CMD_SIZE];
00777 
00778     if (_status != GSSTAT_READY && _status != GSSTAT_WAKEUP) return -1;
00779 
00780     if (_status != GSSTAT_WAKEUP) {
00781         command("AT+WRXACTIVE=0", GSRES_NORMAL);
00782         command("AT+STORENWCONN", GSRES_NORMAL);
00783     } else {
00784         command("ATE0", GSRES_NORMAL);
00785         if (_rts) {
00786             command("AT&K0", GSRES_NORMAL);
00787             command("AT&R1", GSRES_NORMAL);
00788         }
00789     }
00790     _status = GSSTAT_STANDBY;
00791     sprintf(cmd, "AT+PSSTBY=%d,0,0,0", msec); // go standby
00792     return command(cmd, GSRES_NORMAL, 0);
00793 }
00794 
00795 int GSwifi::wakeup () {
00796 
00797     if (_status == GSSTAT_WAKEUP) {
00798         _status = GSSTAT_READY;
00799         command("ATE0", GSRES_NORMAL);
00800         if (_rts) {
00801             command("AT&K0", GSRES_NORMAL);
00802             command("AT&R1", GSRES_NORMAL);
00803         }
00804 #ifdef GS_BULK
00805         command("AT+BDATA=1", GSRES_NORMAL);
00806 #endif
00807         command("AT+RESTORENWCONN", GSRES_NORMAL);
00808         wait_ms(100);
00809         return command("AT+WRXACTIVE=1", GSRES_NORMAL);
00810     } else
00811     if (_status == GSSTAT_DEEPSLEEP) {
00812         _status = GSSTAT_READY;
00813         return command("AT", GSRES_NORMAL);
00814     }
00815     return -1;
00816 }
00817 
00818 int GSwifi::deepSleep () {
00819 
00820     if (_status != GSSTAT_READY) return -1;
00821 
00822     _status = GSSTAT_DEEPSLEEP;
00823     return command("AT+PSDPSLEEP", GSRES_NORMAL, 0); // go deep sleep
00824 }
00825 
00826 bool GSwifi::isConnected () {
00827     return _connect;
00828 }
00829 
00830 GSSTATUS GSwifi::getStatus () {
00831     return _status;
00832 }
00833 
00834 int GSwifi::getRssi () {
00835     if (command("AT+WRSSI=?", GSRES_RSSI)) {
00836         return 0;
00837     }
00838     return _rssi;
00839 }
00840 
00841 int GSwifi::ntpdate (Host host, int sec) {
00842     char cmd[GS_CMD_SIZE];
00843 
00844     if (! _connect || _status != GSSTAT_READY) return -1;
00845 
00846     if (host.getIp().isNull()) {
00847         if (getHostByName(host)) {
00848             if (getHostByName(host)) return -1;
00849         }
00850     }
00851 
00852     if (sec) {
00853         sprintf(cmd, "AT+NTIMESYNC=1,%d.%d.%d.%d,%d,1,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3],
00854           GS_TIMEOUT / 1000, sec);
00855     } else {
00856         sprintf(cmd, "AT+NTIMESYNC=1,%d.%d.%d.%d,%d,0", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3],
00857           GS_TIMEOUT / 1000);
00858     }
00859     return command(cmd, GSRES_NORMAL);
00860 }
00861 
00862 int GSwifi::setTime (time_t time) {
00863     char cmd[GS_CMD_SIZE];
00864     struct tm *t;
00865 
00866     if (_status != GSSTAT_READY) return -1;
00867 
00868     t = localtime(&time);
00869     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);
00870     return command(cmd, GSRES_NORMAL);
00871 }
00872 
00873 time_t GSwifi::getTime () {
00874 
00875     if (command("AT+GETTIME=?", GSRES_TIME)) {
00876         return 0;
00877     }
00878     return _time;
00879 }
00880 
00881 int GSwifi::gpioOut (int port, int out) {
00882     char cmd[GS_CMD_SIZE];
00883 
00884     if (_status != GSSTAT_READY) return -1;
00885 
00886     sprintf(cmd, "AT+DGPIO=%d,%d", port, out);
00887     return command(cmd, GSRES_NORMAL);
00888 }
00889 
00890 void GSwifi::poll_cmd () {
00891     int i;
00892 
00893     while (_gs_enter) {
00894         // received "\n"
00895         char buf[GS_CMD_SIZE];
00896 
00897 //        wait_ms(10);
00898         _gs_enter --;
00899         i = 0;
00900         while (_buf_cmd.use() && i < sizeof(buf)) {
00901             _buf_cmd.get(&buf[i]);
00902             if (buf[i] == '\n') {
00903                 break;
00904             }
00905             i ++;
00906         }
00907         buf[i] = 0;
00908         DBG("poll: %d %s\r\n", _gs_enter, buf);
00909 
00910         if (i == 0) {
00911         } else
00912         if (strncmp(buf, "CONNECT", 7) == 0 && buf[8] >= '0' && buf[8] <= 'F') {
00913             int cid = x2i(buf[8]);
00914             if (_gs_sock[cid].type == GSTYPE_SERVER) {
00915                 int acid, ip1, ip2, ip3, ip4;
00916                 char *tmp = buf + 12;
00917 
00918                 acid = x2i(buf[10]);
00919                 DBG("connect %d -> %d\r\n", cid, acid);
00920                 newSock(acid, _gs_sock[cid].type, _gs_sock[cid].protocol, _gs_sock[cid].onGsReceive);
00921                 _gs_sock[acid].lcid = cid;
00922                 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00923                 _gs_sock[acid].host.setIp(IpAddr(ip1, ip2, ip3, ip4));
00924                 tmp = strstr(tmp, " ") + 1;
00925                 _gs_sock[acid].host.setPort(atoi(tmp));
00926 
00927 #ifdef GS_USE_HTTPD
00928                 if (_gs_sock[acid].protocol == GSPROT_HTTPD) {
00929                     poll_httpd(acid, 0);
00930                 } else
00931 #endif
00932                 if (_gs_sock[acid].onGsReceive != NULL) {
00933                     _gs_sock[acid].onGsReceive(acid, 0); // event connected
00934                 }
00935             }
00936         } else
00937         if (strncmp(buf, "DISCONNECT", 10) == 0) {
00938             int cid = x2i(buf[11]);
00939             DBG("disconnect %d\r\n", cid);
00940             _gs_sock[cid].connect = false;
00941 
00942 #ifdef GS_USE_HTTPD
00943             if (_gs_sock[cid].protocol == GSPROT_HTTPD) {
00944                 poll_httpd(cid, 0);
00945             } else
00946 #endif
00947             if (_gs_sock[cid].onGsReceive != NULL) {
00948                 _gs_sock[cid].onGsReceive(cid, 0); // event disconnected
00949             }
00950         } else
00951         if (strncmp(buf, "DISASSOCIATED", 13) == 0 ||
00952           strncmp(buf, "Disassociated", 13) == 0 ||
00953           strncmp(buf, "Disassociation Event", 20) == 0 ||
00954           strncmp(buf, "UnExpected Warm Boot", 20) == 0) {
00955             _connect = false;
00956             for (i = 0; i < 16; i ++) {
00957                 _gs_sock[i].connect = false;
00958             }
00959         } else
00960         if (strncmp(buf, "Out of StandBy-Timer", 20) == 0 ||
00961           strncmp(buf, "Out of StandBy-Alarm", 20) == 0) {
00962 //            if (_status == GSSTAT_STANDBY) {
00963                 _status = GSSTAT_WAKEUP;
00964 //            }
00965         } else 
00966         if (strncmp(buf, "Out of Deep Sleep", 17) == 0 ) {
00967 //            if (_status == GSSTAT_DEEPSLEEP) {
00968                 _status = GSSTAT_READY;
00969 //            }
00970         } else 
00971         if (strncmp(buf, "Out of", 6) == 0) {
00972         }
00973         DBG("status: %d\r\n", _status);
00974     }
00975 }
00976 
00977 void GSwifi::poll () {
00978     int i, j;
00979 
00980     poll_cmd();
00981 
00982     for (i = 0; i < 16; i ++) {
00983 //        if (_gs_sock[i].connect && _gs_sock[i].received) {
00984         if (_gs_sock[i].received && _gs_sock[i].data->use()) {
00985             // recv interrupt
00986             _gs_sock[i].received = 0;
00987 #ifdef GS_USE_HTTPD
00988             if (_gs_sock[i].protocol == GSPROT_HTTPD) {
00989                 for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) {
00990                     if (! _gs_sock[i].connect || ! _gs_sock[i].data->use()) break;
00991                     poll_httpd(i, _gs_sock[i].data->use());
00992                 }
00993             } else
00994 #endif
00995             if (_gs_sock[i].onGsReceive != NULL) {
00996                 for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) {
00997                     if (! _gs_sock[i].connect || ! _gs_sock[i].data->use()) break;
00998                     _gs_sock[i].onGsReceive(i, _gs_sock[i].data->use());
00999                 }
01000             }
01001         }
01002     }
01003     
01004     if (!_connect && _reconnect_count < _reconnect && _ssid) {
01005         // re-connrct
01006         int r;
01007         char cmd[GS_CMD_SIZE];
01008         _reconnect_count ++;
01009         DBG("re-connect %d\r\n", _reconnect_count);
01010         sprintf(cmd, "AT+WA=%s", _ssid);
01011         r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
01012         if (r == 0) {
01013             _connect = true;
01014             _reconnect_count = 0;
01015         }
01016     }
01017 }
01018 
01019 void GSwifi::newSock (int cid, GSTYPE type, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
01020     _gs_sock[cid].type = type;
01021     _gs_sock[cid].protocol = pro;
01022     _gs_sock[cid].connect = true;
01023     if (_gs_sock[cid].data == NULL) {
01024         _gs_sock[cid].data = new RingBuffer(GS_DATA_SIZE);
01025     } else {
01026         _gs_sock[cid].data->clear();
01027     }
01028     _gs_sock[cid].lcid = 0;
01029     _gs_sock[cid].received = 0;
01030     _gs_sock[cid].onGsReceive = ponGsReceive;
01031 }
01032 
01033 int GSwifi::open (Host &host, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
01034     char cmd[GS_CMD_SIZE];
01035 
01036     if (! _connect || _status != GSSTAT_READY) return -1;
01037     if (host.getIp().isNull() || host.getPort() == 0) {
01038         return -1;
01039     }
01040 
01041     if (pro == GSPROT_UDP) {
01042         sprintf(cmd, "AT+NCUDP=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01043     } else {
01044         sprintf(cmd, "AT+NCTCP=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01045     }
01046     if (command(cmd, GSRES_CONNECT)) return -1;
01047 
01048     newSock(_cid, GSTYPE_CLIENT, pro, ponGsReceive);
01049     return _cid;
01050 }
01051 
01052 int GSwifi::listen (int port, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
01053     char cmd[GS_CMD_SIZE];
01054 
01055     if (! _connect || _status != GSSTAT_READY) return -1;
01056     if (port == 0) {
01057         return -1;
01058     }
01059 
01060     if (pro == GSPROT_UDP) {
01061         sprintf(cmd, "AT+NSUDP=%d", port);
01062     } else {
01063         sprintf(cmd, "AT+NSTCP=%d", port);
01064     }
01065     if (command(cmd, GSRES_CONNECT)) return -1;
01066 
01067     newSock(_cid, GSTYPE_SERVER, pro, ponGsReceive);
01068     return _cid;
01069 }
01070 
01071 int GSwifi::close (int cid) {
01072     char cmd[GS_CMD_SIZE];
01073 
01074     if (! _gs_sock[cid].connect) return -1;
01075 
01076     _gs_sock[cid].connect = false;
01077 //    delete _gs_sock[cid].data;
01078 //    _gs_sock[cid].data = NULL;
01079     sprintf(cmd, "AT+NCLOSE=%X", cid);
01080     return command(cmd, GSRES_NORMAL);    
01081 }
01082 
01083 int GSwifi::send (int cid, const char *buf, int len) {
01084     int i;
01085     Timer timeout;
01086 
01087     if (! _gs_sock[cid].connect) return -1;
01088 
01089     if ((_gs_sock[cid].protocol == GSPROT_TCP) ||
01090       (_gs_sock[cid].protocol == GSPROT_UDP && _gs_sock[cid].type == GSTYPE_CLIENT) ||
01091       (_gs_sock[cid].protocol == GSPROT_HTTPD)) {
01092         // TCP Client, TCP Server, UDP Client
01093         _gs_ok = 0;
01094         _gs_failure = 0;
01095 #ifdef GS_BULK
01096         _gs.printf("\x1bZ%X%04d", cid, len);
01097         for (i = 0; i < len; i ++) {
01098             _gs_putc(buf[i]);
01099 #ifdef DEBUG_VIEW
01100             DBG("%c", buf[i]);
01101 #endif
01102         }
01103 #else
01104         _gs.printf("\x1bS%X", cid);
01105         for (i = 0; i < len; i ++) {
01106             if (buf[i] >= 0x20 && buf[i] < 0x7f) {
01107                 _gs_putc(buf[i]);
01108 #ifdef DEBUG_VIEW
01109                 DBG("%c", buf[i]);
01110 #endif
01111             }
01112         }
01113         _gs_putc(0x1b);
01114         _gs_putc('E');
01115 #endif
01116     } else {
01117         return -1;
01118     }
01119     timeout.start();
01120     while (!_gs_ok && !_gs_failure && timeout.read_ms() < GS_TIMEOUT);
01121     return _gs_ok == 1 ? 0 : -1;
01122 }
01123 
01124 int GSwifi::send (int cid, const char *buf, int len, Host &host) {
01125     int i;
01126     Timer timeout;
01127 
01128     if (! _gs_sock[cid].connect) return -1;
01129 
01130     if ((_gs_sock[cid].protocol == GSPROT_UDP && _gs_sock[cid].type == GSTYPE_SERVER)) {
01131         // UDP Server
01132         _gs_ok = 0;
01133         _gs_failure = 0;
01134 #ifdef GS_BULK
01135         _gs.printf("\x1bY%X", cid);
01136         _gs.printf("%d.%d.%d.%d:%d:", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01137         _gs.printf("%04d", len);
01138         for (i = 0; i < len; i ++) {
01139             _gs_putc(buf[i]);
01140 #ifdef DEBUG_VIEW
01141             DBG("%c", buf[i]);
01142 #endif
01143         }
01144 #else
01145         _gs.printf("\x1bU%X", cid);
01146         _gs.printf("%d.%d.%d.%d:%d:", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01147         for (i = 0; i < len; i ++) {
01148             if (buf[i] >= 0x20 && buf[i] < 0x7f) {
01149                 _gs_putc(buf[i]);
01150 #ifdef DEBUG_VIEW
01151                 DBG("%c", buf[i]);
01152 #endif
01153             }
01154         }
01155         _gs_putc(0x1b);
01156         _gs_putc('E');
01157 #endif
01158     } else {
01159         return -1;
01160     }
01161     timeout.start();
01162     while (!_gs_ok && !_gs_failure && timeout.read_ms() < GS_TIMEOUT);
01163     return _gs_ok == 1 ? 0 : -1;
01164 }
01165 
01166 int GSwifi::recv (int cid, char *buf, int len) {
01167     int r;
01168     Timer timeout;
01169     
01170     if (_gs_sock[cid].data == NULL) return 0;
01171 
01172     timeout.start();
01173     while (_gs_sock[cid].data->use() == 0) {
01174         if (timeout.read_ms() > GS_TIMEOUT) return 0;
01175     }
01176     timeout.stop();
01177 
01178     r = _gs_sock[cid].data->get(buf, len);
01179     return r;
01180 }
01181 
01182 int GSwifi::recv (int cid, char *buf, int len, Host &host) {
01183     int r;
01184     Timer timeout;
01185     
01186     if (_gs_sock[cid].data == NULL) return 0;
01187 
01188     timeout.start();
01189     while (_gs_sock[cid].data->use() == 0) {
01190         if (timeout.read_ms() > GS_TIMEOUT) return 0;
01191     }
01192     timeout.stop();
01193 
01194     r = _gs_sock[cid].data->get(buf, len);
01195     host = _from;
01196     return r;
01197 }
01198 
01199 bool GSwifi::isConnected (int cid) {
01200     return _gs_sock[cid].connect;
01201 }
01202 
01203 int GSwifi::httpGet (Host &host, const char *uri, const char *user, const char *pwd, int ssl, onGsReceiveFunc ponGsReceive) {
01204     char cmd[GS_CMD_SIZE];
01205 
01206     if (! _connect || _status != GSSTAT_READY) return -1;
01207 
01208     if (host.getIp().isNull()) {
01209         if (getHostByName(host)) {
01210             if (getHostByName(host)) return -1;
01211         }
01212     }
01213     if (host.getPort() == 0) {
01214         if (ssl) {
01215             host.setPort(443);
01216         } else {
01217             host.setPort(80);
01218         }
01219     }
01220 
01221     command("AT+HTTPCONF=3,close", GSRES_NORMAL); // Connection:
01222     sprintf(cmd, "AT+HTTPCONF=11,%s", host.getName());  // Host:
01223     command(cmd, GSRES_NORMAL);
01224     if (user && pwd) {
01225         char tmp[GS_CMD_SIZE], tmp2[GS_CMD_SIZE];
01226         snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
01227         base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2));
01228         sprintf(cmd, "AT+HTTPCONF=2,Basic %s", tmp2);  // Authorization:
01229         command(cmd, GSRES_NORMAL);
01230     } else {
01231         command("AT+HTTPCONFDEL=2", GSRES_NORMAL);
01232     }
01233     command("AT+HTTPCONFDEL=5", GSRES_NORMAL);
01234     command("AT+HTTPCONFDEL=7", GSRES_NORMAL);
01235 
01236     sprintf(cmd, "AT+HTTPOPEN=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01237     if (ssl) {
01238         strcat(cmd, ",1");
01239     }
01240     if (command(cmd, GSRES_HTTP)) return -1;
01241     newSock(_cid, GSTYPE_CLIENT, GSPROT_HTTPGET, ponGsReceive);
01242 
01243     sprintf(cmd, "AT+HTTPSEND=%d,1,%d,%s", _cid, GS_TIMEOUT / 1000, uri);  // GET
01244     command(cmd, GSRES_NORMAL);
01245 
01246     return _cid;
01247 }
01248 
01249 int GSwifi::httpGet (Host &host, const char *uri, int ssl, onGsReceiveFunc ponGsReceive) {
01250     return httpGet (host, uri, NULL, NULL, ssl, ponGsReceive);
01251 }
01252 
01253 int GSwifi::httpPost (Host &host, const char *uri, const char *body, const char *user, const char *pwd, int ssl, onGsReceiveFunc ponGsReceive) {
01254     char cmd[GS_CMD_SIZE];
01255     int i, len;
01256 
01257     if (! _connect || _status != GSSTAT_READY) return -1;
01258 
01259     if (host.getIp().isNull()) {
01260         if (getHostByName(host)) {
01261             if (getHostByName(host)) return -1;
01262         }
01263     }
01264     if (host.getPort() == 0) {
01265         if (ssl) {
01266             host.setPort(443);
01267         } else {
01268             host.setPort(80);
01269         }
01270     }
01271     len = strlen(body);
01272 
01273     command("AT+HTTPCONF=3,close", GSRES_NORMAL); // Connection:
01274     sprintf(cmd, "AT+HTTPCONF=11,%s", host.getName());  // Host:
01275     command(cmd, GSRES_NORMAL);
01276     sprintf(cmd, "AT+HTTPCONF=5,%d", len);  // Content-Length:
01277     command(cmd, GSRES_NORMAL);
01278     command("AT+HTTPCONF=7,application/x-www-form-urlencoded", GSRES_NORMAL); // Content-type:
01279     if (user && pwd) {
01280         char tmp[GS_CMD_SIZE], tmp2[GS_CMD_SIZE];
01281         snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
01282         base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2));
01283         sprintf(cmd, "AT+HTTPCONF=2,Basic %s", tmp2);  // Authorization:
01284         command(cmd, GSRES_NORMAL);
01285     } else {
01286         command("AT+HTTPCONFDEL=2", GSRES_NORMAL);
01287     }
01288 
01289     sprintf(cmd, "AT+HTTPOPEN=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
01290     if (ssl) {
01291         strcat(cmd, ",1");
01292     }
01293     if (command(cmd, GSRES_HTTP)) return -1;
01294     newSock(_cid, GSTYPE_CLIENT, GSPROT_HTTPPOST, ponGsReceive);
01295 
01296     sprintf(cmd, "AT+HTTPSEND=%d,3,%d,%s,%d", _cid, GS_TIMEOUT / 1000, uri, len);  // POST
01297     command(cmd, GSRES_NORMAL);
01298 
01299     _gs.printf("\x1bH%X", _cid);
01300     for (i = 0; i < len; i ++) {
01301         _gs_putc(body[i]);
01302         DBG("%c", body[i]);
01303     }
01304 
01305     return _cid;
01306 }
01307 
01308 int GSwifi::httpPost (Host &host, const char *uri, const char *body, int ssl, onGsReceiveFunc ponGsReceive) {
01309     return httpPost (host, uri, body, NULL, NULL, ssl, ponGsReceive);
01310 }
01311 
01312 int GSwifi::certAdd (const char *name, const char *cert, int len) {
01313     int i;
01314     char cmd[GS_CMD_SIZE];
01315 
01316     if (! _connect || _status != GSSTAT_READY) return -1;
01317 
01318     sprintf(cmd, "AT+TCERTADD=%s,1,%d,1", name, len);  // Hex, ram
01319     command(cmd, GSRES_NORMAL);
01320     
01321     _gs_putc(0x1b);
01322     _gs_putc('W');
01323     for (i = 0; i < len; i ++) {
01324         _gs_putc(cert[i]);
01325     }
01326     return cmdResponse(GSRES_NORMAL, GS_TIMEOUT);
01327 }
01328 
01329 int GSwifi::provisioning (char *user, char *pass) {
01330     char cmd[GS_CMD_SIZE];
01331 
01332     if (_status != GSSTAT_READY) return -1;
01333 
01334     sprintf(cmd, "AT+WEBPROV=%s,%s", user, pass);
01335     return command(cmd, GSRES_NORMAL);
01336 }
01337 
01338 int GSwifi::setBaud (int baud) {
01339 
01340     if (_status != GSSTAT_READY) return -1;
01341 
01342     _gs.printf("ATB=%d\r\n", baud);
01343     _gs.baud(baud);
01344     for (int i = 0; i < 10; i ++) {
01345         wait_ms(10);
01346         poll_cmd();
01347         _buf_cmd.clear();
01348     }
01349     return 0;
01350 }
01351 
01352 int GSwifi::base64encode (char *input, int length, char *output, int len) {
01353     // code from 
01354     // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
01355     static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
01356     unsigned int c, c1, c2, c3;
01357 
01358     if (len < ((((length-1)/3)+1)<<2)) return -1;
01359     for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
01360         c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
01361         c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
01362         c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0;
01363 
01364         c = ((c1 & 0xFC) >> 2);
01365         output[j+0] = base64[c];
01366         c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4);
01367         output[j+1] = base64[c];
01368         c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6);
01369         output[j+2] = (length>i+1)?base64[c]:'=';
01370         c = (c3 & 0x3F);
01371         output[j+3] = (length>i+2)?base64[c]:'=';
01372     }
01373     output[(((length-1)/3)+1)<<2] = '\0';
01374     return 0;
01375 }
01376 
01377 int GSwifi::from_hex (int ch) {
01378   return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
01379 }
01380 
01381 int GSwifi::to_hex (int code) {
01382   static char hex[] = "0123456789abcdef";
01383   return hex[code & 15];
01384 }
01385 
01386 int GSwifi::urlencode (char *str, char *buf, int len) {
01387     // code from 
01388     // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
01389 //  char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
01390     char *pstr = str, *pbuf = buf;
01391 
01392     if (len < (strlen(str) * 3 + 1)) return -1;
01393     while (*pstr) {
01394         if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
01395             *pbuf++ = *pstr;
01396         else if (*pstr == ' ') 
01397             *pbuf++ = '+';
01398         else 
01399             *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
01400         pstr++;
01401     }
01402     *pbuf = '\0';
01403     return 0;
01404 }
01405 
01406 int GSwifi::urldecode (char *str, char *buf, int len) {
01407     // code from 
01408     // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
01409 //  char *pstr = str, *buf = (char*)malloc(strlen(str) + 1), *pbuf = buf;
01410     char *pstr = str, *pbuf = buf;
01411 
01412     if (len < (strlen(str) / 3 - 1)) return -1;
01413     while (*pstr) {
01414         if (*pstr == '%') {
01415             if (pstr[1] && pstr[2]) {
01416                 *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
01417                 pstr += 2;
01418             }
01419         } else if (*pstr == '+') { 
01420             *pbuf++ = ' ';
01421         } else {
01422             *pbuf++ = *pstr;
01423         }
01424         pstr++;
01425     }
01426     *pbuf = '\0';
01427     return 0;
01428 }
01429 
01430 int GSwifi::x2i (char c) {
01431     if (c >= '0' && c <= '9') {
01432         return c - '0';
01433     } else
01434     if (c >= 'A' && c <= 'F') {
01435         return c - 'A' + 10;
01436     } else
01437     if (c >= 'a' && c <= 'f') {
01438         return c - 'a' + 10;
01439     }
01440     return 0;
01441 }
01442 
01443 char GSwifi::i2x (int i) {
01444     if (i >= 0 && i <= 9) {
01445         return i + '0';
01446     } else
01447     if (i >= 10 && i <= 15) {
01448         return i - 10 + 'A';
01449     }
01450     return 0;
01451 }
01452 
01453 #ifdef DEBUG
01454 // for test
01455 void GSwifi::dump () {
01456     int i;
01457     
01458     DBG("GS mode=%d, escape=%d, cid=%d\r\n", _gs_mode, _escape, _cid);
01459     for (i = 0; i < 16; i ++) {
01460         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());
01461         if (_gs_sock[i].protocol == GSPROT_HTTPD) {
01462             DBG("  mode=%d, type=%d, len=%d\r\n", i, _httpd[i].mode, _httpd[i].type, _httpd[i].len);
01463         }
01464     }
01465 }
01466 
01467 void GSwifi::test () {
01468 /*
01469     command(NULL, GSRES_NORMAL);
01470     wait_ms(100);
01471     command("AT+NCLOSEALL", GSRES_NORMAL);
01472     _connect = true;
01473 */
01474     command("AT+WRXACTIVE=1", GSRES_NORMAL);
01475 }
01476 
01477 int GSwifi::getc() {
01478     char c;
01479     if (_buf_cmd.use()) {
01480         _buf_cmd.get(&c);
01481     }
01482 /*
01483     } else
01484     if (_gs_sock[0].data != NULL) {
01485         _gs_sock[0].data->get(&c);
01486     }
01487 */
01488     return c;
01489 }
01490 
01491 void GSwifi::putc(char c) {
01492     _gs_putc(c);
01493 }
01494 
01495 int GSwifi::readable() {
01496     return _buf_cmd.use();
01497 //    return _buf_cmd.use() || (_gs_sock[0].data != NULL && _gs_sock[0].data->use());
01498 }
01499 #endif