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

Dependents:   GSwifi_httpd GSwifi_websocket GSwifi_tcpclient GSwifi_tcpserver ... more

Fork of GSwifi by gs fan

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 /* Copyright (C) 2013 gsfan, MIT License
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  */
00018 /** @file
00019  * @brief Gainspan wi-fi module library for mbed
00020  * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
00021  */
00022 
00023 #include "mbed.h"
00024 #include "GSwifi.h"
00025 
00026 
00027 GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_reset, PinName p_alarm, int baud)
00028   : _gs(p_tx, p_rx), _reset(p_reset), _buf_cmd(GS_CMD_SIZE) {
00029 
00030     if (p_alarm != NC) {
00031         _alarm = new DigitalInOut(p_alarm);
00032         _alarm->output(); // low
00033         _alarm->write(0);
00034     } else {
00035         _alarm = NULL;
00036     }
00037 
00038     _reset.output(); // low
00039     _reset = 0;
00040     _baud = baud;
00041     if (_baud) _gs.baud(_baud);
00042     _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
00043     _rts = false;
00044 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00045     _uart = LPC_UART1;
00046 #elif defined(TARGET_LPC11U24)
00047     _uart = LPC_USART;
00048 #endif
00049 
00050     wait_ms(100);
00051     reset();
00052 }
00053 
00054 GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts, PinName p_reset, PinName p_alarm, int baud)
00055   : _gs(p_tx, p_rx), _reset(p_reset), _buf_cmd(GS_CMD_SIZE) {
00056 
00057     if (p_alarm != NC) {
00058         _alarm = new DigitalInOut(p_alarm);
00059         _alarm->output(); // low
00060         _alarm->write(0);
00061     } else {
00062         _alarm = NULL;
00063     }
00064 
00065     _reset.output(); // low
00066     _reset = 0;
00067     _baud = baud;
00068     if (_baud) _gs.baud(_baud);
00069     _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
00070     _rts = false;
00071 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00072     _uart = LPC_UART1;
00073     if (p_cts == p12) { // CTS input (P0_17)
00074         _uart->MCR |= (1<<7); // CTSEN
00075         LPC_PINCON->PINSEL1 &= ~(3 << 2);
00076         LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS
00077     } else
00078     if (p_cts == P2_2) { // CTS input (P2_2)
00079         _uart->MCR |= (1<<7); // CTSEN
00080         LPC_PINCON->PINSEL4 &= ~(3 << 4);
00081         LPC_PINCON->PINSEL4 |= (2 << 4); // UART CTS
00082     }
00083     if (p_rts == P0_22) { // RTS output (P0_22)
00084         _uart->MCR |= (1<<6); // RTSEN
00085         LPC_PINCON->PINSEL1 &= ~(3 << 12);
00086         LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS
00087         _rts = true;
00088     } else
00089     if (p_rts == P2_7) { // RTS output (P2_7)
00090         _uart->MCR |= (1<<6); // RTSEN
00091         LPC_PINCON->PINSEL4 &= ~(3 << 14);
00092         LPC_PINCON->PINSEL4 |= (2 << 14); // UART RTS
00093         _rts = true;
00094     }
00095 #elif defined(TARGET_LPC11U24)
00096     _uart = LPC_USART;
00097     if (p_cts == p21) { // CTS input (P0_7)
00098         _uart->MCR |= (1<<7); // CTSEN
00099         LPC_IOCON->PIO0_7 &= ~0x07;
00100         LPC_IOCON->PIO0_7 |= 0x01; // UART CTS
00101     }
00102     if (p_rts == p22) { // RTS output (P0_17)
00103         _uart->MCR |= (1<<6); // RTSEN
00104         LPC_IOCON->PIO0_17 &= ~0x07;
00105         LPC_IOCON->PIO0_17 |= 0x01; // UART RTS
00106         _rts = true;
00107     }
00108 #endif
00109 
00110     wait_ms(100);
00111     reset();
00112 }
00113 
00114 void GSwifi::reset () {
00115 
00116     if (_alarm != NULL) {
00117         _alarm->output(); // low
00118         _alarm->write(0);
00119         wait_ms(10);
00120         _alarm->input(); // high
00121         _alarm->mode(PullUp);
00122         wait_ms(10);
00123     }
00124     _reset.output(); // low
00125     _reset = 0;
00126 
00127     memset(&_gs_sock, 0, sizeof(_gs_sock));
00128     memset(&_mac, 0, sizeof(_mac));
00129     _connect = false;
00130     _status = GSSTAT_READY;
00131     _escape = false;
00132     resetResponse(GSRES_NONE);
00133     _gs_mode = GSMODE_COMMAND;
00134     _dhcp = false;
00135     _ssid = NULL;
00136     _pass = NULL;
00137     _reconnect = 0;
00138     _buf_cmd.flush();
00139 
00140     wait_ms(100);
00141     if (! _baud) autobaud(0);
00142     _reset.input(); // high
00143     _reset.mode(PullNone);
00144     if (! _baud) autobaud(1);
00145     wait_ms(500);
00146 }
00147 
00148 int GSwifi::autobaud (int flg) {
00149     int i;
00150 
00151 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
00152     if (flg == 0) {
00153         _uart->ACR = (1<<2)|(1<<0); // auto-baud mode 0
00154         return 0;
00155     } else {
00156         for (i = 0; i < 50; i ++) {
00157             if (! (_uart->ACR & (1<<0))) {
00158                 return 0;
00159             }
00160             wait_ms(10);
00161         }
00162         _uart->ACR = 0;
00163     }
00164 #endif
00165     return -1;
00166 }
00167 
00168 int GSwifi::acquireUart (int ms) {
00169     Timer timeout;
00170 
00171     if (! _rts) return 0;
00172 
00173 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
00174     timeout.start();
00175     while (timeout.read_ms() < ms) {
00176         // CTS check
00177         if (_uart->MSR & (1<<4)) {
00178             timeout.stop();
00179             _uart->MCR &= ~(1<<6); // RTS off
00180             _uart->MCR &= ~(1<<1);
00181             return 0;
00182         }
00183     }
00184     timeout.stop();
00185     DBG("cts timeout\r\n");
00186 #endif
00187     return -1;
00188 }
00189 
00190 void GSwifi::releaseUart () {
00191 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
00192     _uart->MCR |= (1<<6); // RTSEN
00193 #endif
00194 }
00195 
00196 // uart interrupt
00197 void GSwifi::isr_recv () {
00198     static int len, mode;
00199     static char tmp[20];
00200     char dat;
00201 
00202     dat = _gs_getc();
00203 #ifdef DEBUG_VIEW
00204     if (dat >= 0x20 && dat < 0x7f) {
00205         DBG("%c_", dat);
00206     } else {
00207         DBG("%02x_", dat);
00208     }
00209 #endif
00210 
00211     switch (_gs_mode) {
00212     case GSMODE_COMMAND: // command responce
00213         if (_escape) {
00214             // esc
00215             switch (dat) {
00216             case 'O':
00217                 DBG("ok\r\n");
00218                 _gs_ok = true;
00219                 break;
00220             case 'F':
00221                 DBG("failure\r\n");
00222                 _gs_failure = true;
00223                 break;
00224             case 'S':
00225                 DBG("GSMODE_DATA_RX\r\n");
00226                 _gs_mode = GSMODE_DATA_RX;
00227                 mode = 0;
00228                 break;
00229             case 'u':
00230                 DBG("GSMODE_DATA_RXUDP\r\n");
00231                 _gs_mode = GSMODE_DATA_RXUDP;
00232                 mode = 0;
00233                 break;
00234             case 'Z':
00235             case 'H':
00236                 DBG("GSMODE_DATA_RX_BULK\r\n");
00237                 _gs_mode = GSMODE_DATA_RX_BULK;
00238                 mode = 0;
00239                 break;
00240             case 'y':
00241                 DBG("GSMODE_DATA_RXUDP_BULK\r\n");
00242                 _gs_mode = GSMODE_DATA_RXUDP_BULK;
00243                 mode = 0;
00244                 break;
00245             default:
00246                 DBG("unknown [ESC] %02x\r\n", dat);
00247                 break;
00248             }
00249             _escape = false;
00250         } else {
00251             if (dat == 0x1b) {
00252                 _escape = true;
00253             } else
00254             if (dat == '\n') {
00255                 // end of line
00256                 parseResponse();
00257             } else
00258             if (dat != '\r') {
00259                 // command
00260                 _buf_cmd.queue(dat);
00261             }
00262         }
00263         break;
00264 
00265     case GSMODE_DATA_RX:
00266     case GSMODE_DATA_RXUDP:
00267         if (mode == 0) {
00268             // cid
00269             _cid = x2i(dat);
00270             _gs_sock[_cid].received = false;
00271             mode ++;
00272             if (_gs_mode == GSMODE_DATA_RX) {
00273                 mode = 3;
00274             }
00275             len = 0;
00276         } else
00277         if (mode == 1) {
00278             // ip
00279             if ((dat < '0' || dat > '9') && dat != '.') {
00280                 int ip1, ip2, ip3, ip4;
00281                 tmp[len] = 0;
00282                 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00283                 _from.setIp(IpAddr(ip1, ip2, ip3, ip4));
00284                 mode ++;
00285                 len = 0;
00286                 break;
00287             }
00288             if (len < sizeof(tmp) - 1) {
00289                 tmp[len] = dat;    
00290                 len ++;
00291             }        
00292         } else
00293         if (mode == 2) {
00294             // port
00295             if (dat < '0' || dat > '9') {
00296                 tmp[len] = 0;
00297                 _from.setPort(atoi(tmp));
00298                 mode ++;
00299                 len = 0;
00300                 break;
00301             }
00302             if (len < sizeof(tmp) - 1) {
00303                 tmp[len] = dat;            
00304                 len ++;        
00305             }
00306         } else
00307         if (_escape) {
00308             // esc
00309             switch (dat) {
00310             case 'E':
00311                 DBG("recv ascii %d\r\n", _cid);
00312                 _gs_sock[_cid].received = true;
00313                 _gs_mode = GSMODE_COMMAND;
00314 
00315                 if (_gs_sock[_cid].protocol == GSPROT_HTTPGET) {
00316                     // recv interrupt
00317                     if (_gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available()) == 0)
00318                         _gs_sock[_cid].received = false;
00319                 }
00320                 break;
00321             default:
00322                 DBG("unknown <ESC> %02x\r\n", dat);
00323                 break;
00324             }
00325             _escape = false;
00326         } else {
00327             if (dat == 0x1b) {
00328                 _escape = true;
00329             } else {
00330                 // data
00331                 if (_gs_sock[_cid].data != NULL) {
00332                   _gs_sock[_cid].data->queue(dat);
00333                   len ++;
00334 
00335                   if (len < GS_DATA_SIZE && _gs_sock[_cid].data->isFull()) {
00336                     // buffer full
00337                     // recv interrupt
00338                     _gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available());
00339                   }
00340                 }
00341             }
00342         }
00343         break;
00344 
00345     case GSMODE_DATA_RX_BULK:
00346     case GSMODE_DATA_RXUDP_BULK:
00347         if (mode == 0) {
00348             // cid
00349             _cid = x2i(dat);
00350             _gs_sock[_cid].received = false;
00351             mode ++;
00352             if (_gs_mode == GSMODE_DATA_RX_BULK) {
00353                 mode = 3;
00354             }
00355             len = 0;
00356         } else
00357         if (mode == 1) {
00358             // ip
00359             if ((dat < '0' || dat > '9') && dat != '.') {
00360                 int ip1, ip2, ip3, ip4;
00361                 tmp[len] = 0;
00362                 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00363                 _from.setIp(IpAddr(ip1, ip2, ip3, ip4));
00364                 mode ++;
00365                 len = 0;
00366                 break;
00367             }
00368             if (len < sizeof(tmp) - 1) {
00369                 tmp[len] = dat;    
00370                 len ++;        
00371             }
00372         } else
00373         if (mode == 2) {
00374             // port
00375             if (dat < '0' || dat > '9') {
00376                 tmp[len] = 0;
00377                 _from.setPort(atoi(tmp));
00378                 mode ++;
00379                 len = 0;
00380                 break;
00381             }
00382             if (len < sizeof(tmp) - 1) {
00383                 tmp[len] = dat;            
00384                 len ++;        
00385             }
00386         } else
00387         if (mode == 3) {
00388             // length
00389             tmp[len] = dat;            
00390             len ++;        
00391             if (len >= 4) {
00392                 tmp[len] = 0;
00393                 len = atoi(tmp);
00394                 mode ++;
00395                 break;
00396             }
00397         } else
00398         if (mode == 4) {
00399             // data
00400             if (_gs_sock[_cid].data != NULL) {
00401               _gs_sock[_cid].data->queue(dat);
00402               len  --;
00403 
00404               if (len && _gs_sock[_cid].data->isFull()) {
00405                 // buffer full
00406                 // recv interrupt
00407                 _gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available());
00408               }
00409             }
00410             if (len == 0) {
00411                 DBG("recv binary %d\r\n", _cid);
00412                 _gs_sock[_cid].received = true;
00413                 _escape = false;
00414                 _gs_mode = GSMODE_COMMAND;
00415 
00416                 if (_gs_sock[_cid].protocol == GSPROT_HTTPGET) {
00417                     // recv interrupt
00418                     if (_gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available()) == 0)
00419                         _gs_sock[_cid].received = false;
00420                 }
00421             }
00422         }
00423         break;
00424 
00425     }
00426 }
00427 
00428 void GSwifi::parseResponse () {
00429     int i;
00430     char buf[GS_CMD_SIZE];
00431 
00432     while (! _buf_cmd.isEmpty()) {
00433         // received "\n"
00434         i = 0;
00435         while ((! _buf_cmd.isEmpty()) && i < sizeof(buf)) {
00436             _buf_cmd.dequeue(&buf[i]);
00437             if (buf[i] == '\n') {
00438                 break;
00439             }
00440             i ++;
00441         }
00442         if (i == 0) continue;
00443         buf[i] = 0;
00444         DBG("parseResponse: %s\r\n", buf);
00445 
00446         parseCmdResponse(buf);
00447 
00448         if (strncmp(buf, "CONNECT ", 8) == 0 && buf[8] >= '0' && buf[8] <= 'F' && buf[9] != 0) {
00449             int cid = x2i(buf[8]);
00450             if (_gs_sock[cid].type == GSTYPE_SERVER) {
00451                 // fork (server socket)
00452                 int acid, ip1, ip2, ip3, ip4;
00453                 char *tmp = buf + 12;
00454 
00455                 acid = x2i(buf[10]);
00456                 DBG("connect %d -> %d\r\n", cid, acid);
00457                 newSock(acid, _gs_sock[cid].type, _gs_sock[cid].protocol);
00458                 _gs_sock[acid].onGsReceive = _gs_sock[cid].onGsReceive;
00459                 _gs_sock[acid].lcid = cid;
00460                 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00461                 _gs_sock[acid].host.setIp(IpAddr(ip1, ip2, ip3, ip4));
00462                 tmp = strstr(tmp, " ") + 1;
00463                 _gs_sock[acid].host.setPort(atoi(tmp));
00464                 _gs_sock[acid].onGsReceive.call(acid, 0); // event connected
00465             }
00466         } else
00467         if (strncmp(buf, "DISCONNECT ", 11) == 0) {
00468             int cid = x2i(buf[11]);
00469             DBG("disconnect %d\r\n", cid);
00470             _gs_sock[cid].connect = false;
00471             _gs_sock[cid].onGsReceive.call(cid, -1); // event disconnected
00472         } else
00473         if (strncmp(buf, "DISASSOCIATED", 13) == 0 ||
00474           strncmp(buf, "Disassociated", 13) == 0 ||
00475           strncmp(buf, "Disassociation Event", 20) == 0 ) {
00476             _connect = false;
00477             for (i = 0; i < 16; i ++) {
00478                 _gs_sock[i].connect = false;
00479             }
00480         } else
00481         if (strncmp(buf, "UnExpected Warm Boot", 20) == 0 ||
00482           strncmp(buf, "APP Reset-APP SW Reset", 22) == 0 ||
00483           strncmp(buf, "APP Reset-Wlan Except", 21) == 0 ) {
00484             DBG("disassociate\r\n");
00485             _connect = false;
00486             _status = GSSTAT_READY;
00487             _escape = false;
00488             resetResponse(GSRES_NONE);
00489             _gs_mode = GSMODE_COMMAND;
00490             for (i = 0; i < 16; i ++) {
00491                 _gs_sock[i].connect = false;
00492             }
00493         } else
00494         if (strncmp(buf, "Out of StandBy-Timer", 20) == 0 ||
00495           strncmp(buf, "Out of StandBy-Alarm", 20) == 0) {
00496             if (_status == GSSTAT_STANDBY) {
00497                 _status = GSSTAT_WAKEUP;
00498             }
00499         } else 
00500         if (strncmp(buf, "Out of Deep Sleep", 17) == 0 ) {
00501             if (_status == GSSTAT_DEEPSLEEP) {
00502                 _status = GSSTAT_READY;
00503             }
00504         }
00505         DBG("status: %d\r\n", _status);
00506     }
00507 }
00508 
00509 void GSwifi::parseCmdResponse (char *buf) {
00510     if (_gs_res == GSRES_NONE) return;
00511 
00512     if (strcmp(buf, "OK") == 0) {
00513         _gs_ok = true;
00514     } else
00515     if (strncmp(buf, "ERROR", 5) == 0) {
00516         _gs_failure = true;
00517     }
00518 
00519     switch(_gs_res) {
00520     case GSRES_NORMAL:
00521         _gs_flg = -1;
00522         break;
00523     case GSRES_WPS:
00524         if (_gs_flg == 0 && strncmp(buf, "SSID=", 5) == 0) {
00525             if (!_ssid) _ssid = (char*)malloc(strlen(&buf[5]) + 1);
00526             strcpy(_ssid, &buf[5]);
00527             _gs_flg ++;
00528         } else
00529         if (_gs_flg == 1 && strncmp(buf, "CHANNEL=", 8) == 0) {
00530             _gs_flg ++;
00531         } else
00532         if (_gs_flg == 2 && strncmp(buf, "PASSPHRASE=", 11) == 0) {
00533             if (!_pass) _pass = (char*)malloc(strlen(&buf[11]) + 1);
00534             strcpy(_pass, &buf[11]);
00535             _gs_flg = -1;
00536         }
00537         break;
00538     case GSRES_CONNECT:
00539         if (strncmp(buf, "CONNECT ", 8) == 0 && buf[9] == 0) {
00540             _cid = x2i(buf[8]);
00541             _gs_flg = -1;
00542         }
00543         break;
00544     case GSRES_DHCP:
00545         if (_gs_flg == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) {
00546             _gs_flg ++;
00547         } else
00548         if (_gs_flg == 1) {
00549             int ip1, ip2, ip3, ip4;
00550             char *tmp = buf + 1;
00551             sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00552             _ipaddr = IpAddr(ip1, ip2, ip3, ip4);
00553             tmp = strstr(tmp, ":") + 2;
00554             sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00555             _netmask = IpAddr(ip1, ip2, ip3, ip4);
00556             tmp = strstr(tmp, ":") + 2;
00557             sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00558             _gateway = IpAddr(ip1, ip2, ip3, ip4);
00559             _gs_flg = -1;
00560         }
00561         break;
00562     case GSRES_MACADDRESS:
00563         if (buf[2] == ':' && buf[5] == ':') {
00564             int mac1, mac2, mac3, mac4, mac5, mac6;
00565             sscanf(buf, "%x:%x:%x:%x:%x:%x", &mac1, &mac2, &mac3, &mac4, &mac5, &mac6);
00566             _mac[0] = mac1;
00567             _mac[1] = mac2;
00568             _mac[2] = mac3;
00569             _mac[3] = mac4;
00570             _mac[4] = mac5;
00571             _mac[5] = mac6;
00572             _gs_flg = -1;
00573         }
00574         break;
00575     case GSRES_DNSLOOKUP:
00576         if (strncmp(buf, "IP:", 3) == 0) {
00577             int ip1, ip2, ip3, ip4;
00578             sscanf(&buf[3], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
00579             _resolv = IpAddr(ip1, ip2, ip3, ip4);
00580             _gs_flg = -1;
00581         }
00582         break;
00583     case GSRES_HTTP:
00584         if (buf[0] >= '0' && buf[0] <= 'F' && buf[1] == 0) {
00585             _cid = x2i(buf[0]);
00586             _gs_flg = -1;
00587         }
00588         break;
00589     case GSRES_RSSI:
00590         if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) {
00591             _rssi = atoi(buf);
00592             _gs_flg = -1;
00593         }
00594         break;
00595     case GSRES_TIME:
00596         if (buf[0] >= '0' && buf[0] <= '9') {
00597             int year, month, day, hour, min, sec;
00598             struct tm t;
00599             sscanf(buf, "%d/%d/%d,%d:%d:%d", &day, &month, &year, &hour, &min, &sec);
00600             t.tm_sec = sec;
00601             t.tm_min = min;
00602             t.tm_hour = hour;
00603             t.tm_mday = day;
00604             t.tm_mon = month - 1;
00605             t.tm_year = year - 1900;   
00606             _time = mktime(&t);            
00607             _gs_flg = -1;
00608         }
00609         break;
00610     case GSRES_STATUS:
00611         if (_gs_flg == 0 && strncmp(buf, "NOT ASSOCIATED", 14) == 0) {
00612             _connect = false;
00613             for (int i = 0; i < 16; i ++) {
00614                 _gs_sock[i].connect = false;
00615             }
00616             _gs_flg = -1;
00617         }
00618         if (_gs_flg == 0 && strncmp(buf, "MODE:", 5) == 0) {
00619             _gs_flg ++;
00620         } else
00621         if (_gs_flg == 1 && strncmp(buf, "BSSID:", 6) == 0) {
00622             char *tmp = strstr(buf, "SECURITY:") + 2;
00623             if (strncmp(tmp, "WEP (OPEN)", 10) == NULL) {
00624                 _sec = GSSEC_OPEN;
00625             } else
00626             if (strncmp(tmp, "WEP (SHARED)", 12) == NULL) {
00627                 _sec = GSSEC_WEP;
00628             } else
00629             if (strncmp(tmp, "WPA-PERSONAL", 12) == NULL) {
00630                 _sec = GSSEC_WPA_PSK;
00631             } else
00632             if (strncmp(tmp, "WPA2-PERSONAL", 13) == NULL) {
00633                 _sec = GSSEC_WPA2_PSK;
00634             }
00635             _gs_flg = -1;
00636         }
00637         break;        
00638     }
00639 
00640     return;
00641 }
00642 
00643 void GSwifi::poll () {
00644     int i, j;
00645     static int t = 0;
00646     static Timer timer;
00647 
00648     for (i = 0; i < 16; i ++) {
00649         if (_gs_sock[i].connect && _gs_sock[i].received) {
00650           if (_gs_sock[i].data && ! _gs_sock[i].data->isEmpty()) {
00651             // recv interrupt
00652             _gs_sock[i].received = false;
00653             for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) {
00654                 if (! _gs_sock[i].connect || _gs_sock[i].data->isEmpty()) break;
00655                 _gs_sock[i].onGsReceive.call(i, _gs_sock[i].data->available());
00656             }
00657           }
00658         }
00659     }
00660 
00661     if (_ssid && ! _connect)
00662       if (t == 0 || timer.read() > _reconnect) {
00663         DBG("reconnect\r\n");
00664         if (reconnect()) {
00665             timer.reset();
00666             timer.start();
00667             t = 1;
00668         }
00669     }
00670 }
00671 
00672 int GSwifi::command (const char *cmd, GSRESPONCE res, int timeout) {
00673     int i;
00674 
00675     if (acquireUart()) return -1;
00676 
00677     if (cmd == NULL) {
00678         // dummy CR+LF
00679         _gs_putc('\r');
00680         _gs_putc('\n');
00681         releaseUart();
00682         wait_ms(100);
00683         _buf_cmd.flush();
00684         return 0;
00685     }
00686 
00687     resetResponse(res);
00688     for (i = 0; i < strlen(cmd); i ++) {
00689         _gs_putc(cmd[i]);
00690     }
00691     _gs_putc('\r');
00692     _gs_putc('\n');
00693     releaseUart();
00694     DBG("command: %s\r\n", cmd);
00695     if (strlen(cmd) == 0) return 0;
00696 
00697     return waitResponse(timeout);
00698 }
00699 
00700 void GSwifi::resetResponse (GSRESPONCE res) {
00701     _gs_ok = false;
00702     _gs_failure = false;
00703     _gs_flg = 0;
00704     _gs_res = res;
00705 }
00706 
00707 int GSwifi::waitResponse (int ms) {
00708     Timer timeout;
00709 
00710     if (! ms) return 0;
00711 
00712     timeout.start();
00713     for (;;) {
00714         if (timeout.read_ms() > ms) {
00715             DBG("timeout\r\n");
00716             break;
00717         }
00718         if (_gs_ok && (_gs_flg == -1 || _gs_res == GSRES_NONE)) {
00719             timeout.stop();
00720             _gs_res = GSRES_NONE;
00721             return 0;
00722         }
00723         if (_gs_failure) break;
00724     }
00725     timeout.stop();
00726     _gs_res = GSRES_NONE;
00727     return -1;
00728 }
00729 
00730 int GSwifi::connect (GSSECURITY sec, const char *ssid, const char *pass, int dhcp, int reconnect, char *name) {
00731     int r;
00732     char cmd[GS_CMD_SIZE];
00733     
00734     if (_connect || _status != GSSTAT_READY) return -1;
00735 
00736     command(NULL, GSRES_NORMAL);
00737     if (command("ATE0", GSRES_NORMAL)) return -1;
00738     if (_rts) {
00739         command("AT&R1", GSRES_NORMAL);
00740     }
00741     if (getMacAddress(_mac)) return -1;
00742 #ifdef GS_BULK
00743     command("AT+BDATA=1", GSRES_NORMAL);
00744 #endif
00745 
00746     disconnect();
00747     command("AT+WM=0", GSRES_NORMAL); // infrastructure
00748     wait_ms(100);
00749     if (dhcp && sec != GSSEC_WPS_BUTTON) {
00750         if (name) {
00751             sprintf(cmd, "AT+NDHCP=1,%s", name);
00752         } else {
00753             strcpy(cmd, "AT+NDHCP=1," GS_DHCPNAME);
00754         }
00755         command(cmd, GSRES_NORMAL);
00756     } else {
00757         command("AT+NDHCP=0", GSRES_NORMAL);
00758     }
00759 
00760     switch (sec) {
00761     case GSSEC_NONE:
00762     case GSSEC_OPEN:
00763     case GSSEC_WEP:
00764         sprintf(cmd, "AT+WAUTH=%d", sec);
00765         command(cmd, GSRES_NORMAL);
00766         if (sec != GSSEC_NONE) {
00767             sprintf(cmd, "AT+WWEP1=%s", pass);
00768             command(cmd, GSRES_NORMAL);
00769             wait_ms(100);
00770         }
00771         sprintf(cmd, "AT+WA=%s", ssid);
00772         r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
00773         if (r) {
00774             DBG("retry\r\n");
00775             wait_ms(1000);
00776             r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
00777         }
00778         break;
00779     case GSSEC_WPA_PSK:
00780     case GSSEC_WPA_ENT:
00781     case GSSEC_WPA2_PSK:
00782     case GSSEC_WPA2_ENT:
00783         command("AT+WAUTH=0", GSRES_NORMAL);
00784 //        sprintf(cmd, "AT+WWPA=%s", pass);
00785         sprintf(cmd, "AT+WPAPSK=%s,%s", ssid, pass);
00786         command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
00787         wait_ms(100);
00788         sprintf(cmd, "AT+WA=%s", ssid);
00789         r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
00790         if (r) {
00791             DBG("retry\r\n");
00792             wait_ms(1000);
00793             r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
00794         }
00795         break;
00796     case GSSEC_WPS_BUTTON:
00797         command("AT+WAUTH=0", GSRES_NORMAL);
00798         r = command("AT+WWPS=1", GSRES_WPS, GS_TIMEOUT2);
00799         if (r) break;
00800         if (dhcp) {
00801             r = setAddress(name);
00802         }
00803         break;
00804     case GSSEC_WPS_PIN:
00805         command("AT+WAUTH=0", GSRES_NORMAL);
00806         sprintf(cmd, "AT+WWPS=2,%s", pass);
00807         r = command(cmd, GSRES_WPS, GS_TIMEOUT2);
00808         if (r) break;
00809         if (dhcp) {
00810             r = setAddress(name);
00811         }
00812         break;
00813     default:
00814         DBG("Can't use security\r\n");
00815         r = -1;
00816         break;
00817     }
00818 
00819     if (r == 0 && !dhcp) {
00820         sprintf(cmd, "AT+DNSSET=%d.%d.%d.%d",
00821             _gateway[0], _gateway[1], _gateway[2], _gateway[3]);
00822         command(cmd, GSRES_NORMAL);
00823     }
00824 
00825     if (r == 0) {
00826         _connect = true;
00827         _reconnect = reconnect * 1000;
00828         _sec = sec;
00829         _dhcp = dhcp;
00830         if (_reconnect && ssid) {
00831             if (!_ssid) _ssid = (char*)malloc(strlen(ssid) + 1);
00832             strcpy(_ssid, ssid);
00833         }
00834         if (_reconnect && pass) {
00835             if (!_pass) _pass = (char*)malloc(strlen(pass) + 1);
00836             strcpy(_pass, pass);
00837         }
00838     }
00839     return r;
00840 }
00841 
00842 int GSwifi::adhock (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask) {
00843     int r;
00844     char cmd[GS_CMD_SIZE];
00845 
00846     if (_connect || _status != GSSTAT_READY) return -1;
00847 
00848     command(NULL, GSRES_NORMAL);
00849     if (command("ATE0", GSRES_NORMAL)) return -1;
00850     if (_rts) {
00851         command("AT&R1", GSRES_NORMAL);
00852     }
00853     if (getMacAddress(_mac)) return -1;
00854 #ifdef GS_BULK
00855     command("AT+BDATA=1", GSRES_NORMAL);
00856 #endif
00857 
00858     disconnect();
00859     command("AT+WM=1", GSRES_NORMAL); // adhock
00860     wait_ms(100);
00861     command("AT+NDHCP=0", GSRES_NORMAL);
00862     setAddress(ipaddr, netmask, ipaddr, ipaddr);
00863 
00864     switch (sec) {
00865     case GSSEC_NONE:
00866     case GSSEC_OPEN:
00867     case GSSEC_WEP:
00868         sprintf(cmd, "AT+WAUTH=%d", sec);
00869         command(cmd, GSRES_NORMAL);
00870         if (sec != GSSEC_NONE) {
00871             sprintf(cmd, "AT+WWEP1=%s", pass);
00872             command(cmd, GSRES_NORMAL);
00873             wait_ms(100);
00874         }
00875         sprintf(cmd, "AT+WA=%s", ssid);
00876         r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
00877         break;
00878     default:
00879         DBG("Can't use security\r\n");
00880         r = -1;
00881         break;
00882     }
00883 
00884     if (r == 0) _connect = true;
00885     return r;
00886 }
00887 
00888 int GSwifi::limitedap (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask, char *dns) {
00889     int r;
00890     char cmd[GS_CMD_SIZE];
00891     
00892     if (_connect || _status != GSSTAT_READY) return -1;
00893 
00894     command(NULL, GSRES_NORMAL);
00895     if (command("ATE0", GSRES_NORMAL)) return -1;
00896     if (_rts) {
00897         command("AT&R1", GSRES_NORMAL);
00898     }
00899     if (getMacAddress(_mac)) return -1;
00900 #ifdef GS_BULK
00901     command("AT+BDATA=1", GSRES_NORMAL);
00902 #endif
00903 
00904     disconnect();
00905     command("AT+WM=2", GSRES_NORMAL); // limited ap
00906     wait_ms(100);
00907     command("AT+NDHCP=0", GSRES_NORMAL);
00908     setAddress(ipaddr, netmask, ipaddr, ipaddr);
00909     if (command("AT+DHCPSRVR=1", GSRES_NORMAL)) return -1;
00910     if (dns) {
00911         sprintf(cmd, "AT+DNS=1,%s", dns);
00912     } else {
00913         strcpy(cmd, "AT+DNS=1," GS_DNSNAME);
00914     }
00915     if (command(cmd, GSRES_NORMAL)) return -1;
00916 
00917     switch (sec) {
00918     case GSSEC_NONE:
00919     case GSSEC_OPEN:
00920     case GSSEC_WEP:
00921         sprintf(cmd, "AT+WAUTH=%d", sec);
00922         command(cmd, GSRES_NORMAL);
00923         if (sec != GSSEC_NONE) {
00924             sprintf(cmd, "AT+WWEP1=%s", pass);
00925             command(cmd, GSRES_NORMAL);
00926             wait_ms(100);
00927         }
00928         sprintf(cmd, "AT+WA=%s", ssid);
00929         r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
00930         break;
00931     default:
00932         DBG("Can't use security\r\n");
00933         r = -1;
00934         break;
00935     }
00936 
00937     if (r == 0) _connect = true;
00938     return r;
00939 }
00940 
00941 int GSwifi::disconnect () {
00942     int i;
00943 
00944     _connect = false;
00945     for (i = 0; i < 16; i ++) {
00946         _gs_sock[i].connect = false;
00947     }
00948     command("AT+NCLOSEALL", GSRES_NORMAL);
00949     command("AT+WD", GSRES_NORMAL);
00950     command("AT+NDHCP=0", GSRES_NORMAL);
00951     wait_ms(100);
00952     return 0;
00953 }
00954 
00955 int GSwifi::reconnect () {
00956     int r;
00957     char cmd[GS_CMD_SIZE];
00958     
00959     if (_connect || _status != GSSTAT_READY) return -1;
00960     if (!_ssid) return -1;
00961 
00962     switch (_sec) {
00963     case GSSEC_WPS_BUTTON:
00964     case GSSEC_WPS_PIN:
00965         sprintf(cmd, "AT+WPAPSK=%s,%s", _ssid, _pass);
00966         command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
00967         wait_ms(100);
00968     case GSSEC_NONE:
00969     case GSSEC_OPEN:
00970     case GSSEC_WEP:
00971     case GSSEC_WPA_PSK:
00972     case GSSEC_WPA_ENT:
00973     case GSSEC_WPA2_PSK:
00974     case GSSEC_WPA2_ENT:
00975         if (_dhcp) {
00976             command("AT+NDHCP=1," GS_DHCPNAME, GSRES_NORMAL);
00977         }
00978         sprintf(cmd, "AT+WA=%s", _ssid);
00979         r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
00980         break;
00981     default:
00982         DBG("Can't use security\r\n");
00983         r = -1;
00984         break;
00985     }
00986 
00987     if (r == 0) _connect = true;
00988     return r;
00989 }
00990 
00991 int GSwifi::setAddress (char *name) {
00992     char cmd[GS_CMD_SIZE];
00993 
00994     if (name) {
00995         sprintf(cmd, "AT+NDHCP=1,%s", name);
00996     } else {
00997         strcpy(cmd, "AT+NDHCP=1," GS_DHCPNAME);
00998     }
00999     if (command(cmd, GSRES_DHCP, GS_TIMEOUT2)) return -1;
01000     if (_ipaddr.isNull()) return -1;
01001     return 0;
01002 }
01003 
01004 int GSwifi::setAddress (IpAddr ipaddr, IpAddr netmask, IpAddr gateway, IpAddr nameserver) {
01005     int r;
01006     char cmd[GS_CMD_SIZE];
01007 
01008     command("AT+NDHCP=0", GSRES_NORMAL);
01009     wait_ms(100);
01010 
01011     sprintf(cmd, "AT+NSET=%d.%d.%d.%d,%d.%d.%d.%d,%d.%d.%d.%d",
01012         ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3],
01013         netmask[0], netmask[1], netmask[2], netmask[3],
01014         gateway[0], gateway[1], gateway[2], gateway[3]);
01015     r = command(cmd, GSRES_NORMAL);
01016     if (r) return -1;
01017     _ipaddr = ipaddr;
01018     _netmask = netmask;
01019     _gateway = gateway;
01020 
01021     if (ipaddr != nameserver) {
01022         sprintf(cmd, "AT+DNSSET=%d.%d.%d.%d",
01023             nameserver[0], nameserver[1], nameserver[2], nameserver[3]);
01024         r = command(cmd, GSRES_NORMAL);
01025     }
01026     return r;
01027 }
01028 
01029 int GSwifi::getAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) {
01030     ipaddr = _ipaddr;
01031     netmask = _netmask;
01032     gateway = _gateway;
01033     nameserver = _nameserver;
01034     return 0;
01035 }
01036 
01037 int GSwifi::getMacAddress (char *mac) {
01038 
01039     command("AT+NMAC=?", GSRES_MACADDRESS);
01040     if (_mac[0] || _mac[1] || _mac[2] || _mac[3] || _mac[4] || _mac[5]) {
01041         memcpy(mac, _mac, 6);
01042         return 0;
01043     }
01044     return -1;
01045 }
01046 
01047 int GSwifi::getHostByName (const char* name, IpAddr &addr) {
01048     char cmd[GS_CMD_SIZE];
01049 
01050     if (! _connect || _status != GSSTAT_READY) return -1;
01051 
01052     sprintf(cmd, "AT+DNSLOOKUP=%s", name);
01053     if (command(cmd, GSRES_DNSLOOKUP)) return -1;
01054 
01055     addr = _resolv;
01056     return 0;
01057 }
01058 
01059 int GSwifi::getHostByName (Host &host) {
01060     char cmd[GS_CMD_SIZE];
01061 
01062     if (! _connect || _status != GSSTAT_READY) return -1;
01063 
01064     sprintf(cmd, "AT+DNSLOOKUP=%s", host.getName());
01065     if (command(cmd, GSRES_DNSLOOKUP)) return -1;
01066 
01067     host.setIp(_resolv);
01068     return 0;
01069 }
01070 
01071 bool GSwifi::isConnected () {
01072 /*
01073     if (_status == GSSTAT_READY) {
01074         command("AT+WSTATUS", GSRES_STATUS);
01075     }
01076 */
01077     return _connect;
01078 }
01079 
01080 GSwifi::GSSTATUS GSwifi::getStatus () {
01081     return _status;
01082 }
01083 
01084 int GSwifi::getRssi () {
01085     if (command("AT+WRSSI=?", GSRES_RSSI)) {
01086         return 0;
01087     }
01088     return _rssi;
01089 }
01090 
01091 int GSwifi::setBaud (int baud) {
01092     char cmd[GS_CMD_SIZE];
01093 
01094     if (_status != GSSTAT_READY || acquireUart()) return -1;
01095 
01096     _baud = baud;
01097     sprintf(cmd, "ATB=%d\r\n", _baud);
01098     _gs_puts(cmd);
01099     releaseUart();
01100     wait_ms(100);
01101     _gs.baud(_baud);
01102     _buf_cmd.flush();
01103     return 0;
01104 }
01105 
01106 int GSwifi::setRegion (int reg) {
01107     char cmd[GS_CMD_SIZE];
01108 
01109     if (_status != GSSTAT_READY) return -1;
01110 
01111     sprintf(cmd, "AT+WREGDOMAIN=%d", reg);
01112     return command(cmd, GSRES_NORMAL);
01113 }
01114 
01115 #ifndef GS_LIB_TINY
01116 int GSwifi::setRFPower (int power) {
01117     char cmd[GS_CMD_SIZE];
01118 
01119     if (power < 0 || power > 7) return -1;
01120 
01121     sprintf(cmd, "AT+WP=%d", power);
01122     return command(cmd, GSRES_NORMAL);
01123 }
01124 
01125 int GSwifi::powerSave (int active, int save) {
01126     char cmd[GS_CMD_SIZE];
01127 
01128     if (_status != GSSTAT_READY) return -1;
01129 
01130     sprintf(cmd, "AT+WRXACTIVE=%d", active);
01131     command(cmd, GSRES_NORMAL);
01132     sprintf(cmd, "AT+WRXPS=%d", save);
01133     return command(cmd, GSRES_NORMAL);
01134 }
01135 
01136 int GSwifi::standby (int msec) {
01137     int i;
01138     char cmd[GS_CMD_SIZE];
01139 
01140     if (_status != GSSTAT_READY && _status != GSSTAT_WAKEUP) return -1;
01141 
01142     if (_status == GSSTAT_READY) {
01143 //        command("AT+WRXACTIVE=0", GSRES_NORMAL);
01144         command("AT+STORENWCONN", GSRES_NORMAL, 100);
01145     } else {
01146         command("ATE0", GSRES_NORMAL);
01147         if (_rts) {
01148             command("AT&R1", GSRES_NORMAL);
01149         }
01150     }
01151     for (i = 0; i < 16; i ++) {
01152         _gs_sock[i].connect = false;
01153     }
01154     _status = GSSTAT_STANDBY;
01155     sprintf(cmd, "AT+PSSTBY=%d,0,0,0", msec); // go standby
01156     return command(cmd, GSRES_NORMAL, 0);
01157 }
01158 
01159 int GSwifi::wakeup () {
01160 
01161     if (_status == GSSTAT_STANDBY && _alarm != NULL) {
01162         Timer timeout;
01163         _alarm->output(); // low
01164         _alarm->write(0);
01165         timeout.start();
01166         while (_status != GSSTAT_WAKEUP && timeout.read() < GS_TIMEOUT) {
01167             poll();
01168         }
01169         timeout.stop();
01170         _alarm->input(); // high
01171         _alarm->mode(PullUp);
01172     }
01173 
01174     if (_status == GSSTAT_WAKEUP) {
01175         _status = GSSTAT_READY;
01176         command("ATE0", GSRES_NORMAL);
01177         if (_rts) {
01178             command("AT&R1", GSRES_NORMAL);
01179         }
01180 #ifdef GS_BULK
01181         command("AT+BDATA=1", GSRES_NORMAL);
01182 #endif
01183         int r = command("AT+RESTORENWCONN", GSRES_NORMAL);
01184         wait_ms(100);
01185 //        return command("AT+WRXACTIVE=1", GSRES_NORMAL);
01186         return r;
01187     } else
01188     if (_status == GSSTAT_DEEPSLEEP) {
01189         _status = GSSTAT_READY;
01190         return command("AT", GSRES_NORMAL);
01191     }
01192     return -1;
01193 }
01194 
01195 int GSwifi::deepSleep () {
01196 
01197     if (_status != GSSTAT_READY) return -1;
01198 
01199     _status = GSSTAT_DEEPSLEEP;
01200     return command("AT+PSDPSLEEP", GSRES_NORMAL, 0); // go deep sleep
01201 }
01202 
01203 int GSwifi::ntpdate (Host host, int sec) {
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 
01214     if (sec) {
01215         sprintf(cmd, "AT+NTIMESYNC=1,%d.%d.%d.%d,%d,1,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3],
01216           GS_TIMEOUT / 1000, sec);
01217     } else {
01218         sprintf(cmd, "AT+NTIMESYNC=1,%d.%d.%d.%d,%d,0", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3],
01219           GS_TIMEOUT / 1000);
01220     }
01221     return command(cmd, GSRES_NORMAL);
01222 }
01223 
01224 int GSwifi::setTime (time_t time) {
01225     char cmd[GS_CMD_SIZE];
01226     struct tm *t;
01227 
01228     if (_status != GSSTAT_READY) return -1;
01229 
01230     t = localtime(&time);
01231     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);
01232     return command(cmd, GSRES_NORMAL);
01233 }
01234 
01235 time_t GSwifi::getTime () {
01236 
01237     if (command("AT+GETTIME=?", GSRES_TIME)) {
01238         return 0;
01239     }
01240     return _time;
01241 }
01242 
01243 int GSwifi::gpioOut (int port, int out) {
01244     char cmd[GS_CMD_SIZE];
01245 
01246     if (_status != GSSTAT_READY) return -1;
01247 
01248     sprintf(cmd, "AT+DGPIO=%d,%d", port, out);
01249     return command(cmd, GSRES_NORMAL);
01250 }
01251 
01252 int GSwifi::certAdd (const char *name, const char *cert, int len) {
01253     int i;
01254     char cmd[GS_CMD_SIZE];
01255 
01256     if (! _connect || _status != GSSTAT_READY) return -1;
01257 
01258     sprintf(cmd, "AT+TCERTADD=%s,1,%d,1", name, len);  // Hex, ram
01259     command(cmd, GSRES_NORMAL);
01260     
01261     resetResponse(GSRES_NORMAL);
01262     _gs_putc(0x1b);
01263     _gs_putc('W');
01264     for (i = 0; i < len; i ++) {
01265         _gs_putc(cert[i]);
01266     }
01267     return waitResponse(GS_TIMEOUT);
01268 }
01269 
01270 int GSwifi::provisioning (char *user, char *pass) {
01271     char cmd[GS_CMD_SIZE];
01272 
01273     if (_status != GSSTAT_READY) return -1;
01274 
01275     sprintf(cmd, "AT+WEBPROV=%s,%s", user, pass);
01276     return command(cmd, GSRES_NORMAL);
01277 }
01278 #endif
01279 
01280 int GSwifi::from_hex (int ch) {
01281   return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
01282 }
01283 
01284 int GSwifi::to_hex (int code) {
01285   static char hex[] = "0123456789abcdef";
01286   return hex[code & 15];
01287 }
01288 
01289 int GSwifi::x2i (char c) {
01290     if (c >= '0' && c <= '9') {
01291         return c - '0';
01292     } else
01293     if (c >= 'A' && c <= 'F') {
01294         return c - 'A' + 10;
01295     } else
01296     if (c >= 'a' && c <= 'f') {
01297         return c - 'a' + 10;
01298     }
01299     return 0;
01300 }
01301 
01302 char GSwifi::i2x (int i) {
01303     if (i >= 0 && i <= 9) {
01304         return i + '0';
01305     } else
01306     if (i >= 10 && i <= 15) {
01307         return i - 10 + 'A';
01308     }
01309     return '0';
01310 }
01311 
01312 
01313 #ifdef DEBUG
01314 // for test
01315 void GSwifi::dump () {
01316     int i;
01317     
01318     DBG("GS mode=%d, escape=%d, cid=%d\r\n", _gs_mode, _escape, _cid);
01319     for (i = 0; i < 16; i ++) {
01320         DBG("[%d] ", i);
01321         DBG("connect=%d, type=%d, protocol=%d, len=%d\r\n", _gs_sock[i].connect, _gs_sock[i].type, _gs_sock[i].protocol, _gs_sock[i].data->available());
01322         DBG("  %x, %x\r\n", &_gs_sock[i], _gs_sock[i].data);
01323 #ifdef GS_ENABLE_HTTPD
01324         if (_gs_sock[i].protocol == GSPROT_HTTPD) {
01325             DBG("  mode=%d, type=%d, len=%d\r\n", i, _httpd[i].mode, _httpd[i].type, _httpd[i].len);
01326             DBG("  %x, %x\r\n", &_httpd[i], _httpd[i].buf);
01327         }
01328 #endif
01329     }
01330 }
01331 
01332 void GSwifi::test () {
01333 /*
01334     command(NULL, GSRES_NORMAL);
01335     wait_ms(100);
01336     command("AT+NCLOSEALL", GSRES_NORMAL);
01337     _connect = true;
01338 */
01339     command("AT+WRXACTIVE=1", GSRES_NORMAL);
01340 }
01341 
01342 int GSwifi::getc() {
01343     char c;
01344     if (! _buf_cmd.isEmpty()) {
01345         _buf_cmd.dequeue(&c);
01346     }
01347 /*
01348     } else
01349     if (_gs_sock[0].data != NULL) {
01350         _gs_sock[0].data->dequeue(&c);
01351     }
01352 */
01353     return c;
01354 }
01355 
01356 void GSwifi::putc(char c) {
01357     _gs_putc(c);
01358 }
01359 
01360 int GSwifi::readable() {
01361     return ! _buf_cmd.isEmpty();
01362 //    return _buf_cmd.use() || (_gs_sock[0].data != NULL && _gs_sock[0].data->use());
01363 }
01364 #endif