OLD

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