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

Dependents:   GSwifi_httpd GSwifi_websocket GSwifi_tcpclient GSwifi_tcpserver ... more

Fork of GSwifi by gs fan

GainSpan Wi-Fi library

The GS1011 is an ultra low power 802.11b wireless module from GainSpan.

see: http://mbed.org/users/gsfan/notebook/gainspan_wifi/

/media/uploads/gsfan/gs_im_002.jpg /media/uploads/gsfan/gs1011m_2.jpg

ゲインスパン Wi-Fi モジュール ライブラリ

ゲインスパン社の低電力 Wi-Fiモジュール(無線LAN) GS1011 シリーズ用のライブラリです。

解説: http://mbed.org/users/gsfan/notebook/gainspan_wifi/

Committer:
gsfan
Date:
Wed Jun 26 02:39:59 2013 +0000
Revision:
37:e61ea8267415
Parent:
36:a70b11e1560f
Child:
38:dfc31d58fa1d
fix uart lock; sort functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gsfan 25:f6e5622d2930 1 /* Copyright (C) 2013 gsfan, MIT License
gsfan 25:f6e5622d2930 2 *
gsfan 25:f6e5622d2930 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
gsfan 25:f6e5622d2930 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
gsfan 25:f6e5622d2930 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
gsfan 25:f6e5622d2930 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
gsfan 25:f6e5622d2930 7 * furnished to do so, subject to the following conditions:
gsfan 25:f6e5622d2930 8 *
gsfan 25:f6e5622d2930 9 * The above copyright notice and this permission notice shall be included in all copies or
gsfan 25:f6e5622d2930 10 * substantial portions of the Software.
gsfan 25:f6e5622d2930 11 *
gsfan 25:f6e5622d2930 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
gsfan 25:f6e5622d2930 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
gsfan 25:f6e5622d2930 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
gsfan 25:f6e5622d2930 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
gsfan 25:f6e5622d2930 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
gsfan 0:2f6062c6d018 17 */
gsfan 0:2f6062c6d018 18 /** @file
gsfan 0:2f6062c6d018 19 * @brief Gainspan wi-fi module library for mbed
gsfan 0:2f6062c6d018 20 * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
gsfan 0:2f6062c6d018 21 */
gsfan 0:2f6062c6d018 22
gsfan 0:2f6062c6d018 23 #include "mbed.h"
gsfan 0:2f6062c6d018 24 #include "GSwifi.h"
gsfan 0:2f6062c6d018 25
gsfan 0:2f6062c6d018 26
gsfan 37:e61ea8267415 27 GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_reset, PinName p_alarm, int baud)
gsfan 37:e61ea8267415 28 : _gs(p_tx, p_rx), _reset(p_reset), _buf_cmd(GS_CMD_SIZE) {
gsfan 25:f6e5622d2930 29
gsfan 25:f6e5622d2930 30 if (p_alarm != NC) {
gsfan 26:b347ee3a1087 31 _alarm = new DigitalInOut(p_alarm);
gsfan 26:b347ee3a1087 32 _alarm->output(); // low
gsfan 26:b347ee3a1087 33 _alarm->write(0);
gsfan 25:f6e5622d2930 34 } else {
gsfan 25:f6e5622d2930 35 _alarm = NULL;
gsfan 25:f6e5622d2930 36 }
gsfan 0:2f6062c6d018 37
gsfan 26:b347ee3a1087 38 _reset.output(); // low
gsfan 26:b347ee3a1087 39 _reset = 0;
gsfan 35:515ec79792d3 40 _baud = baud;
gsfan 35:515ec79792d3 41 if (_baud) _gs.baud(_baud);
gsfan 0:2f6062c6d018 42 _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
gsfan 0:2f6062c6d018 43 _rts = false;
gsfan 36:a70b11e1560f 44 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
gsfan 36:a70b11e1560f 45 _uart = LPC_UART1;
gsfan 36:a70b11e1560f 46 #elif defined(TARGET_LPC11U24)
gsfan 36:a70b11e1560f 47 _uart = LPC_USART;
gsfan 36:a70b11e1560f 48 #endif
gsfan 25:f6e5622d2930 49
gsfan 35:515ec79792d3 50 wait_ms(100);
gsfan 25:f6e5622d2930 51 reset();
gsfan 0:2f6062c6d018 52 }
gsfan 0:2f6062c6d018 53
gsfan 37:e61ea8267415 54 GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts, PinName p_reset, PinName p_alarm, int baud)
gsfan 37:e61ea8267415 55 : _gs(p_tx, p_rx), _reset(p_reset), _buf_cmd(GS_CMD_SIZE) {
gsfan 25:f6e5622d2930 56
gsfan 25:f6e5622d2930 57 if (p_alarm != NC) {
gsfan 26:b347ee3a1087 58 _alarm = new DigitalInOut(p_alarm);
gsfan 26:b347ee3a1087 59 _alarm->output(); // low
gsfan 26:b347ee3a1087 60 _alarm->write(0);
gsfan 25:f6e5622d2930 61 } else {
gsfan 25:f6e5622d2930 62 _alarm = NULL;
gsfan 25:f6e5622d2930 63 }
gsfan 0:2f6062c6d018 64
gsfan 26:b347ee3a1087 65 _reset.output(); // low
gsfan 26:b347ee3a1087 66 _reset = 0;
gsfan 35:515ec79792d3 67 _baud = baud;
gsfan 35:515ec79792d3 68 if (_baud) _gs.baud(_baud);
gsfan 0:2f6062c6d018 69 _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
gsfan 33:b5a5a1e6325f 70 _rts = false;
gsfan 0:2f6062c6d018 71 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
gsfan 36:a70b11e1560f 72 _uart = LPC_UART1;
gsfan 0:2f6062c6d018 73 if (p_cts == p12) { // CTS input (P0_17)
gsfan 36:a70b11e1560f 74 _uart->MCR |= (1<<7); // CTSEN
gsfan 0:2f6062c6d018 75 LPC_PINCON->PINSEL1 &= ~(3 << 2);
gsfan 0:2f6062c6d018 76 LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS
gsfan 0:2f6062c6d018 77 }
gsfan 0:2f6062c6d018 78 if (p_rts == P0_22) { // RTS output (P0_22)
gsfan 36:a70b11e1560f 79 _uart->MCR |= (1<<6); // RTSEN
gsfan 0:2f6062c6d018 80 LPC_PINCON->PINSEL1 &= ~(3 << 12);
gsfan 0:2f6062c6d018 81 LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS
gsfan 0:2f6062c6d018 82 _rts = true;
gsfan 0:2f6062c6d018 83 }
gsfan 0:2f6062c6d018 84 #elif defined(TARGET_LPC11U24)
gsfan 36:a70b11e1560f 85 _uart = LPC_USART;
gsfan 0:2f6062c6d018 86 if (p_cts == p21) { // CTS input (P0_7)
gsfan 36:a70b11e1560f 87 _uart->MCR |= (1<<7); // CTSEN
gsfan 0:2f6062c6d018 88 LPC_IOCON->PIO0_7 &= ~0x07;
gsfan 0:2f6062c6d018 89 LPC_IOCON->PIO0_7 |= 0x01; // UART CTS
gsfan 0:2f6062c6d018 90 }
gsfan 0:2f6062c6d018 91 if (p_rts == p22) { // RTS output (P0_17)
gsfan 36:a70b11e1560f 92 _uart->MCR |= (1<<6); // RTSEN
gsfan 0:2f6062c6d018 93 LPC_IOCON->PIO0_17 &= ~0x07;
gsfan 0:2f6062c6d018 94 LPC_IOCON->PIO0_17 |= 0x01; // UART RTS
gsfan 0:2f6062c6d018 95 _rts = true;
gsfan 0:2f6062c6d018 96 }
gsfan 36:a70b11e1560f 97 #elif defined(TARGET_KL25Z)
gsfan 36:a70b11e1560f 98 _uart = NULL;
gsfan 0:2f6062c6d018 99 #endif
gsfan 25:f6e5622d2930 100
gsfan 35:515ec79792d3 101 wait_ms(100);
gsfan 25:f6e5622d2930 102 reset();
gsfan 25:f6e5622d2930 103 }
gsfan 25:f6e5622d2930 104
gsfan 25:f6e5622d2930 105 void GSwifi::reset () {
gsfan 26:b347ee3a1087 106
gsfan 26:b347ee3a1087 107 if (_alarm != NULL) {
gsfan 26:b347ee3a1087 108 _alarm->output(); // low
gsfan 26:b347ee3a1087 109 _alarm->write(0);
gsfan 26:b347ee3a1087 110 wait_ms(10);
gsfan 26:b347ee3a1087 111 _alarm->input(); // high
gsfan 28:fbba4c58d14c 112 _alarm->mode(PullUp);
gsfan 26:b347ee3a1087 113 wait_ms(10);
gsfan 26:b347ee3a1087 114 }
gsfan 26:b347ee3a1087 115 _reset.output(); // low
gsfan 26:b347ee3a1087 116 _reset = 0;
gsfan 26:b347ee3a1087 117
gsfan 35:515ec79792d3 118 memset(&_gs_sock, 0, sizeof(_gs_sock));
gsfan 35:515ec79792d3 119 memset(&_mac, 0, sizeof(_mac));
gsfan 25:f6e5622d2930 120 _connect = false;
gsfan 25:f6e5622d2930 121 _status = GSSTAT_READY;
gsfan 25:f6e5622d2930 122 _escape = 0;
gsfan 26:b347ee3a1087 123 resetResponse(GSRES_NONE);
gsfan 25:f6e5622d2930 124 _gs_mode = GSMODE_COMMAND;
gsfan 25:f6e5622d2930 125 _ssid = NULL;
gsfan 26:b347ee3a1087 126 _pass = NULL;
gsfan 25:f6e5622d2930 127 _reconnect = 0;
gsfan 26:b347ee3a1087 128 _buf_cmd.flush();
gsfan 25:f6e5622d2930 129
gsfan 33:b5a5a1e6325f 130 wait_ms(100);
gsfan 35:515ec79792d3 131 if (! _baud) autobaud(0);
gsfan 26:b347ee3a1087 132 _reset.input(); // high
gsfan 28:fbba4c58d14c 133 _reset.mode(PullUp);
gsfan 35:515ec79792d3 134 if (! _baud) autobaud(1);
gsfan 25:f6e5622d2930 135 wait_ms(500);
gsfan 0:2f6062c6d018 136 }
gsfan 0:2f6062c6d018 137
gsfan 35:515ec79792d3 138 int GSwifi::autobaud (int flg) {
gsfan 35:515ec79792d3 139 int i;
gsfan 35:515ec79792d3 140
gsfan 36:a70b11e1560f 141 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
gsfan 35:515ec79792d3 142 if (flg == 0) {
gsfan 36:a70b11e1560f 143 _uart->ACR = (1<<2)|(1<<0); // auto-baud mode 0
gsfan 35:515ec79792d3 144 return 0;
gsfan 35:515ec79792d3 145 } else {
gsfan 35:515ec79792d3 146 for (i = 0; i < 50; i ++) {
gsfan 36:a70b11e1560f 147 if (! (_uart->ACR & (1<<0))) {
gsfan 35:515ec79792d3 148 return 0;
gsfan 35:515ec79792d3 149 }
gsfan 35:515ec79792d3 150 wait_ms(10);
gsfan 35:515ec79792d3 151 }
gsfan 36:a70b11e1560f 152 _uart->ACR = 0;
gsfan 35:515ec79792d3 153 }
gsfan 35:515ec79792d3 154 #endif
gsfan 35:515ec79792d3 155 return -1;
gsfan 35:515ec79792d3 156 }
gsfan 35:515ec79792d3 157
gsfan 37:e61ea8267415 158 int GSwifi::acquireUart (int ms) {
gsfan 36:a70b11e1560f 159 Timer timeout;
gsfan 36:a70b11e1560f 160
gsfan 36:a70b11e1560f 161 if (! _rts) return 0;
gsfan 36:a70b11e1560f 162
gsfan 37:e61ea8267415 163 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
gsfan 36:a70b11e1560f 164 timeout.start();
gsfan 36:a70b11e1560f 165 while (timeout.read_ms() < ms) {
gsfan 36:a70b11e1560f 166 // CTS check
gsfan 37:e61ea8267415 167 if (_uart->MSR & (1<<4)) {
gsfan 36:a70b11e1560f 168 timeout.stop();
gsfan 37:e61ea8267415 169 _uart->MCR &= ~(1<<6); // RTS off
gsfan 37:e61ea8267415 170 _uart->MCR &= ~(1<<1);
gsfan 36:a70b11e1560f 171 return 0;
gsfan 36:a70b11e1560f 172 }
gsfan 36:a70b11e1560f 173 }
gsfan 36:a70b11e1560f 174 timeout.stop();
gsfan 36:a70b11e1560f 175 DBG("cts timeout\r\n");
gsfan 37:e61ea8267415 176 #endif
gsfan 36:a70b11e1560f 177 return -1;
gsfan 36:a70b11e1560f 178 }
gsfan 36:a70b11e1560f 179
gsfan 37:e61ea8267415 180 void GSwifi::releaseUart () {
gsfan 37:e61ea8267415 181 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
gsfan 37:e61ea8267415 182 _uart->MCR |= (1<<6); // RTSEN
gsfan 37:e61ea8267415 183 #endif
gsfan 37:e61ea8267415 184 }
gsfan 37:e61ea8267415 185
gsfan 0:2f6062c6d018 186 // uart interrupt
gsfan 0:2f6062c6d018 187 void GSwifi::isr_recv () {
gsfan 0:2f6062c6d018 188 static int len, mode;
gsfan 0:2f6062c6d018 189 static char tmp[20];
gsfan 33:b5a5a1e6325f 190 char dat;
gsfan 33:b5a5a1e6325f 191
gsfan 1:b127c6c5241d 192 dat = _gs_getc();
gsfan 23:a783c62c36d0 193 #ifdef DEBUG_VIEW
gsfan 26:b347ee3a1087 194 if (dat >= 0x20 && dat < 0x7f) {
gsfan 26:b347ee3a1087 195 DBG("%c_", dat);
gsfan 26:b347ee3a1087 196 } else {
gsfan 26:b347ee3a1087 197 DBG("%02x_", dat);
gsfan 26:b347ee3a1087 198 }
gsfan 23:a783c62c36d0 199 #endif
gsfan 25:f6e5622d2930 200
gsfan 0:2f6062c6d018 201 switch (_gs_mode) {
gsfan 0:2f6062c6d018 202 case GSMODE_COMMAND: // command responce
gsfan 0:2f6062c6d018 203 if (_escape) {
gsfan 0:2f6062c6d018 204 // esc
gsfan 0:2f6062c6d018 205 switch (dat) {
gsfan 0:2f6062c6d018 206 case 'O':
gsfan 0:2f6062c6d018 207 DBG("ok\r\n");
gsfan 26:b347ee3a1087 208 _gs_ok = true;
gsfan 0:2f6062c6d018 209 break;
gsfan 0:2f6062c6d018 210 case 'F':
gsfan 0:2f6062c6d018 211 DBG("failure\r\n");
gsfan 26:b347ee3a1087 212 _gs_failure = true;
gsfan 0:2f6062c6d018 213 break;
gsfan 0:2f6062c6d018 214 case 'S':
gsfan 0:2f6062c6d018 215 DBG("GSMODE_DATA_RX\r\n");
gsfan 0:2f6062c6d018 216 _gs_mode = GSMODE_DATA_RX;
gsfan 0:2f6062c6d018 217 mode = 0;
gsfan 0:2f6062c6d018 218 break;
gsfan 0:2f6062c6d018 219 case 'u':
gsfan 0:2f6062c6d018 220 DBG("GSMODE_DATA_RXUDP\r\n");
gsfan 0:2f6062c6d018 221 _gs_mode = GSMODE_DATA_RXUDP;
gsfan 0:2f6062c6d018 222 mode = 0;
gsfan 0:2f6062c6d018 223 break;
gsfan 0:2f6062c6d018 224 case 'Z':
gsfan 0:2f6062c6d018 225 case 'H':
gsfan 0:2f6062c6d018 226 DBG("GSMODE_DATA_RX_BULK\r\n");
gsfan 0:2f6062c6d018 227 _gs_mode = GSMODE_DATA_RX_BULK;
gsfan 0:2f6062c6d018 228 mode = 0;
gsfan 0:2f6062c6d018 229 break;
gsfan 0:2f6062c6d018 230 case 'y':
gsfan 0:2f6062c6d018 231 DBG("GSMODE_DATA_RXUDP_BULK\r\n");
gsfan 0:2f6062c6d018 232 _gs_mode = GSMODE_DATA_RXUDP_BULK;
gsfan 0:2f6062c6d018 233 mode = 0;
gsfan 0:2f6062c6d018 234 break;
gsfan 0:2f6062c6d018 235 default:
gsfan 0:2f6062c6d018 236 DBG("unknown [ESC] %02x\r\n", dat);
gsfan 0:2f6062c6d018 237 break;
gsfan 0:2f6062c6d018 238 }
gsfan 0:2f6062c6d018 239 _escape = 0;
gsfan 0:2f6062c6d018 240 } else {
gsfan 0:2f6062c6d018 241 if (dat == 0x1b) {
gsfan 0:2f6062c6d018 242 _escape = 1;
gsfan 0:2f6062c6d018 243 } else
gsfan 26:b347ee3a1087 244 if (dat == '\n') {
gsfan 26:b347ee3a1087 245 // end of line
gsfan 26:b347ee3a1087 246 parseResponse();
gsfan 26:b347ee3a1087 247 } else
gsfan 0:2f6062c6d018 248 if (dat != '\r') {
gsfan 0:2f6062c6d018 249 // command
gsfan 25:f6e5622d2930 250 _buf_cmd.queue(dat);
gsfan 0:2f6062c6d018 251 }
gsfan 0:2f6062c6d018 252 }
gsfan 0:2f6062c6d018 253 break;
gsfan 0:2f6062c6d018 254
gsfan 0:2f6062c6d018 255 case GSMODE_DATA_RX:
gsfan 0:2f6062c6d018 256 case GSMODE_DATA_RXUDP:
gsfan 0:2f6062c6d018 257 if (mode == 0) {
gsfan 0:2f6062c6d018 258 // cid
gsfan 0:2f6062c6d018 259 _cid = x2i(dat);
gsfan 26:b347ee3a1087 260 _gs_sock[_cid].received = false;
gsfan 0:2f6062c6d018 261 mode ++;
gsfan 0:2f6062c6d018 262 if (_gs_mode == GSMODE_DATA_RX) {
gsfan 0:2f6062c6d018 263 mode = 3;
gsfan 0:2f6062c6d018 264 }
gsfan 0:2f6062c6d018 265 len = 0;
gsfan 0:2f6062c6d018 266 } else
gsfan 0:2f6062c6d018 267 if (mode == 1) {
gsfan 0:2f6062c6d018 268 // ip
gsfan 0:2f6062c6d018 269 if ((dat < '0' || dat > '9') && dat != '.') {
gsfan 0:2f6062c6d018 270 int ip1, ip2, ip3, ip4;
gsfan 0:2f6062c6d018 271 tmp[len] = 0;
gsfan 0:2f6062c6d018 272 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
gsfan 0:2f6062c6d018 273 _from.setIp(IpAddr(ip1, ip2, ip3, ip4));
gsfan 0:2f6062c6d018 274 mode ++;
gsfan 0:2f6062c6d018 275 len = 0;
gsfan 0:2f6062c6d018 276 break;
gsfan 0:2f6062c6d018 277 }
gsfan 37:e61ea8267415 278 if (len < sizeof(tmp) - 1) {
gsfan 37:e61ea8267415 279 tmp[len] = dat;
gsfan 37:e61ea8267415 280 len ++;
gsfan 37:e61ea8267415 281 }
gsfan 0:2f6062c6d018 282 } else
gsfan 0:2f6062c6d018 283 if (mode == 2) {
gsfan 0:2f6062c6d018 284 // port
gsfan 0:2f6062c6d018 285 if (dat < '0' || dat > '9') {
gsfan 0:2f6062c6d018 286 tmp[len] = 0;
gsfan 0:2f6062c6d018 287 _from.setPort(atoi(tmp));
gsfan 0:2f6062c6d018 288 mode ++;
gsfan 0:2f6062c6d018 289 len = 0;
gsfan 0:2f6062c6d018 290 break;
gsfan 0:2f6062c6d018 291 }
gsfan 37:e61ea8267415 292 if (len < sizeof(tmp) - 1) {
gsfan 37:e61ea8267415 293 tmp[len] = dat;
gsfan 37:e61ea8267415 294 len ++;
gsfan 37:e61ea8267415 295 }
gsfan 0:2f6062c6d018 296 } else
gsfan 0:2f6062c6d018 297 if (_escape) {
gsfan 0:2f6062c6d018 298 // esc
gsfan 0:2f6062c6d018 299 switch (dat) {
gsfan 0:2f6062c6d018 300 case 'E':
gsfan 0:2f6062c6d018 301 DBG("recv ascii %d\r\n", _cid);
gsfan 26:b347ee3a1087 302 _gs_sock[_cid].received = true;
gsfan 0:2f6062c6d018 303 _gs_mode = GSMODE_COMMAND;
gsfan 26:b347ee3a1087 304
gsfan 26:b347ee3a1087 305 if (_gs_sock[_cid].protocol == GSPROT_HTTPGET) {
gsfan 26:b347ee3a1087 306 // recv interrupt
gsfan 29:1c4419512941 307 if (_gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available()) == 0)
gsfan 26:b347ee3a1087 308 _gs_sock[_cid].received = false;
gsfan 0:2f6062c6d018 309 }
gsfan 0:2f6062c6d018 310 break;
gsfan 0:2f6062c6d018 311 default:
gsfan 0:2f6062c6d018 312 DBG("unknown <ESC> %02x\r\n", dat);
gsfan 0:2f6062c6d018 313 break;
gsfan 0:2f6062c6d018 314 }
gsfan 0:2f6062c6d018 315 _escape = 0;
gsfan 0:2f6062c6d018 316 } else {
gsfan 0:2f6062c6d018 317 if (dat == 0x1b) {
gsfan 0:2f6062c6d018 318 _escape = 1;
gsfan 0:2f6062c6d018 319 } else {
gsfan 0:2f6062c6d018 320 // data
gsfan 37:e61ea8267415 321 if (_gs_sock[_cid].data != NULL) {
gsfan 37:e61ea8267415 322 _gs_sock[_cid].data->queue(dat);
gsfan 37:e61ea8267415 323 len ++;
gsfan 26:b347ee3a1087 324
gsfan 37:e61ea8267415 325 if (len < GS_DATA_SIZE && _gs_sock[_cid].data->isFull()) {
gsfan 14:9e89b922ace1 326 // buffer full
gsfan 26:b347ee3a1087 327 // recv interrupt
gsfan 29:1c4419512941 328 _gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available());
gsfan 37:e61ea8267415 329 }
gsfan 12:63e714550791 330 }
gsfan 0:2f6062c6d018 331 }
gsfan 0:2f6062c6d018 332 }
gsfan 0:2f6062c6d018 333 break;
gsfan 0:2f6062c6d018 334
gsfan 0:2f6062c6d018 335 case GSMODE_DATA_RX_BULK:
gsfan 0:2f6062c6d018 336 case GSMODE_DATA_RXUDP_BULK:
gsfan 0:2f6062c6d018 337 if (mode == 0) {
gsfan 0:2f6062c6d018 338 // cid
gsfan 0:2f6062c6d018 339 _cid = x2i(dat);
gsfan 26:b347ee3a1087 340 _gs_sock[_cid].received = false;
gsfan 0:2f6062c6d018 341 mode ++;
gsfan 0:2f6062c6d018 342 if (_gs_mode == GSMODE_DATA_RX_BULK) {
gsfan 0:2f6062c6d018 343 mode = 3;
gsfan 0:2f6062c6d018 344 }
gsfan 0:2f6062c6d018 345 len = 0;
gsfan 0:2f6062c6d018 346 } else
gsfan 0:2f6062c6d018 347 if (mode == 1) {
gsfan 0:2f6062c6d018 348 // ip
gsfan 0:2f6062c6d018 349 if ((dat < '0' || dat > '9') && dat != '.') {
gsfan 0:2f6062c6d018 350 int ip1, ip2, ip3, ip4;
gsfan 0:2f6062c6d018 351 tmp[len] = 0;
gsfan 0:2f6062c6d018 352 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
gsfan 0:2f6062c6d018 353 _from.setIp(IpAddr(ip1, ip2, ip3, ip4));
gsfan 0:2f6062c6d018 354 mode ++;
gsfan 0:2f6062c6d018 355 len = 0;
gsfan 0:2f6062c6d018 356 break;
gsfan 0:2f6062c6d018 357 }
gsfan 37:e61ea8267415 358 if (len < sizeof(tmp) - 1) {
gsfan 37:e61ea8267415 359 tmp[len] = dat;
gsfan 37:e61ea8267415 360 len ++;
gsfan 37:e61ea8267415 361 }
gsfan 0:2f6062c6d018 362 } else
gsfan 0:2f6062c6d018 363 if (mode == 2) {
gsfan 0:2f6062c6d018 364 // port
gsfan 0:2f6062c6d018 365 if (dat < '0' || dat > '9') {
gsfan 0:2f6062c6d018 366 tmp[len] = 0;
gsfan 0:2f6062c6d018 367 _from.setPort(atoi(tmp));
gsfan 0:2f6062c6d018 368 mode ++;
gsfan 0:2f6062c6d018 369 len = 0;
gsfan 0:2f6062c6d018 370 break;
gsfan 0:2f6062c6d018 371 }
gsfan 37:e61ea8267415 372 if (len < sizeof(tmp) - 1) {
gsfan 37:e61ea8267415 373 tmp[len] = dat;
gsfan 37:e61ea8267415 374 len ++;
gsfan 37:e61ea8267415 375 }
gsfan 0:2f6062c6d018 376 } else
gsfan 0:2f6062c6d018 377 if (mode == 3) {
gsfan 0:2f6062c6d018 378 // length
gsfan 0:2f6062c6d018 379 tmp[len] = dat;
gsfan 0:2f6062c6d018 380 len ++;
gsfan 0:2f6062c6d018 381 if (len >= 4) {
gsfan 0:2f6062c6d018 382 tmp[len] = 0;
gsfan 0:2f6062c6d018 383 len = atoi(tmp);
gsfan 0:2f6062c6d018 384 mode ++;
gsfan 0:2f6062c6d018 385 break;
gsfan 0:2f6062c6d018 386 }
gsfan 0:2f6062c6d018 387 } else
gsfan 0:2f6062c6d018 388 if (mode == 4) {
gsfan 0:2f6062c6d018 389 // data
gsfan 5:6def1d0df519 390 if (_gs_sock[_cid].data != NULL) {
gsfan 37:e61ea8267415 391 _gs_sock[_cid].data->queue(dat);
gsfan 37:e61ea8267415 392 len --;
gsfan 26:b347ee3a1087 393
gsfan 37:e61ea8267415 394 if (len && _gs_sock[_cid].data->isFull()) {
gsfan 14:9e89b922ace1 395 // buffer full
gsfan 26:b347ee3a1087 396 // recv interrupt
gsfan 29:1c4419512941 397 _gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available());
gsfan 37:e61ea8267415 398 }
gsfan 12:63e714550791 399 }
gsfan 0:2f6062c6d018 400 if (len == 0) {
gsfan 0:2f6062c6d018 401 DBG("recv binary %d\r\n", _cid);
gsfan 26:b347ee3a1087 402 _gs_sock[_cid].received = true;
gsfan 0:2f6062c6d018 403 _escape = 0;
gsfan 0:2f6062c6d018 404 _gs_mode = GSMODE_COMMAND;
gsfan 26:b347ee3a1087 405
gsfan 26:b347ee3a1087 406 if (_gs_sock[_cid].protocol == GSPROT_HTTPGET) {
gsfan 26:b347ee3a1087 407 // recv interrupt
gsfan 29:1c4419512941 408 if (_gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->available()) == 0)
gsfan 26:b347ee3a1087 409 _gs_sock[_cid].received = false;
gsfan 0:2f6062c6d018 410 }
gsfan 0:2f6062c6d018 411 }
gsfan 0:2f6062c6d018 412 }
gsfan 0:2f6062c6d018 413 break;
gsfan 0:2f6062c6d018 414
gsfan 0:2f6062c6d018 415 }
gsfan 0:2f6062c6d018 416 }
gsfan 0:2f6062c6d018 417
gsfan 37:e61ea8267415 418 void GSwifi::parseResponse () {
gsfan 37:e61ea8267415 419 int i;
gsfan 37:e61ea8267415 420 char buf[GS_CMD_SIZE];
gsfan 37:e61ea8267415 421
gsfan 37:e61ea8267415 422 while (! _buf_cmd.isEmpty()) {
gsfan 37:e61ea8267415 423 // received "\n"
gsfan 37:e61ea8267415 424 i = 0;
gsfan 37:e61ea8267415 425 while ((! _buf_cmd.isEmpty()) && i < sizeof(buf)) {
gsfan 37:e61ea8267415 426 _buf_cmd.dequeue(&buf[i]);
gsfan 37:e61ea8267415 427 if (buf[i] == '\n') {
gsfan 37:e61ea8267415 428 break;
gsfan 37:e61ea8267415 429 }
gsfan 37:e61ea8267415 430 i ++;
gsfan 37:e61ea8267415 431 }
gsfan 37:e61ea8267415 432 if (i == 0) continue;
gsfan 37:e61ea8267415 433 buf[i] = 0;
gsfan 37:e61ea8267415 434 DBG("parseResponse: %s\r\n", buf);
gsfan 37:e61ea8267415 435
gsfan 37:e61ea8267415 436 parseCmdResponse(buf);
gsfan 37:e61ea8267415 437
gsfan 37:e61ea8267415 438 if (strncmp(buf, "CONNECT ", 8) == 0 && buf[8] >= '0' && buf[8] <= 'F' && buf[9] != 0) {
gsfan 37:e61ea8267415 439 int cid = x2i(buf[8]);
gsfan 37:e61ea8267415 440 if (_gs_sock[cid].type == GSTYPE_SERVER) {
gsfan 37:e61ea8267415 441 // fork (server socket)
gsfan 37:e61ea8267415 442 int acid, ip1, ip2, ip3, ip4;
gsfan 37:e61ea8267415 443 char *tmp = buf + 12;
gsfan 37:e61ea8267415 444
gsfan 37:e61ea8267415 445 acid = x2i(buf[10]);
gsfan 37:e61ea8267415 446 DBG("connect %d -> %d\r\n", cid, acid);
gsfan 37:e61ea8267415 447 newSock(acid, _gs_sock[cid].type, _gs_sock[cid].protocol);
gsfan 37:e61ea8267415 448 _gs_sock[acid].onGsReceive = _gs_sock[cid].onGsReceive;
gsfan 37:e61ea8267415 449 _gs_sock[acid].lcid = cid;
gsfan 37:e61ea8267415 450 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
gsfan 37:e61ea8267415 451 _gs_sock[acid].host.setIp(IpAddr(ip1, ip2, ip3, ip4));
gsfan 37:e61ea8267415 452 tmp = strstr(tmp, " ") + 1;
gsfan 37:e61ea8267415 453 _gs_sock[acid].host.setPort(atoi(tmp));
gsfan 37:e61ea8267415 454 _gs_sock[acid].onGsReceive.call(acid, 0); // event connected
gsfan 37:e61ea8267415 455 }
gsfan 37:e61ea8267415 456 } else
gsfan 37:e61ea8267415 457 if (strncmp(buf, "DISCONNECT ", 11) == 0) {
gsfan 37:e61ea8267415 458 int cid = x2i(buf[11]);
gsfan 37:e61ea8267415 459 DBG("disconnect %d\r\n", cid);
gsfan 37:e61ea8267415 460 _gs_sock[cid].connect = false;
gsfan 37:e61ea8267415 461 _gs_sock[cid].onGsReceive.call(cid, -1); // event disconnected
gsfan 37:e61ea8267415 462 } else
gsfan 37:e61ea8267415 463 if (strncmp(buf, "DISASSOCIATED", 13) == 0 ||
gsfan 37:e61ea8267415 464 strncmp(buf, "Disassociated", 13) == 0 ||
gsfan 37:e61ea8267415 465 strncmp(buf, "Disassociation Event", 20) == 0 ||
gsfan 37:e61ea8267415 466 strncmp(buf, "UnExpected Warm Boot", 20) == 0 ||
gsfan 37:e61ea8267415 467 strncmp(buf, "APP Reset-APP SW Reset", 22) == 0 ||
gsfan 37:e61ea8267415 468 strncmp(buf, "APP Reset-Wlan Except", 21) == 0 ) {
gsfan 37:e61ea8267415 469 DBG("disassociate\r\n");
gsfan 37:e61ea8267415 470 _connect = false;
gsfan 37:e61ea8267415 471 for (i = 0; i < 16; i ++) {
gsfan 37:e61ea8267415 472 _gs_sock[i].connect = false;
gsfan 37:e61ea8267415 473 }
gsfan 37:e61ea8267415 474 } else
gsfan 37:e61ea8267415 475 if (strncmp(buf, "Out of StandBy-Timer", 20) == 0 ||
gsfan 37:e61ea8267415 476 strncmp(buf, "Out of StandBy-Alarm", 20) == 0) {
gsfan 37:e61ea8267415 477 // if (_status == GSSTAT_STANDBY) {
gsfan 37:e61ea8267415 478 _status = GSSTAT_WAKEUP;
gsfan 37:e61ea8267415 479 // }
gsfan 37:e61ea8267415 480 } else
gsfan 37:e61ea8267415 481 if (strncmp(buf, "Out of Deep Sleep", 17) == 0 ) {
gsfan 37:e61ea8267415 482 // if (_status == GSSTAT_DEEPSLEEP) {
gsfan 37:e61ea8267415 483 _status = GSSTAT_READY;
gsfan 37:e61ea8267415 484 // }
gsfan 37:e61ea8267415 485 }
gsfan 37:e61ea8267415 486 DBG("status: %d\r\n", _status);
gsfan 37:e61ea8267415 487 }
gsfan 37:e61ea8267415 488 }
gsfan 37:e61ea8267415 489
gsfan 37:e61ea8267415 490 void GSwifi::parseCmdResponse (char *buf) {
gsfan 37:e61ea8267415 491 if (_gs_res == GSRES_NONE) return;
gsfan 37:e61ea8267415 492
gsfan 37:e61ea8267415 493 if (strcmp(buf, "OK") == 0) {
gsfan 37:e61ea8267415 494 _gs_ok = true;
gsfan 37:e61ea8267415 495 } else
gsfan 37:e61ea8267415 496 if (strncmp(buf, "ERROR", 5) == 0) {
gsfan 37:e61ea8267415 497 _gs_failure = true;
gsfan 37:e61ea8267415 498 }
gsfan 37:e61ea8267415 499
gsfan 37:e61ea8267415 500 switch(_gs_res) {
gsfan 37:e61ea8267415 501 case GSRES_NORMAL:
gsfan 37:e61ea8267415 502 _gs_flg = -1;
gsfan 37:e61ea8267415 503 break;
gsfan 37:e61ea8267415 504 case GSRES_WPS:
gsfan 37:e61ea8267415 505 if (_gs_flg == 0 && strncmp(buf, "SSID=", 5) == 0) {
gsfan 37:e61ea8267415 506 if (!_ssid) _ssid = (char*)malloc(strlen(&buf[5]) + 1);
gsfan 37:e61ea8267415 507 strcpy(_ssid, &buf[5]);
gsfan 37:e61ea8267415 508 _gs_flg ++;
gsfan 37:e61ea8267415 509 } else
gsfan 37:e61ea8267415 510 if (_gs_flg == 1 && strncmp(buf, "CHANNEL=", 8) == 0) {
gsfan 37:e61ea8267415 511 _gs_flg ++;
gsfan 37:e61ea8267415 512 } else
gsfan 37:e61ea8267415 513 if (_gs_flg == 2 && strncmp(buf, "PASSPHRASE=", 11) == 0) {
gsfan 37:e61ea8267415 514 if (!_pass) _pass = (char*)malloc(strlen(&buf[11]) + 1);
gsfan 37:e61ea8267415 515 strcpy(_pass, &buf[11]);
gsfan 37:e61ea8267415 516 _gs_flg = -1;
gsfan 37:e61ea8267415 517 }
gsfan 37:e61ea8267415 518 break;
gsfan 37:e61ea8267415 519 case GSRES_CONNECT:
gsfan 37:e61ea8267415 520 if (strncmp(buf, "CONNECT ", 8) == 0 && buf[9] == 0) {
gsfan 37:e61ea8267415 521 _cid = x2i(buf[8]);
gsfan 37:e61ea8267415 522 _gs_flg = -1;
gsfan 37:e61ea8267415 523 }
gsfan 37:e61ea8267415 524 break;
gsfan 37:e61ea8267415 525 case GSRES_DHCP:
gsfan 37:e61ea8267415 526 if (_gs_flg == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) {
gsfan 37:e61ea8267415 527 _gs_flg ++;
gsfan 37:e61ea8267415 528 } else
gsfan 37:e61ea8267415 529 if (_gs_flg == 1) {
gsfan 37:e61ea8267415 530 int ip1, ip2, ip3, ip4;
gsfan 37:e61ea8267415 531 char *tmp = buf + 1;
gsfan 37:e61ea8267415 532 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
gsfan 37:e61ea8267415 533 _ipaddr = IpAddr(ip1, ip2, ip3, ip4);
gsfan 37:e61ea8267415 534 tmp = strstr(tmp, ":") + 2;
gsfan 37:e61ea8267415 535 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
gsfan 37:e61ea8267415 536 _netmask = IpAddr(ip1, ip2, ip3, ip4);
gsfan 37:e61ea8267415 537 tmp = strstr(tmp, ":") + 2;
gsfan 37:e61ea8267415 538 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
gsfan 37:e61ea8267415 539 _gateway = IpAddr(ip1, ip2, ip3, ip4);
gsfan 37:e61ea8267415 540 _gs_flg = -1;
gsfan 37:e61ea8267415 541 }
gsfan 37:e61ea8267415 542 break;
gsfan 37:e61ea8267415 543 case GSRES_MACADDRESS:
gsfan 37:e61ea8267415 544 if (buf[2] == ':' && buf[5] == ':') {
gsfan 37:e61ea8267415 545 int mac1, mac2, mac3, mac4, mac5, mac6;
gsfan 37:e61ea8267415 546 sscanf(buf, "%x:%x:%x:%x:%x:%x", &mac1, &mac2, &mac3, &mac4, &mac5, &mac6);
gsfan 37:e61ea8267415 547 _mac[0] = mac1;
gsfan 37:e61ea8267415 548 _mac[1] = mac2;
gsfan 37:e61ea8267415 549 _mac[2] = mac3;
gsfan 37:e61ea8267415 550 _mac[3] = mac4;
gsfan 37:e61ea8267415 551 _mac[4] = mac5;
gsfan 37:e61ea8267415 552 _mac[5] = mac6;
gsfan 37:e61ea8267415 553 _gs_flg = -1;
gsfan 37:e61ea8267415 554 }
gsfan 37:e61ea8267415 555 break;
gsfan 37:e61ea8267415 556 case GSRES_DNSLOOKUP:
gsfan 37:e61ea8267415 557 if (strncmp(buf, "IP:", 3) == 0) {
gsfan 37:e61ea8267415 558 int ip1, ip2, ip3, ip4;
gsfan 37:e61ea8267415 559 sscanf(&buf[3], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
gsfan 37:e61ea8267415 560 _resolv = IpAddr(ip1, ip2, ip3, ip4);
gsfan 37:e61ea8267415 561 _gs_flg = -1;
gsfan 37:e61ea8267415 562 }
gsfan 37:e61ea8267415 563 break;
gsfan 37:e61ea8267415 564 case GSRES_HTTP:
gsfan 37:e61ea8267415 565 if (buf[0] >= '0' && buf[0] <= 'F' && buf[1] == 0) {
gsfan 37:e61ea8267415 566 _cid = x2i(buf[0]);
gsfan 37:e61ea8267415 567 _gs_flg = -1;
gsfan 37:e61ea8267415 568 }
gsfan 37:e61ea8267415 569 break;
gsfan 37:e61ea8267415 570 case GSRES_RSSI:
gsfan 37:e61ea8267415 571 if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) {
gsfan 37:e61ea8267415 572 _rssi = atoi(buf);
gsfan 37:e61ea8267415 573 _gs_flg = -1;
gsfan 37:e61ea8267415 574 }
gsfan 37:e61ea8267415 575 break;
gsfan 37:e61ea8267415 576 case GSRES_TIME:
gsfan 37:e61ea8267415 577 if (buf[0] >= '0' && buf[0] <= '9') {
gsfan 37:e61ea8267415 578 int year, month, day, hour, min, sec;
gsfan 37:e61ea8267415 579 struct tm t;
gsfan 37:e61ea8267415 580 sscanf(buf, "%d/%d/%d,%d:%d:%d", &day, &month, &year, &hour, &min, &sec);
gsfan 37:e61ea8267415 581 t.tm_sec = sec;
gsfan 37:e61ea8267415 582 t.tm_min = min;
gsfan 37:e61ea8267415 583 t.tm_hour = hour;
gsfan 37:e61ea8267415 584 t.tm_mday = day;
gsfan 37:e61ea8267415 585 t.tm_mon = month - 1;
gsfan 37:e61ea8267415 586 t.tm_year = year - 1900;
gsfan 37:e61ea8267415 587 _time = mktime(&t);
gsfan 37:e61ea8267415 588 _gs_flg = -1;
gsfan 37:e61ea8267415 589 }
gsfan 37:e61ea8267415 590 break;
gsfan 37:e61ea8267415 591 }
gsfan 37:e61ea8267415 592
gsfan 37:e61ea8267415 593 return;
gsfan 37:e61ea8267415 594 }
gsfan 37:e61ea8267415 595
gsfan 37:e61ea8267415 596 void GSwifi::poll () {
gsfan 37:e61ea8267415 597 int i, j;
gsfan 37:e61ea8267415 598
gsfan 37:e61ea8267415 599 for (i = 0; i < 16; i ++) {
gsfan 37:e61ea8267415 600 if (_gs_sock[i].connect && _gs_sock[i].received) {
gsfan 37:e61ea8267415 601 if (_gs_sock[i].data && ! _gs_sock[i].data->isEmpty()) {
gsfan 37:e61ea8267415 602 // recv interrupt
gsfan 37:e61ea8267415 603 _gs_sock[i].received = false;
gsfan 37:e61ea8267415 604 for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) {
gsfan 37:e61ea8267415 605 if (! _gs_sock[i].connect || _gs_sock[i].data->isEmpty()) break;
gsfan 37:e61ea8267415 606 _gs_sock[i].onGsReceive.call(i, _gs_sock[i].data->available());
gsfan 37:e61ea8267415 607 }
gsfan 37:e61ea8267415 608 }
gsfan 37:e61ea8267415 609 }
gsfan 37:e61ea8267415 610 }
gsfan 37:e61ea8267415 611
gsfan 37:e61ea8267415 612 if (_reconnect && ! _connect) {
gsfan 37:e61ea8267415 613 if (_reconnect_count == 0 || (_reconnect_count < _reconnect && _reconnect_time < time(NULL))) {
gsfan 37:e61ea8267415 614 _reconnect_count ++;
gsfan 37:e61ea8267415 615 DBG("reconnect %d/%d\r\n", _reconnect_count, _reconnect);
gsfan 37:e61ea8267415 616 if (reconnect() == 0) {
gsfan 37:e61ea8267415 617 _reconnect_count = 0;
gsfan 37:e61ea8267415 618 }
gsfan 37:e61ea8267415 619 _reconnect_time = time(NULL) + GS_RECONTIME;
gsfan 37:e61ea8267415 620 }
gsfan 37:e61ea8267415 621 }
gsfan 37:e61ea8267415 622 }
gsfan 37:e61ea8267415 623
gsfan 12:63e714550791 624 int GSwifi::command (const char *cmd, GSRESPONCE res, int timeout) {
gsfan 26:b347ee3a1087 625 int i;
gsfan 0:2f6062c6d018 626
gsfan 37:e61ea8267415 627 if (acquireUart()) return -1;
gsfan 36:a70b11e1560f 628
gsfan 26:b347ee3a1087 629 if (cmd == NULL) {
gsfan 0:2f6062c6d018 630 // dummy CR+LF
gsfan 36:a70b11e1560f 631 _gs_putc('\r');
gsfan 36:a70b11e1560f 632 _gs_putc('\n');
gsfan 37:e61ea8267415 633 releaseUart();
gsfan 26:b347ee3a1087 634 wait_ms(100);
gsfan 26:b347ee3a1087 635 _buf_cmd.flush();
gsfan 0:2f6062c6d018 636 return 0;
gsfan 0:2f6062c6d018 637 }
gsfan 0:2f6062c6d018 638
gsfan 26:b347ee3a1087 639 resetResponse(res);
gsfan 0:2f6062c6d018 640 for (i = 0; i < strlen(cmd); i ++) {
gsfan 1:b127c6c5241d 641 _gs_putc(cmd[i]);
gsfan 0:2f6062c6d018 642 }
gsfan 1:b127c6c5241d 643 _gs_putc('\r');
gsfan 1:b127c6c5241d 644 _gs_putc('\n');
gsfan 37:e61ea8267415 645 releaseUart();
gsfan 0:2f6062c6d018 646 DBG("command: %s\r\n", cmd);
gsfan 0:2f6062c6d018 647 if (strlen(cmd) == 0) return 0;
gsfan 26:b347ee3a1087 648
gsfan 26:b347ee3a1087 649 return waitResponse(timeout);
gsfan 0:2f6062c6d018 650 }
gsfan 0:2f6062c6d018 651
gsfan 26:b347ee3a1087 652 void GSwifi::resetResponse (GSRESPONCE res) {
gsfan 26:b347ee3a1087 653 _gs_ok = false;
gsfan 26:b347ee3a1087 654 _gs_failure = false;
gsfan 26:b347ee3a1087 655 _gs_flg = 0;
gsfan 26:b347ee3a1087 656 _gs_res = res;
gsfan 26:b347ee3a1087 657 }
gsfan 26:b347ee3a1087 658
gsfan 26:b347ee3a1087 659 int GSwifi::waitResponse (int ms) {
gsfan 0:2f6062c6d018 660 Timer timeout;
gsfan 0:2f6062c6d018 661
gsfan 26:b347ee3a1087 662 if (! ms) return 0;
gsfan 26:b347ee3a1087 663
gsfan 0:2f6062c6d018 664 timeout.start();
gsfan 0:2f6062c6d018 665 for (;;) {
gsfan 26:b347ee3a1087 666 if (timeout.read_ms() > ms) {
gsfan 26:b347ee3a1087 667 DBG("timeout\r\n");
gsfan 5:6def1d0df519 668 break;
gsfan 0:2f6062c6d018 669 }
gsfan 26:b347ee3a1087 670 if (_gs_ok && (_gs_flg == -1 || _gs_res == GSRES_NONE)) {
gsfan 26:b347ee3a1087 671 timeout.stop();
gsfan 26:b347ee3a1087 672 _gs_res = GSRES_NONE;
gsfan 26:b347ee3a1087 673 return 0;
gsfan 26:b347ee3a1087 674 }
gsfan 26:b347ee3a1087 675 if (_gs_failure) break;
gsfan 0:2f6062c6d018 676 }
gsfan 26:b347ee3a1087 677 timeout.stop();
gsfan 26:b347ee3a1087 678 _gs_res = GSRES_NONE;
gsfan 26:b347ee3a1087 679 return -1;
gsfan 0:2f6062c6d018 680 }
gsfan 0:2f6062c6d018 681
gsfan 35:515ec79792d3 682 int GSwifi::connect (GSSECURITY sec, const char *ssid, const char *pass, int dhcp, int reconnect, char *name) {
gsfan 0:2f6062c6d018 683 int r;
gsfan 0:2f6062c6d018 684 char cmd[GS_CMD_SIZE];
gsfan 0:2f6062c6d018 685
gsfan 0:2f6062c6d018 686 if (_connect || _status != GSSTAT_READY) return -1;
gsfan 0:2f6062c6d018 687
gsfan 0:2f6062c6d018 688 command(NULL, GSRES_NORMAL);
gsfan 0:2f6062c6d018 689 if (command("ATE0", GSRES_NORMAL)) return -1;
gsfan 0:2f6062c6d018 690 if (_rts) {
gsfan 0:2f6062c6d018 691 command("AT&R1", GSRES_NORMAL);
gsfan 0:2f6062c6d018 692 }
gsfan 35:515ec79792d3 693 if (getMacAddress(_mac)) return -1;
gsfan 0:2f6062c6d018 694 #ifdef GS_BULK
gsfan 0:2f6062c6d018 695 command("AT+BDATA=1", GSRES_NORMAL);
gsfan 0:2f6062c6d018 696 #endif
gsfan 0:2f6062c6d018 697
gsfan 0:2f6062c6d018 698 disconnect();
gsfan 0:2f6062c6d018 699 command("AT+WM=0", GSRES_NORMAL); // infrastructure
gsfan 0:2f6062c6d018 700 wait_ms(100);
gsfan 20:151b5a4fdd29 701 if (dhcp && sec != GSSEC_WPS_BUTTON) {
gsfan 35:515ec79792d3 702 if (name) {
gsfan 35:515ec79792d3 703 sprintf(cmd, "AT+NDHCP=1,%s", name);
gsfan 35:515ec79792d3 704 } else {
gsfan 35:515ec79792d3 705 strcpy(cmd, "AT+NDHCP=1," GS_DHCPNAME);
gsfan 35:515ec79792d3 706 }
gsfan 35:515ec79792d3 707 command(cmd, GSRES_NORMAL);
gsfan 0:2f6062c6d018 708 } else {
gsfan 0:2f6062c6d018 709 command("AT+NDHCP=0", GSRES_NORMAL);
gsfan 0:2f6062c6d018 710 }
gsfan 0:2f6062c6d018 711
gsfan 0:2f6062c6d018 712 switch (sec) {
gsfan 0:2f6062c6d018 713 case GSSEC_NONE:
gsfan 0:2f6062c6d018 714 case GSSEC_OPEN:
gsfan 0:2f6062c6d018 715 case GSSEC_WEP:
gsfan 0:2f6062c6d018 716 sprintf(cmd, "AT+WAUTH=%d", sec);
gsfan 0:2f6062c6d018 717 command(cmd, GSRES_NORMAL);
gsfan 22:9b077e2823ce 718 if (sec != GSSEC_NONE) {
gsfan 22:9b077e2823ce 719 sprintf(cmd, "AT+WWEP1=%s", pass);
gsfan 22:9b077e2823ce 720 command(cmd, GSRES_NORMAL);
gsfan 22:9b077e2823ce 721 wait_ms(100);
gsfan 22:9b077e2823ce 722 }
gsfan 0:2f6062c6d018 723 sprintf(cmd, "AT+WA=%s", ssid);
gsfan 1:b127c6c5241d 724 r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
gsfan 20:151b5a4fdd29 725 if (r) {
gsfan 20:151b5a4fdd29 726 DBG("retry\r\n");
gsfan 26:b347ee3a1087 727 wait_ms(1000);
gsfan 20:151b5a4fdd29 728 r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
gsfan 20:151b5a4fdd29 729 }
gsfan 0:2f6062c6d018 730 break;
gsfan 0:2f6062c6d018 731 case GSSEC_WPA_PSK:
gsfan 28:fbba4c58d14c 732 case GSSEC_WPA_ENT:
gsfan 0:2f6062c6d018 733 case GSSEC_WPA2_PSK:
gsfan 28:fbba4c58d14c 734 case GSSEC_WPA2_ENT:
gsfan 0:2f6062c6d018 735 command("AT+WAUTH=0", GSRES_NORMAL);
gsfan 0:2f6062c6d018 736 // sprintf(cmd, "AT+WWPA=%s", pass);
gsfan 0:2f6062c6d018 737 sprintf(cmd, "AT+WPAPSK=%s,%s", ssid, pass);
gsfan 0:2f6062c6d018 738 command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
gsfan 0:2f6062c6d018 739 wait_ms(100);
gsfan 0:2f6062c6d018 740 sprintf(cmd, "AT+WA=%s", ssid);
gsfan 1:b127c6c5241d 741 r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
gsfan 20:151b5a4fdd29 742 if (r) {
gsfan 20:151b5a4fdd29 743 DBG("retry\r\n");
gsfan 26:b347ee3a1087 744 wait_ms(1000);
gsfan 20:151b5a4fdd29 745 r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
gsfan 20:151b5a4fdd29 746 }
gsfan 0:2f6062c6d018 747 break;
gsfan 0:2f6062c6d018 748 case GSSEC_WPS_BUTTON:
gsfan 0:2f6062c6d018 749 command("AT+WAUTH=0", GSRES_NORMAL);
gsfan 0:2f6062c6d018 750 r = command("AT+WWPS=1", GSRES_WPS, GS_TIMEOUT2);
gsfan 0:2f6062c6d018 751 if (r) break;
gsfan 0:2f6062c6d018 752 if (dhcp) {
gsfan 35:515ec79792d3 753 r = setAddress(name);
gsfan 0:2f6062c6d018 754 }
gsfan 0:2f6062c6d018 755 break;
gsfan 28:fbba4c58d14c 756 case GSSEC_WPS_PIN:
gsfan 28:fbba4c58d14c 757 command("AT+WAUTH=0", GSRES_NORMAL);
gsfan 28:fbba4c58d14c 758 sprintf(cmd, "AT+WWPS=2,%s", pass);
gsfan 28:fbba4c58d14c 759 r = command(cmd, GSRES_WPS, GS_TIMEOUT2);
gsfan 28:fbba4c58d14c 760 if (r) break;
gsfan 28:fbba4c58d14c 761 if (dhcp) {
gsfan 35:515ec79792d3 762 r = setAddress(name);
gsfan 28:fbba4c58d14c 763 }
gsfan 28:fbba4c58d14c 764 break;
gsfan 6:a423f0d197de 765 default:
gsfan 6:a423f0d197de 766 DBG("Can't use security\r\n");
gsfan 6:a423f0d197de 767 r = -1;
gsfan 6:a423f0d197de 768 break;
gsfan 0:2f6062c6d018 769 }
gsfan 0:2f6062c6d018 770
gsfan 18:4b97804c37d1 771 if (r == 0 && !dhcp) {
gsfan 18:4b97804c37d1 772 sprintf(cmd, "AT+DNSSET=%d.%d.%d.%d",
gsfan 18:4b97804c37d1 773 _gateway[0], _gateway[1], _gateway[2], _gateway[3]);
gsfan 18:4b97804c37d1 774 command(cmd, GSRES_NORMAL);
gsfan 18:4b97804c37d1 775 }
gsfan 18:4b97804c37d1 776
gsfan 24:5c350ae2e703 777 if (r == 0) {
gsfan 24:5c350ae2e703 778 _connect = true;
gsfan 24:5c350ae2e703 779 _reconnect = reconnect;
gsfan 24:5c350ae2e703 780 _reconnect_count = 0;
gsfan 28:fbba4c58d14c 781 _sec = sec;
gsfan 35:515ec79792d3 782 if (_reconnect && ssid) {
gsfan 35:515ec79792d3 783 if (!_ssid) _ssid = (char*)malloc(strlen(ssid) + 1);
gsfan 28:fbba4c58d14c 784 strcpy(_ssid, ssid);
gsfan 28:fbba4c58d14c 785 }
gsfan 35:515ec79792d3 786 if (_reconnect && pass) {
gsfan 35:515ec79792d3 787 if (!_pass) _pass = (char*)malloc(strlen(pass) + 1);
gsfan 28:fbba4c58d14c 788 strcpy(_pass, pass);
gsfan 28:fbba4c58d14c 789 }
gsfan 24:5c350ae2e703 790 }
gsfan 0:2f6062c6d018 791 return r;
gsfan 0:2f6062c6d018 792 }
gsfan 0:2f6062c6d018 793
gsfan 19:cad912f5a6ba 794 int GSwifi::adhock (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask) {
gsfan 0:2f6062c6d018 795 int r;
gsfan 0:2f6062c6d018 796 char cmd[GS_CMD_SIZE];
gsfan 0:2f6062c6d018 797
gsfan 0:2f6062c6d018 798 if (_connect || _status != GSSTAT_READY) return -1;
gsfan 0:2f6062c6d018 799
gsfan 0:2f6062c6d018 800 command(NULL, GSRES_NORMAL);
gsfan 0:2f6062c6d018 801 if (command("ATE0", GSRES_NORMAL)) return -1;
gsfan 0:2f6062c6d018 802 if (_rts) {
gsfan 0:2f6062c6d018 803 command("AT&R1", GSRES_NORMAL);
gsfan 0:2f6062c6d018 804 }
gsfan 35:515ec79792d3 805 if (getMacAddress(_mac)) return -1;
gsfan 0:2f6062c6d018 806 #ifdef GS_BULK
gsfan 0:2f6062c6d018 807 command("AT+BDATA=1", GSRES_NORMAL);
gsfan 0:2f6062c6d018 808 #endif
gsfan 0:2f6062c6d018 809
gsfan 35:515ec79792d3 810 disconnect();
gsfan 0:2f6062c6d018 811 command("AT+WM=1", GSRES_NORMAL); // adhock
gsfan 0:2f6062c6d018 812 wait_ms(100);
gsfan 0:2f6062c6d018 813 command("AT+NDHCP=0", GSRES_NORMAL);
gsfan 0:2f6062c6d018 814 setAddress(ipaddr, netmask, ipaddr, ipaddr);
gsfan 0:2f6062c6d018 815
gsfan 0:2f6062c6d018 816 switch (sec) {
gsfan 0:2f6062c6d018 817 case GSSEC_NONE:
gsfan 0:2f6062c6d018 818 case GSSEC_OPEN:
gsfan 0:2f6062c6d018 819 case GSSEC_WEP:
gsfan 0:2f6062c6d018 820 sprintf(cmd, "AT+WAUTH=%d", sec);
gsfan 0:2f6062c6d018 821 command(cmd, GSRES_NORMAL);
gsfan 22:9b077e2823ce 822 if (sec != GSSEC_NONE) {
gsfan 22:9b077e2823ce 823 sprintf(cmd, "AT+WWEP1=%s", pass);
gsfan 22:9b077e2823ce 824 command(cmd, GSRES_NORMAL);
gsfan 22:9b077e2823ce 825 wait_ms(100);
gsfan 22:9b077e2823ce 826 }
gsfan 0:2f6062c6d018 827 sprintf(cmd, "AT+WA=%s", ssid);
gsfan 0:2f6062c6d018 828 r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
gsfan 0:2f6062c6d018 829 break;
gsfan 0:2f6062c6d018 830 default:
gsfan 0:2f6062c6d018 831 DBG("Can't use security\r\n");
gsfan 0:2f6062c6d018 832 r = -1;
gsfan 0:2f6062c6d018 833 break;
gsfan 0:2f6062c6d018 834 }
gsfan 0:2f6062c6d018 835
gsfan 0:2f6062c6d018 836 if (r == 0) _connect = true;
gsfan 0:2f6062c6d018 837 return r;
gsfan 0:2f6062c6d018 838 }
gsfan 0:2f6062c6d018 839
gsfan 22:9b077e2823ce 840 int GSwifi::limitedap (GSSECURITY sec, const char *ssid, const char *pass, IpAddr ipaddr, IpAddr netmask, char *dns) {
gsfan 0:2f6062c6d018 841 int r;
gsfan 0:2f6062c6d018 842 char cmd[GS_CMD_SIZE];
gsfan 0:2f6062c6d018 843
gsfan 0:2f6062c6d018 844 if (_connect || _status != GSSTAT_READY) return -1;
gsfan 0:2f6062c6d018 845
gsfan 0:2f6062c6d018 846 command(NULL, GSRES_NORMAL);
gsfan 0:2f6062c6d018 847 if (command("ATE0", GSRES_NORMAL)) return -1;
gsfan 0:2f6062c6d018 848 if (_rts) {
gsfan 0:2f6062c6d018 849 command("AT&R1", GSRES_NORMAL);
gsfan 0:2f6062c6d018 850 }
gsfan 35:515ec79792d3 851 if (getMacAddress(_mac)) return -1;
gsfan 0:2f6062c6d018 852 #ifdef GS_BULK
gsfan 0:2f6062c6d018 853 command("AT+BDATA=1", GSRES_NORMAL);
gsfan 0:2f6062c6d018 854 #endif
gsfan 0:2f6062c6d018 855
gsfan 35:515ec79792d3 856 disconnect();
gsfan 0:2f6062c6d018 857 command("AT+WM=2", GSRES_NORMAL); // limited ap
gsfan 26:b347ee3a1087 858 wait_ms(100);
gsfan 0:2f6062c6d018 859 command("AT+NDHCP=0", GSRES_NORMAL);
gsfan 0:2f6062c6d018 860 setAddress(ipaddr, netmask, ipaddr, ipaddr);
gsfan 8:bce9e7e51a0d 861 if (command("AT+DHCPSRVR=1", GSRES_NORMAL)) return -1;
gsfan 22:9b077e2823ce 862 if (dns) {
gsfan 22:9b077e2823ce 863 sprintf(cmd, "AT+DNS=1,%s", dns);
gsfan 22:9b077e2823ce 864 } else {
gsfan 22:9b077e2823ce 865 strcpy(cmd, "AT+DNS=1," GS_DNSNAME);
gsfan 22:9b077e2823ce 866 }
gsfan 22:9b077e2823ce 867 if (command(cmd, GSRES_NORMAL)) return -1;
gsfan 0:2f6062c6d018 868
gsfan 0:2f6062c6d018 869 switch (sec) {
gsfan 0:2f6062c6d018 870 case GSSEC_NONE:
gsfan 0:2f6062c6d018 871 case GSSEC_OPEN:
gsfan 0:2f6062c6d018 872 case GSSEC_WEP:
gsfan 0:2f6062c6d018 873 sprintf(cmd, "AT+WAUTH=%d", sec);
gsfan 0:2f6062c6d018 874 command(cmd, GSRES_NORMAL);
gsfan 22:9b077e2823ce 875 if (sec != GSSEC_NONE) {
gsfan 22:9b077e2823ce 876 sprintf(cmd, "AT+WWEP1=%s", pass);
gsfan 22:9b077e2823ce 877 command(cmd, GSRES_NORMAL);
gsfan 22:9b077e2823ce 878 wait_ms(100);
gsfan 22:9b077e2823ce 879 }
gsfan 0:2f6062c6d018 880 sprintf(cmd, "AT+WA=%s", ssid);
gsfan 0:2f6062c6d018 881 r = command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
gsfan 0:2f6062c6d018 882 break;
gsfan 0:2f6062c6d018 883 default:
gsfan 0:2f6062c6d018 884 DBG("Can't use security\r\n");
gsfan 0:2f6062c6d018 885 r = -1;
gsfan 0:2f6062c6d018 886 break;
gsfan 0:2f6062c6d018 887 }
gsfan 0:2f6062c6d018 888
gsfan 0:2f6062c6d018 889 if (r == 0) _connect = true;
gsfan 0:2f6062c6d018 890 return r;
gsfan 0:2f6062c6d018 891 }
gsfan 0:2f6062c6d018 892
gsfan 0:2f6062c6d018 893 int GSwifi::disconnect () {
gsfan 0:2f6062c6d018 894 int i;
gsfan 0:2f6062c6d018 895
gsfan 0:2f6062c6d018 896 _connect = false;
gsfan 0:2f6062c6d018 897 for (i = 0; i < 16; i ++) {
gsfan 0:2f6062c6d018 898 _gs_sock[i].connect = false;
gsfan 0:2f6062c6d018 899 }
gsfan 0:2f6062c6d018 900 command("AT+NCLOSEALL", GSRES_NORMAL);
gsfan 0:2f6062c6d018 901 command("AT+WD", GSRES_NORMAL);
gsfan 0:2f6062c6d018 902 command("AT+NDHCP=0", GSRES_NORMAL);
gsfan 0:2f6062c6d018 903 wait_ms(100);
gsfan 0:2f6062c6d018 904 return 0;
gsfan 0:2f6062c6d018 905 }
gsfan 0:2f6062c6d018 906
gsfan 28:fbba4c58d14c 907 int GSwifi::reconnect () {
gsfan 28:fbba4c58d14c 908 int r;
gsfan 28:fbba4c58d14c 909 char cmd[GS_CMD_SIZE];
gsfan 28:fbba4c58d14c 910
gsfan 28:fbba4c58d14c 911 if (_connect || _status != GSSTAT_READY) return -1;
gsfan 28:fbba4c58d14c 912 if (!_ssid) return -1;
gsfan 28:fbba4c58d14c 913
gsfan 28:fbba4c58d14c 914 switch (_sec) {
gsfan 28:fbba4c58d14c 915 case GSSEC_WPS_BUTTON:
gsfan 28:fbba4c58d14c 916 case GSSEC_WPS_PIN:
gsfan 28:fbba4c58d14c 917 sprintf(cmd, "AT+WPAPSK=%s,%s", _ssid, _pass);
gsfan 28:fbba4c58d14c 918 command(cmd, GSRES_NORMAL, GS_TIMEOUT2);
gsfan 28:fbba4c58d14c 919 wait_ms(100);
gsfan 28:fbba4c58d14c 920 case GSSEC_NONE:
gsfan 28:fbba4c58d14c 921 case GSSEC_OPEN:
gsfan 28:fbba4c58d14c 922 case GSSEC_WEP:
gsfan 28:fbba4c58d14c 923 case GSSEC_WPA_PSK:
gsfan 28:fbba4c58d14c 924 case GSSEC_WPA_ENT:
gsfan 28:fbba4c58d14c 925 case GSSEC_WPA2_PSK:
gsfan 28:fbba4c58d14c 926 case GSSEC_WPA2_ENT:
gsfan 28:fbba4c58d14c 927 sprintf(cmd, "AT+WA=%s", _ssid);
gsfan 28:fbba4c58d14c 928 r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
gsfan 28:fbba4c58d14c 929 break;
gsfan 28:fbba4c58d14c 930 default:
gsfan 28:fbba4c58d14c 931 DBG("Can't use security\r\n");
gsfan 28:fbba4c58d14c 932 r = -1;
gsfan 28:fbba4c58d14c 933 break;
gsfan 28:fbba4c58d14c 934 }
gsfan 35:515ec79792d3 935
gsfan 35:515ec79792d3 936 if (r == 0) _connect = true;
gsfan 28:fbba4c58d14c 937 return r;
gsfan 28:fbba4c58d14c 938 }
gsfan 28:fbba4c58d14c 939
gsfan 35:515ec79792d3 940 int GSwifi::setAddress (char *name) {
gsfan 35:515ec79792d3 941 char cmd[GS_CMD_SIZE];
gsfan 0:2f6062c6d018 942
gsfan 35:515ec79792d3 943 if (name) {
gsfan 35:515ec79792d3 944 sprintf(cmd, "AT+NDHCP=1,%s", name);
gsfan 35:515ec79792d3 945 } else {
gsfan 35:515ec79792d3 946 strcpy(cmd, "AT+NDHCP=1," GS_DHCPNAME);
gsfan 35:515ec79792d3 947 }
gsfan 35:515ec79792d3 948 if (command(cmd, GSRES_DHCP), GS_TIMEOUT2) return -1;
gsfan 0:2f6062c6d018 949 if (_ipaddr.isNull()) return -1;
gsfan 0:2f6062c6d018 950 return 0;
gsfan 0:2f6062c6d018 951 }
gsfan 0:2f6062c6d018 952
gsfan 0:2f6062c6d018 953 int GSwifi::setAddress (IpAddr ipaddr, IpAddr netmask, IpAddr gateway, IpAddr nameserver) {
gsfan 0:2f6062c6d018 954 int r;
gsfan 0:2f6062c6d018 955 char cmd[GS_CMD_SIZE];
gsfan 0:2f6062c6d018 956
gsfan 0:2f6062c6d018 957 command("AT+NDHCP=0", GSRES_NORMAL);
gsfan 0:2f6062c6d018 958 wait_ms(100);
gsfan 0:2f6062c6d018 959
gsfan 0:2f6062c6d018 960 sprintf(cmd, "AT+NSET=%d.%d.%d.%d,%d.%d.%d.%d,%d.%d.%d.%d",
gsfan 0:2f6062c6d018 961 ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3],
gsfan 0:2f6062c6d018 962 netmask[0], netmask[1], netmask[2], netmask[3],
gsfan 0:2f6062c6d018 963 gateway[0], gateway[1], gateway[2], gateway[3]);
gsfan 0:2f6062c6d018 964 r = command(cmd, GSRES_NORMAL);
gsfan 0:2f6062c6d018 965 if (r) return -1;
gsfan 0:2f6062c6d018 966 _ipaddr = ipaddr;
gsfan 0:2f6062c6d018 967 _netmask = netmask;
gsfan 0:2f6062c6d018 968 _gateway = gateway;
gsfan 0:2f6062c6d018 969
gsfan 0:2f6062c6d018 970 if (ipaddr != nameserver) {
gsfan 0:2f6062c6d018 971 sprintf(cmd, "AT+DNSSET=%d.%d.%d.%d",
gsfan 0:2f6062c6d018 972 nameserver[0], nameserver[1], nameserver[2], nameserver[3]);
gsfan 0:2f6062c6d018 973 r = command(cmd, GSRES_NORMAL);
gsfan 0:2f6062c6d018 974 }
gsfan 0:2f6062c6d018 975 return r;
gsfan 0:2f6062c6d018 976 }
gsfan 0:2f6062c6d018 977
gsfan 1:b127c6c5241d 978 int GSwifi::getAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) {
gsfan 1:b127c6c5241d 979 ipaddr = _ipaddr;
gsfan 1:b127c6c5241d 980 netmask = _netmask;
gsfan 1:b127c6c5241d 981 gateway = _gateway;
gsfan 1:b127c6c5241d 982 nameserver = _nameserver;
gsfan 2:c6e0e97901b3 983 return 0;
gsfan 1:b127c6c5241d 984 }
gsfan 1:b127c6c5241d 985
gsfan 29:1c4419512941 986 int GSwifi::getMacAddress (char *mac) {
gsfan 35:515ec79792d3 987
gsfan 35:515ec79792d3 988 command("AT+NMAC=?", GSRES_MACADDRESS);
gsfan 35:515ec79792d3 989 if (_mac[0] || _mac[1] || _mac[2] || _mac[3] || _mac[4] || _mac[5]) {
gsfan 35:515ec79792d3 990 memcpy(mac, _mac, 6);
gsfan 35:515ec79792d3 991 return 0;
gsfan 35:515ec79792d3 992 }
gsfan 35:515ec79792d3 993 return -1;
gsfan 26:b347ee3a1087 994 }
gsfan 26:b347ee3a1087 995
gsfan 0:2f6062c6d018 996 int GSwifi::getHostByName (const char* name, IpAddr &addr) {
gsfan 0:2f6062c6d018 997 char cmd[GS_CMD_SIZE];
gsfan 0:2f6062c6d018 998
gsfan 0:2f6062c6d018 999 if (! _connect || _status != GSSTAT_READY) return -1;
gsfan 0:2f6062c6d018 1000
gsfan 0:2f6062c6d018 1001 sprintf(cmd, "AT+DNSLOOKUP=%s", name);
gsfan 0:2f6062c6d018 1002 if (command(cmd, GSRES_DNSLOOKUP)) return -1;
gsfan 0:2f6062c6d018 1003
gsfan 0:2f6062c6d018 1004 addr = _resolv;
gsfan 0:2f6062c6d018 1005 return 0;
gsfan 0:2f6062c6d018 1006 }
gsfan 0:2f6062c6d018 1007
gsfan 0:2f6062c6d018 1008 int GSwifi::getHostByName (Host &host) {
gsfan 0:2f6062c6d018 1009 char cmd[GS_CMD_SIZE];
gsfan 0:2f6062c6d018 1010
gsfan 0:2f6062c6d018 1011 if (! _connect || _status != GSSTAT_READY) return -1;
gsfan 0:2f6062c6d018 1012
gsfan 0:2f6062c6d018 1013 sprintf(cmd, "AT+DNSLOOKUP=%s", host.getName());
gsfan 0:2f6062c6d018 1014 if (command(cmd, GSRES_DNSLOOKUP)) return -1;
gsfan 0:2f6062c6d018 1015
gsfan 0:2f6062c6d018 1016 host.setIp(_resolv);
gsfan 0:2f6062c6d018 1017 return 0;
gsfan 0:2f6062c6d018 1018 }
gsfan 0:2f6062c6d018 1019
gsfan 37:e61ea8267415 1020 bool GSwifi::isConnected () {
gsfan 37:e61ea8267415 1021 return _connect;
gsfan 37:e61ea8267415 1022 }
gsfan 37:e61ea8267415 1023
gsfan 37:e61ea8267415 1024 GSwifi::GSSTATUS GSwifi::getStatus () {
gsfan 37:e61ea8267415 1025 return _status;
gsfan 37:e61ea8267415 1026 }
gsfan 37:e61ea8267415 1027
gsfan 37:e61ea8267415 1028 int GSwifi::getRssi () {
gsfan 37:e61ea8267415 1029 if (command("AT+WRSSI=?", GSRES_RSSI)) {
gsfan 37:e61ea8267415 1030 return 0;
gsfan 37:e61ea8267415 1031 }
gsfan 37:e61ea8267415 1032 return _rssi;
gsfan 37:e61ea8267415 1033 }
gsfan 37:e61ea8267415 1034
gsfan 37:e61ea8267415 1035 int GSwifi::setBaud (int baud) {
gsfan 37:e61ea8267415 1036 char cmd[GS_CMD_SIZE];
gsfan 37:e61ea8267415 1037
gsfan 37:e61ea8267415 1038 if (_status != GSSTAT_READY || acquireUart()) return -1;
gsfan 37:e61ea8267415 1039
gsfan 37:e61ea8267415 1040 _baud = baud;
gsfan 37:e61ea8267415 1041 sprintf(cmd, "ATB=%d\r\n", _baud);
gsfan 37:e61ea8267415 1042 _gs_puts(cmd);
gsfan 37:e61ea8267415 1043 releaseUart();
gsfan 37:e61ea8267415 1044 wait_ms(100);
gsfan 37:e61ea8267415 1045 _gs.baud(_baud);
gsfan 37:e61ea8267415 1046 _buf_cmd.flush();
gsfan 37:e61ea8267415 1047 return 0;
gsfan 37:e61ea8267415 1048 }
gsfan 37:e61ea8267415 1049
gsfan 37:e61ea8267415 1050 int GSwifi::setRegion (int reg) {
gsfan 37:e61ea8267415 1051 char cmd[GS_CMD_SIZE];
gsfan 37:e61ea8267415 1052
gsfan 37:e61ea8267415 1053 if (_status != GSSTAT_READY) return -1;
gsfan 37:e61ea8267415 1054
gsfan 37:e61ea8267415 1055 sprintf(cmd, "AT+WREGDOMAIN=%d", reg);
gsfan 37:e61ea8267415 1056 return command(cmd, GSRES_NORMAL);
gsfan 37:e61ea8267415 1057 }
gsfan 37:e61ea8267415 1058
gsfan 37:e61ea8267415 1059 #ifndef GS_LIB_TINY
gsfan 0:2f6062c6d018 1060 int GSwifi::setRFPower (int power) {
gsfan 0:2f6062c6d018 1061 char cmd[GS_CMD_SIZE];
gsfan 0:2f6062c6d018 1062
gsfan 0:2f6062c6d018 1063 if (power < 0 || power > 7) return -1;
gsfan 0:2f6062c6d018 1064
gsfan 0:2f6062c6d018 1065 sprintf(cmd, "AT+WP=%d", power);
gsfan 0:2f6062c6d018 1066 return command(cmd, GSRES_NORMAL);
gsfan 0:2f6062c6d018 1067 }
gsfan 0:2f6062c6d018 1068
gsfan 2:c6e0e97901b3 1069 int GSwifi::powerSave (int active, int save) {
gsfan 0:2f6062c6d018 1070 char cmd[GS_CMD_SIZE];
gsfan 0:2f6062c6d018 1071
gsfan 0:2f6062c6d018 1072 if (_status != GSSTAT_READY) return -1;
gsfan 0:2f6062c6d018 1073
gsfan 2:c6e0e97901b3 1074 sprintf(cmd, "AT+WRXACTIVE=%d", active);
gsfan 0:2f6062c6d018 1075 command(cmd, GSRES_NORMAL);
gsfan 3:1345daf4ec1a 1076 sprintf(cmd, "AT+WRXPS=%d", save);
gsfan 0:2f6062c6d018 1077 return command(cmd, GSRES_NORMAL);
gsfan 0:2f6062c6d018 1078 }
gsfan 0:2f6062c6d018 1079
gsfan 0:2f6062c6d018 1080 int GSwifi::standby (int msec) {
gsfan 26:b347ee3a1087 1081 int i;
gsfan 0:2f6062c6d018 1082 char cmd[GS_CMD_SIZE];
gsfan 0:2f6062c6d018 1083
gsfan 0:2f6062c6d018 1084 if (_status != GSSTAT_READY && _status != GSSTAT_WAKEUP) return -1;
gsfan 0:2f6062c6d018 1085
gsfan 26:b347ee3a1087 1086 if (_status == GSSTAT_READY) {
gsfan 0:2f6062c6d018 1087 command("AT+WRXACTIVE=0", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1088 command("AT+STORENWCONN", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1089 } else {
gsfan 0:2f6062c6d018 1090 command("ATE0", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1091 if (_rts) {
gsfan 0:2f6062c6d018 1092 command("AT&R1", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1093 }
gsfan 0:2f6062c6d018 1094 }
gsfan 26:b347ee3a1087 1095 for (i = 0; i < 16; i ++) {
gsfan 26:b347ee3a1087 1096 _gs_sock[i].connect = false;
gsfan 26:b347ee3a1087 1097 }
gsfan 0:2f6062c6d018 1098 _status = GSSTAT_STANDBY;
gsfan 0:2f6062c6d018 1099 sprintf(cmd, "AT+PSSTBY=%d,0,0,0", msec); // go standby
gsfan 0:2f6062c6d018 1100 return command(cmd, GSRES_NORMAL, 0);
gsfan 0:2f6062c6d018 1101 }
gsfan 0:2f6062c6d018 1102
gsfan 0:2f6062c6d018 1103 int GSwifi::wakeup () {
gsfan 0:2f6062c6d018 1104
gsfan 26:b347ee3a1087 1105 if (_status == GSSTAT_STANDBY && _alarm != NULL) {
gsfan 25:f6e5622d2930 1106 Timer timeout;
gsfan 26:b347ee3a1087 1107 _alarm->output(); // low
gsfan 25:f6e5622d2930 1108 _alarm->write(0);
gsfan 25:f6e5622d2930 1109 timeout.start();
gsfan 25:f6e5622d2930 1110 while (_status != GSSTAT_WAKEUP && timeout.read() < GS_TIMEOUT) {
gsfan 25:f6e5622d2930 1111 poll();
gsfan 25:f6e5622d2930 1112 }
gsfan 25:f6e5622d2930 1113 timeout.stop();
gsfan 26:b347ee3a1087 1114 _alarm->input(); // high
gsfan 28:fbba4c58d14c 1115 _alarm->mode(PullUp);
gsfan 25:f6e5622d2930 1116 }
gsfan 25:f6e5622d2930 1117
gsfan 0:2f6062c6d018 1118 if (_status == GSSTAT_WAKEUP) {
gsfan 0:2f6062c6d018 1119 _status = GSSTAT_READY;
gsfan 0:2f6062c6d018 1120 command("ATE0", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1121 if (_rts) {
gsfan 0:2f6062c6d018 1122 command("AT&R1", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1123 }
gsfan 0:2f6062c6d018 1124 #ifdef GS_BULK
gsfan 0:2f6062c6d018 1125 command("AT+BDATA=1", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1126 #endif
gsfan 0:2f6062c6d018 1127 command("AT+RESTORENWCONN", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1128 wait_ms(100);
gsfan 0:2f6062c6d018 1129 return command("AT+WRXACTIVE=1", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1130 } else
gsfan 0:2f6062c6d018 1131 if (_status == GSSTAT_DEEPSLEEP) {
gsfan 0:2f6062c6d018 1132 _status = GSSTAT_READY;
gsfan 0:2f6062c6d018 1133 return command("AT", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1134 }
gsfan 0:2f6062c6d018 1135 return -1;
gsfan 0:2f6062c6d018 1136 }
gsfan 0:2f6062c6d018 1137
gsfan 0:2f6062c6d018 1138 int GSwifi::deepSleep () {
gsfan 0:2f6062c6d018 1139
gsfan 0:2f6062c6d018 1140 if (_status != GSSTAT_READY) return -1;
gsfan 0:2f6062c6d018 1141
gsfan 0:2f6062c6d018 1142 _status = GSSTAT_DEEPSLEEP;
gsfan 0:2f6062c6d018 1143 return command("AT+PSDPSLEEP", GSRES_NORMAL, 0); // go deep sleep
gsfan 0:2f6062c6d018 1144 }
gsfan 0:2f6062c6d018 1145
gsfan 5:6def1d0df519 1146 int GSwifi::ntpdate (Host host, int sec) {
gsfan 5:6def1d0df519 1147 char cmd[GS_CMD_SIZE];
gsfan 5:6def1d0df519 1148
gsfan 5:6def1d0df519 1149 if (! _connect || _status != GSSTAT_READY) return -1;
gsfan 5:6def1d0df519 1150
gsfan 5:6def1d0df519 1151 if (host.getIp().isNull()) {
gsfan 5:6def1d0df519 1152 if (getHostByName(host)) {
gsfan 5:6def1d0df519 1153 if (getHostByName(host)) return -1;
gsfan 5:6def1d0df519 1154 }
gsfan 5:6def1d0df519 1155 }
gsfan 5:6def1d0df519 1156
gsfan 5:6def1d0df519 1157 if (sec) {
gsfan 5:6def1d0df519 1158 sprintf(cmd, "AT+NTIMESYNC=1,%d.%d.%d.%d,%d,1,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3],
gsfan 5:6def1d0df519 1159 GS_TIMEOUT / 1000, sec);
gsfan 5:6def1d0df519 1160 } else {
gsfan 5:6def1d0df519 1161 sprintf(cmd, "AT+NTIMESYNC=1,%d.%d.%d.%d,%d,0", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3],
gsfan 5:6def1d0df519 1162 GS_TIMEOUT / 1000);
gsfan 5:6def1d0df519 1163 }
gsfan 5:6def1d0df519 1164 return command(cmd, GSRES_NORMAL);
gsfan 5:6def1d0df519 1165 }
gsfan 5:6def1d0df519 1166
gsfan 5:6def1d0df519 1167 int GSwifi::setTime (time_t time) {
gsfan 5:6def1d0df519 1168 char cmd[GS_CMD_SIZE];
gsfan 5:6def1d0df519 1169 struct tm *t;
gsfan 5:6def1d0df519 1170
gsfan 5:6def1d0df519 1171 if (_status != GSSTAT_READY) return -1;
gsfan 5:6def1d0df519 1172
gsfan 5:6def1d0df519 1173 t = localtime(&time);
gsfan 5:6def1d0df519 1174 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);
gsfan 5:6def1d0df519 1175 return command(cmd, GSRES_NORMAL);
gsfan 5:6def1d0df519 1176 }
gsfan 5:6def1d0df519 1177
gsfan 5:6def1d0df519 1178 time_t GSwifi::getTime () {
gsfan 5:6def1d0df519 1179
gsfan 5:6def1d0df519 1180 if (command("AT+GETTIME=?", GSRES_TIME)) {
gsfan 5:6def1d0df519 1181 return 0;
gsfan 5:6def1d0df519 1182 }
gsfan 5:6def1d0df519 1183 return _time;
gsfan 5:6def1d0df519 1184 }
gsfan 5:6def1d0df519 1185
gsfan 6:a423f0d197de 1186 int GSwifi::gpioOut (int port, int out) {
gsfan 6:a423f0d197de 1187 char cmd[GS_CMD_SIZE];
gsfan 6:a423f0d197de 1188
gsfan 6:a423f0d197de 1189 if (_status != GSSTAT_READY) return -1;
gsfan 6:a423f0d197de 1190
gsfan 6:a423f0d197de 1191 sprintf(cmd, "AT+DGPIO=%d,%d", port, out);
gsfan 6:a423f0d197de 1192 return command(cmd, GSRES_NORMAL);
gsfan 6:a423f0d197de 1193 }
gsfan 6:a423f0d197de 1194
gsfan 19:cad912f5a6ba 1195 int GSwifi::certAdd (const char *name, const char *cert, int len) {
gsfan 0:2f6062c6d018 1196 int i;
gsfan 0:2f6062c6d018 1197 char cmd[GS_CMD_SIZE];
gsfan 0:2f6062c6d018 1198
gsfan 0:2f6062c6d018 1199 if (! _connect || _status != GSSTAT_READY) return -1;
gsfan 0:2f6062c6d018 1200
gsfan 0:2f6062c6d018 1201 sprintf(cmd, "AT+TCERTADD=%s,1,%d,1", name, len); // Hex, ram
gsfan 0:2f6062c6d018 1202 command(cmd, GSRES_NORMAL);
gsfan 0:2f6062c6d018 1203
gsfan 26:b347ee3a1087 1204 resetResponse(GSRES_NORMAL);
gsfan 1:b127c6c5241d 1205 _gs_putc(0x1b);
gsfan 1:b127c6c5241d 1206 _gs_putc('W');
gsfan 0:2f6062c6d018 1207 for (i = 0; i < len; i ++) {
gsfan 1:b127c6c5241d 1208 _gs_putc(cert[i]);
gsfan 0:2f6062c6d018 1209 }
gsfan 26:b347ee3a1087 1210 return waitResponse(GS_TIMEOUT);
gsfan 0:2f6062c6d018 1211 }
gsfan 0:2f6062c6d018 1212
gsfan 22:9b077e2823ce 1213 int GSwifi::provisioning (char *user, char *pass) {
gsfan 22:9b077e2823ce 1214 char cmd[GS_CMD_SIZE];
gsfan 22:9b077e2823ce 1215
gsfan 22:9b077e2823ce 1216 if (_status != GSSTAT_READY) return -1;
gsfan 22:9b077e2823ce 1217
gsfan 22:9b077e2823ce 1218 sprintf(cmd, "AT+WEBPROV=%s,%s", user, pass);
gsfan 22:9b077e2823ce 1219 return command(cmd, GSRES_NORMAL);
gsfan 22:9b077e2823ce 1220 }
gsfan 37:e61ea8267415 1221 #endif
gsfan 25:f6e5622d2930 1222
gsfan 20:151b5a4fdd29 1223 int GSwifi::from_hex (int ch) {
gsfan 20:151b5a4fdd29 1224 return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
gsfan 20:151b5a4fdd29 1225 }
gsfan 20:151b5a4fdd29 1226
gsfan 20:151b5a4fdd29 1227 int GSwifi::to_hex (int code) {
gsfan 20:151b5a4fdd29 1228 static char hex[] = "0123456789abcdef";
gsfan 20:151b5a4fdd29 1229 return hex[code & 15];
gsfan 20:151b5a4fdd29 1230 }
gsfan 20:151b5a4fdd29 1231
gsfan 0:2f6062c6d018 1232 int GSwifi::x2i (char c) {
gsfan 0:2f6062c6d018 1233 if (c >= '0' && c <= '9') {
gsfan 0:2f6062c6d018 1234 return c - '0';
gsfan 0:2f6062c6d018 1235 } else
gsfan 0:2f6062c6d018 1236 if (c >= 'A' && c <= 'F') {
gsfan 0:2f6062c6d018 1237 return c - 'A' + 10;
gsfan 0:2f6062c6d018 1238 } else
gsfan 0:2f6062c6d018 1239 if (c >= 'a' && c <= 'f') {
gsfan 0:2f6062c6d018 1240 return c - 'a' + 10;
gsfan 0:2f6062c6d018 1241 }
gsfan 0:2f6062c6d018 1242 return 0;
gsfan 0:2f6062c6d018 1243 }
gsfan 0:2f6062c6d018 1244
gsfan 0:2f6062c6d018 1245 char GSwifi::i2x (int i) {
gsfan 0:2f6062c6d018 1246 if (i >= 0 && i <= 9) {
gsfan 0:2f6062c6d018 1247 return i + '0';
gsfan 0:2f6062c6d018 1248 } else
gsfan 0:2f6062c6d018 1249 if (i >= 10 && i <= 15) {
gsfan 0:2f6062c6d018 1250 return i - 10 + 'A';
gsfan 0:2f6062c6d018 1251 }
gsfan 37:e61ea8267415 1252 return '0';
gsfan 0:2f6062c6d018 1253 }
gsfan 0:2f6062c6d018 1254
gsfan 25:f6e5622d2930 1255
gsfan 22:9b077e2823ce 1256 #ifdef DEBUG
gsfan 0:2f6062c6d018 1257 // for test
gsfan 23:a783c62c36d0 1258 void GSwifi::dump () {
gsfan 23:a783c62c36d0 1259 int i;
gsfan 23:a783c62c36d0 1260
gsfan 23:a783c62c36d0 1261 DBG("GS mode=%d, escape=%d, cid=%d\r\n", _gs_mode, _escape, _cid);
gsfan 23:a783c62c36d0 1262 for (i = 0; i < 16; i ++) {
gsfan 35:515ec79792d3 1263 DBG("[%d] ", i);
gsfan 35:515ec79792d3 1264 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());
gsfan 35:515ec79792d3 1265 DBG(" %x, %x\r\n", &_gs_sock[i], _gs_sock[i].data);
gsfan 35:515ec79792d3 1266 #ifdef GS_ENABLE_HTTPD
gsfan 23:a783c62c36d0 1267 if (_gs_sock[i].protocol == GSPROT_HTTPD) {
gsfan 23:a783c62c36d0 1268 DBG(" mode=%d, type=%d, len=%d\r\n", i, _httpd[i].mode, _httpd[i].type, _httpd[i].len);
gsfan 35:515ec79792d3 1269 DBG(" %x, %x\r\n", &_httpd[i], _httpd[i].buf);
gsfan 23:a783c62c36d0 1270 }
gsfan 35:515ec79792d3 1271 #endif
gsfan 23:a783c62c36d0 1272 }
gsfan 23:a783c62c36d0 1273 }
gsfan 0:2f6062c6d018 1274
gsfan 0:2f6062c6d018 1275 void GSwifi::test () {
gsfan 2:c6e0e97901b3 1276 /*
gsfan 0:2f6062c6d018 1277 command(NULL, GSRES_NORMAL);
gsfan 0:2f6062c6d018 1278 wait_ms(100);
gsfan 0:2f6062c6d018 1279 command("AT+NCLOSEALL", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1280 _connect = true;
gsfan 2:c6e0e97901b3 1281 */
gsfan 2:c6e0e97901b3 1282 command("AT+WRXACTIVE=1", GSRES_NORMAL);
gsfan 0:2f6062c6d018 1283 }
gsfan 0:2f6062c6d018 1284
gsfan 0:2f6062c6d018 1285 int GSwifi::getc() {
gsfan 0:2f6062c6d018 1286 char c;
gsfan 25:f6e5622d2930 1287 if (! _buf_cmd.isEmpty()) {
gsfan 25:f6e5622d2930 1288 _buf_cmd.dequeue(&c);
gsfan 0:2f6062c6d018 1289 }
gsfan 0:2f6062c6d018 1290 /*
gsfan 0:2f6062c6d018 1291 } else
gsfan 0:2f6062c6d018 1292 if (_gs_sock[0].data != NULL) {
gsfan 25:f6e5622d2930 1293 _gs_sock[0].data->dequeue(&c);
gsfan 0:2f6062c6d018 1294 }
gsfan 0:2f6062c6d018 1295 */
gsfan 0:2f6062c6d018 1296 return c;
gsfan 0:2f6062c6d018 1297 }
gsfan 0:2f6062c6d018 1298
gsfan 0:2f6062c6d018 1299 void GSwifi::putc(char c) {
gsfan 1:b127c6c5241d 1300 _gs_putc(c);
gsfan 0:2f6062c6d018 1301 }
gsfan 0:2f6062c6d018 1302
gsfan 0:2f6062c6d018 1303 int GSwifi::readable() {
gsfan 25:f6e5622d2930 1304 return ! _buf_cmd.isEmpty();
gsfan 0:2f6062c6d018 1305 // return _buf_cmd.use() || (_gs_sock[0].data != NULL && _gs_sock[0].data->use());
gsfan 0:2f6062c6d018 1306 }
gsfan 18:4b97804c37d1 1307 #endif