private fork

Fork of GSwifiInterface by gs fan

Committer:
gsfan
Date:
Sun Jan 27 14:31:19 2013 +0000
Revision:
5:78943b3945b5
Parent:
Wifly/Wifly.cpp@4:0bcec6272784
Child:
7:f94c59d0c735
Child:
8:64184a968e3b
1st build

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gsfan 5:78943b3945b5 1 /* Copyright (C) 2012 mbed.org, MIT License
gsfan 5:78943b3945b5 2 *
gsfan 5:78943b3945b5 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
gsfan 5:78943b3945b5 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
gsfan 5:78943b3945b5 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
gsfan 5:78943b3945b5 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
gsfan 5:78943b3945b5 7 * furnished to do so, subject to the following conditions:
gsfan 5:78943b3945b5 8 *
gsfan 5:78943b3945b5 9 * The above copyright notice and this permission notice shall be included in all copies or
gsfan 5:78943b3945b5 10 * substantial portions of the Software.
gsfan 5:78943b3945b5 11 *
gsfan 5:78943b3945b5 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
gsfan 5:78943b3945b5 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
gsfan 5:78943b3945b5 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
gsfan 5:78943b3945b5 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
gsfan 5:78943b3945b5 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
gsfan 5:78943b3945b5 17 */
gsfan 5:78943b3945b5 18 /* Copyright (C) 2013 gsfan, MIT License
gsfan 5:78943b3945b5 19 * port to the GainSpan Wi-FI module GS1011
gsfan 5:78943b3945b5 20 */
gsfan 5:78943b3945b5 21
gsfan 5:78943b3945b5 22 #include "mbed.h"
gsfan 5:78943b3945b5 23 #include "GSwifi.h"
gsfan 5:78943b3945b5 24 #include <string>
gsfan 5:78943b3945b5 25 #include <algorithm>
gsfan 5:78943b3945b5 26
gsfan 5:78943b3945b5 27 GSwifi * GSwifi::_inst;
gsfan 5:78943b3945b5 28
gsfan 5:78943b3945b5 29 GSwifi::GSwifi( PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, const char * ssid, const char * phrase, Security sec):
gsfan 5:78943b3945b5 30 _uart(tx, rx), _reset(reset), _buf_gswifi(CFG_CMD_SIZE)
gsfan 5:78943b3945b5 31 {
gsfan 5:78943b3945b5 32 memset(&_state, 0, sizeof(_state));
gsfan 5:78943b3945b5 33 memset(&_con, 0, sizeof(_con));
gsfan 5:78943b3945b5 34 _state.sec = sec;
gsfan 5:78943b3945b5 35 _state.acid = -1;
gsfan 5:78943b3945b5 36
gsfan 5:78943b3945b5 37 // change all ' ' in '$' in the ssid and the passphrase
gsfan 5:78943b3945b5 38 strncpy(_ssid, ssid, sizeof(_ssid));
gsfan 5:78943b3945b5 39 for (int i = 0; i < strlen(ssid); i++) {
gsfan 5:78943b3945b5 40 if (_ssid[i] == ' ')
gsfan 5:78943b3945b5 41 _ssid[i] = '$';
gsfan 5:78943b3945b5 42 }
gsfan 5:78943b3945b5 43 strncpy(_phrase, phrase, sizeof(_phrase));
gsfan 5:78943b3945b5 44 for (int i = 0; i < strlen(phrase); i++) {
gsfan 5:78943b3945b5 45 if (_phrase[i] == ' ')
gsfan 5:78943b3945b5 46 _phrase[i] = '$';
gsfan 5:78943b3945b5 47 }
gsfan 5:78943b3945b5 48
gsfan 5:78943b3945b5 49 _inst = this;
gsfan 5:78943b3945b5 50 _state.mode = MODE_COMMAND;
gsfan 5:78943b3945b5 51
gsfan 5:78943b3945b5 52 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
gsfan 5:78943b3945b5 53 if (cts == p12) { // CTS input (P0_17)
gsfan 5:78943b3945b5 54 LPC_UART1->MCR |= (1<<7); // CTSEN
gsfan 5:78943b3945b5 55 LPC_PINCON->PINSEL1 &= ~(3 << 2);
gsfan 5:78943b3945b5 56 LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS
gsfan 5:78943b3945b5 57 }
gsfan 5:78943b3945b5 58 if (rts == P0_22) { // RTS output (P0_22)
gsfan 5:78943b3945b5 59 LPC_UART1->MCR |= (1<<6); // RTSEN
gsfan 5:78943b3945b5 60 LPC_PINCON->PINSEL1 &= ~(3 << 12);
gsfan 5:78943b3945b5 61 LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS
gsfan 5:78943b3945b5 62 _rts = true;
gsfan 5:78943b3945b5 63 } else {
gsfan 5:78943b3945b5 64 _rts = false;
gsfan 5:78943b3945b5 65 }
gsfan 5:78943b3945b5 66 #elif defined(TARGET_LPC11U24)
gsfan 5:78943b3945b5 67 if (cts == p21) { // CTS input (P0_7)
gsfan 5:78943b3945b5 68 LPC_USART->MCR |= (1<<7); // CTSEN
gsfan 5:78943b3945b5 69 LPC_IOCON->PIO0_7 &= ~0x07;
gsfan 5:78943b3945b5 70 LPC_IOCON->PIO0_7 |= 0x01; // UART CTS
gsfan 5:78943b3945b5 71 }
gsfan 5:78943b3945b5 72 if (rts == p22) { // RTS output (P0_17)
gsfan 5:78943b3945b5 73 LPC_USART->MCR |= (1<<6); // RTSEN
gsfan 5:78943b3945b5 74 LPC_IOCON->PIO0_17 &= ~0x07;
gsfan 5:78943b3945b5 75 LPC_IOCON->PIO0_17 |= 0x01; // UART RTS
gsfan 5:78943b3945b5 76 _rts = true;
gsfan 5:78943b3945b5 77 } else {
gsfan 5:78943b3945b5 78 _rts = false;
gsfan 5:78943b3945b5 79 }
gsfan 5:78943b3945b5 80 #endif
gsfan 5:78943b3945b5 81 _uart.baud(CFG_UART_BAUD);
gsfan 5:78943b3945b5 82 _uart.attach(this, &GSwifi::handler_rx);
gsfan 5:78943b3945b5 83 this->reset();
gsfan 5:78943b3945b5 84 }
gsfan 5:78943b3945b5 85
gsfan 5:78943b3945b5 86 bool GSwifi::join()
gsfan 5:78943b3945b5 87 {
gsfan 5:78943b3945b5 88 bool r;
gsfan 5:78943b3945b5 89 char cmd[CFG_CMD_SIZE];
gsfan 5:78943b3945b5 90
gsfan 5:78943b3945b5 91 send("\r\n", 2);
gsfan 5:78943b3945b5 92 if (sendCommand("ATE0") == false) return -1;
gsfan 5:78943b3945b5 93 if (_rts) {
gsfan 5:78943b3945b5 94 sendCommand("AT&K0");
gsfan 5:78943b3945b5 95 sendCommand("AT&R1");
gsfan 5:78943b3945b5 96 }
gsfan 5:78943b3945b5 97
gsfan 5:78943b3945b5 98 disconnect();
gsfan 5:78943b3945b5 99 sendCommand("AT+WREGDOMAIN=" CFG_WREGDOMAIN);
gsfan 5:78943b3945b5 100 sendCommand("AT+BDATA=1");
gsfan 5:78943b3945b5 101 sendCommand("AT+WM=0"); // infrastructure
gsfan 5:78943b3945b5 102 wait_ms(100);
gsfan 5:78943b3945b5 103 if (_state.dhcp && _state.sec != SEC_WPS_BUTTON) {
gsfan 5:78943b3945b5 104 sendCommand("AT+NDHCP=1");
gsfan 5:78943b3945b5 105 } else {
gsfan 5:78943b3945b5 106 sendCommand("AT+NDHCP=0");
gsfan 5:78943b3945b5 107 }
gsfan 5:78943b3945b5 108
gsfan 5:78943b3945b5 109 switch (_state.sec) {
gsfan 5:78943b3945b5 110 case SEC_NONE:
gsfan 5:78943b3945b5 111 case SEC_OPEN:
gsfan 5:78943b3945b5 112 case SEC_WEP:
gsfan 5:78943b3945b5 113 sprintf(cmd, "AT+WAUTH=%d", _ssid);
gsfan 5:78943b3945b5 114 sendCommand(cmd);
gsfan 5:78943b3945b5 115 if (_state.sec != SEC_NONE) {
gsfan 5:78943b3945b5 116 sprintf(cmd, "AT+WWEP1=%s", _phrase);
gsfan 5:78943b3945b5 117 sendCommand(cmd);
gsfan 5:78943b3945b5 118 wait_ms(100);
gsfan 5:78943b3945b5 119 }
gsfan 5:78943b3945b5 120 sprintf(cmd, "AT+WA=%s", _ssid);
gsfan 5:78943b3945b5 121 for (int i= 0; i < MAX_TRY_JOIN; i++) {
gsfan 5:78943b3945b5 122 r = sendCommand(cmd, RES_DHCP, CFG_TIMEOUT2);
gsfan 5:78943b3945b5 123 if (r) break;
gsfan 5:78943b3945b5 124 }
gsfan 5:78943b3945b5 125 break;
gsfan 5:78943b3945b5 126 case SEC_WPA_PSK:
gsfan 5:78943b3945b5 127 case SEC_WPA2_PSK:
gsfan 5:78943b3945b5 128 sendCommand("AT+WAUTH=0");
gsfan 5:78943b3945b5 129 sprintf(cmd, "AT+WPAPSK=%s,%s", _ssid, _phrase);
gsfan 5:78943b3945b5 130 sendCommand(cmd, RES_NORMAL, CFG_TIMEOUT2);
gsfan 5:78943b3945b5 131 wait_ms(100);
gsfan 5:78943b3945b5 132 sprintf(cmd, "AT+WA=%s", _ssid);
gsfan 5:78943b3945b5 133 for (int i= 0; i < MAX_TRY_JOIN; i++) {
gsfan 5:78943b3945b5 134 r = sendCommand(cmd, RES_DHCP, CFG_TIMEOUT2);
gsfan 5:78943b3945b5 135 if (r) break;
gsfan 5:78943b3945b5 136 }
gsfan 5:78943b3945b5 137 break;
gsfan 5:78943b3945b5 138 case SEC_WPS_BUTTON:
gsfan 5:78943b3945b5 139 sendCommand("AT+WAUTH=0");
gsfan 5:78943b3945b5 140 for (int i= 0; i < MAX_TRY_JOIN; i++) {
gsfan 5:78943b3945b5 141 r = sendCommand("AT+WWPS=1", RES_WPS, CFG_TIMEOUT2);
gsfan 5:78943b3945b5 142 if (r) break;
gsfan 5:78943b3945b5 143 }
gsfan 5:78943b3945b5 144 if (r && _state.dhcp) {
gsfan 5:78943b3945b5 145 r = sendCommand("AT+NDHCP=1", RES_DHCP, CFG_TIMEOUT2);
gsfan 5:78943b3945b5 146 }
gsfan 5:78943b3945b5 147 break;
gsfan 5:78943b3945b5 148 default:
gsfan 5:78943b3945b5 149 DBG("Can't use security\r\n");
gsfan 5:78943b3945b5 150 r = false;
gsfan 5:78943b3945b5 151 break;
gsfan 5:78943b3945b5 152 }
gsfan 5:78943b3945b5 153
gsfan 5:78943b3945b5 154 if (r) {
gsfan 5:78943b3945b5 155 if (!_state.dhcp) {
gsfan 5:78943b3945b5 156 sprintf(cmd, "AT+NSET=%s,%s,%s", _ip, _netmask, _gateway);
gsfan 5:78943b3945b5 157 sendCommand(cmd);
gsfan 5:78943b3945b5 158 sprintf(cmd, "AT+DNSSET=%s", _nameserver);
gsfan 5:78943b3945b5 159 sendCommand(cmd);
gsfan 5:78943b3945b5 160 }
gsfan 5:78943b3945b5 161
gsfan 5:78943b3945b5 162 _state.associated = true;
gsfan 5:78943b3945b5 163 INFO("ssid: %s\r\nphrase: %s\r\nsecurity: %d", _ssid, _phrase, _state.sec);
gsfan 5:78943b3945b5 164 }
gsfan 5:78943b3945b5 165
gsfan 5:78943b3945b5 166 return r;
gsfan 5:78943b3945b5 167 }
gsfan 5:78943b3945b5 168
gsfan 5:78943b3945b5 169
gsfan 5:78943b3945b5 170 bool GSwifi::gethostbyname(const char * host, char * ip)
gsfan 5:78943b3945b5 171 {
gsfan 5:78943b3945b5 172 int i, flg = 0;
gsfan 5:78943b3945b5 173 char cmd[CFG_CMD_SIZE];
gsfan 5:78943b3945b5 174
gsfan 5:78943b3945b5 175 for (i = 0; i < strlen(host); i ++) {
gsfan 5:78943b3945b5 176 if ((host[i] < '0' || host[i] > '9') && host[i] != '.') {
gsfan 5:78943b3945b5 177 flg = 1;
gsfan 5:78943b3945b5 178 break;
gsfan 5:78943b3945b5 179 }
gsfan 5:78943b3945b5 180 }
gsfan 5:78943b3945b5 181 if (!flg) {
gsfan 5:78943b3945b5 182 strncpy(ip, host, 16);
gsfan 5:78943b3945b5 183 return true;
gsfan 5:78943b3945b5 184 }
gsfan 5:78943b3945b5 185
gsfan 5:78943b3945b5 186 sprintf(cmd, "AT+DNSLOOKUP=%s", host);
gsfan 5:78943b3945b5 187 if (sendCommand(cmd, RES_DNSLOOKUP)) {
gsfan 5:78943b3945b5 188 strncpy(ip, _resolv, 16);
gsfan 5:78943b3945b5 189 return true;
gsfan 5:78943b3945b5 190 }
gsfan 5:78943b3945b5 191
gsfan 5:78943b3945b5 192 return false;
gsfan 5:78943b3945b5 193 }
gsfan 5:78943b3945b5 194
gsfan 5:78943b3945b5 195
gsfan 5:78943b3945b5 196 void GSwifi::flush(int cid)
gsfan 5:78943b3945b5 197 {
gsfan 5:78943b3945b5 198 if (cid < 0) {
gsfan 5:78943b3945b5 199 return _buf_gswifi.flush();
gsfan 5:78943b3945b5 200 } else {
gsfan 5:78943b3945b5 201 if (_con[cid].buf == NULL)
gsfan 5:78943b3945b5 202 _con[cid].buf = new CircBuffer<char>(CFG_DATA_SIZE);
gsfan 5:78943b3945b5 203 return _con[cid].buf->flush();
gsfan 5:78943b3945b5 204 }
gsfan 5:78943b3945b5 205 }
gsfan 5:78943b3945b5 206
gsfan 5:78943b3945b5 207 bool GSwifi::sendCommand(const char * cmd, Response res, int timeout)
gsfan 5:78943b3945b5 208 {
gsfan 5:78943b3945b5 209 DBG("command: %s",cmd);
gsfan 5:78943b3945b5 210
gsfan 5:78943b3945b5 211 send(cmd, strlen(cmd));
gsfan 5:78943b3945b5 212 if (send("\r\n", 2, res, timeout) == -1) {
gsfan 5:78943b3945b5 213 ERR("sendCommand: cannot %s", cmd);
gsfan 5:78943b3945b5 214 return false;
gsfan 5:78943b3945b5 215 }
gsfan 5:78943b3945b5 216 return true;
gsfan 5:78943b3945b5 217 }
gsfan 5:78943b3945b5 218
gsfan 5:78943b3945b5 219
gsfan 5:78943b3945b5 220 bool GSwifi::disconnect()
gsfan 5:78943b3945b5 221 {
gsfan 5:78943b3945b5 222 // if already disconnected, return
gsfan 5:78943b3945b5 223 if (!_state.associated)
gsfan 5:78943b3945b5 224 return true;
gsfan 5:78943b3945b5 225
gsfan 5:78943b3945b5 226 for (int i = 0; i < 16; i ++) {
gsfan 5:78943b3945b5 227 if (_con[i].buf)
gsfan 5:78943b3945b5 228 _con[i].buf->flush();
gsfan 5:78943b3945b5 229 }
gsfan 5:78943b3945b5 230 sendCommand("AT+NCLOSEALL");
gsfan 5:78943b3945b5 231 sendCommand("AT+WD");
gsfan 5:78943b3945b5 232 sendCommand("AT+NDHCP=0");
gsfan 5:78943b3945b5 233 wait_ms(100);
gsfan 5:78943b3945b5 234
gsfan 5:78943b3945b5 235 _state.associated = false;
gsfan 5:78943b3945b5 236 return true;
gsfan 5:78943b3945b5 237
gsfan 5:78943b3945b5 238 }
gsfan 5:78943b3945b5 239
gsfan 5:78943b3945b5 240 bool GSwifi::is_connected(int cid)
gsfan 5:78943b3945b5 241 {
gsfan 5:78943b3945b5 242 return _con[cid].connected;
gsfan 5:78943b3945b5 243 }
gsfan 5:78943b3945b5 244
gsfan 5:78943b3945b5 245
gsfan 5:78943b3945b5 246 void GSwifi::reset()
gsfan 5:78943b3945b5 247 {
gsfan 5:78943b3945b5 248 _reset = 0;
gsfan 5:78943b3945b5 249 wait_ms(100);
gsfan 5:78943b3945b5 250 _reset = 1;
gsfan 5:78943b3945b5 251 wait_ms(500);
gsfan 5:78943b3945b5 252 }
gsfan 5:78943b3945b5 253
gsfan 5:78943b3945b5 254
gsfan 5:78943b3945b5 255 int GSwifi::putc(char c)
gsfan 5:78943b3945b5 256 {
gsfan 5:78943b3945b5 257 while (!_uart.writeable());
gsfan 5:78943b3945b5 258 return _uart.putc(c);
gsfan 5:78943b3945b5 259 }
gsfan 5:78943b3945b5 260
gsfan 5:78943b3945b5 261
gsfan 5:78943b3945b5 262 int GSwifi::readable(int cid)
gsfan 5:78943b3945b5 263 {
gsfan 5:78943b3945b5 264 if (cid < 0) {
gsfan 5:78943b3945b5 265 return _buf_gswifi.available();
gsfan 5:78943b3945b5 266 } else {
gsfan 5:78943b3945b5 267 return _con[cid].buf->available();
gsfan 5:78943b3945b5 268 }
gsfan 5:78943b3945b5 269 }
gsfan 5:78943b3945b5 270
gsfan 5:78943b3945b5 271 int GSwifi::writeable()
gsfan 5:78943b3945b5 272 {
gsfan 5:78943b3945b5 273 return _uart.writeable();
gsfan 5:78943b3945b5 274 }
gsfan 5:78943b3945b5 275
gsfan 5:78943b3945b5 276 char GSwifi::getc(int cid)
gsfan 5:78943b3945b5 277 {
gsfan 5:78943b3945b5 278 char c;
gsfan 5:78943b3945b5 279 if (cid < 0) {
gsfan 5:78943b3945b5 280 while (!_buf_gswifi.available());
gsfan 5:78943b3945b5 281 _buf_gswifi.dequeue(&c);
gsfan 5:78943b3945b5 282 } else {
gsfan 5:78943b3945b5 283 while (!_con[cid].buf->available());
gsfan 5:78943b3945b5 284 _con[cid].buf->dequeue(&c);
gsfan 5:78943b3945b5 285 }
gsfan 5:78943b3945b5 286 return c;
gsfan 5:78943b3945b5 287 }
gsfan 5:78943b3945b5 288
gsfan 5:78943b3945b5 289 void GSwifi::handler_rx(void)
gsfan 5:78943b3945b5 290 {
gsfan 5:78943b3945b5 291 static int len, flg;
gsfan 5:78943b3945b5 292 static char tmp[20];
gsfan 5:78943b3945b5 293 char dat;
gsfan 5:78943b3945b5 294
gsfan 5:78943b3945b5 295 while (_uart.readable()) {
gsfan 5:78943b3945b5 296
gsfan 5:78943b3945b5 297 dat = _uart.getc();
gsfan 5:78943b3945b5 298
gsfan 5:78943b3945b5 299 switch (_state.mode) {
gsfan 5:78943b3945b5 300 case MODE_COMMAND: // command responce
gsfan 5:78943b3945b5 301 if (_state.escape) {
gsfan 5:78943b3945b5 302 // esc
gsfan 5:78943b3945b5 303 switch (dat) {
gsfan 5:78943b3945b5 304 case 'O':
gsfan 5:78943b3945b5 305 DBG("ok");
gsfan 5:78943b3945b5 306 _state.retres = RES_OK;
gsfan 5:78943b3945b5 307 _state.cmdres = RES_OK;
gsfan 5:78943b3945b5 308 break;
gsfan 5:78943b3945b5 309 case 'F':
gsfan 5:78943b3945b5 310 DBG("failure");
gsfan 5:78943b3945b5 311 _state.retres = RES_FAILURE;
gsfan 5:78943b3945b5 312 _state.cmdres = RES_FAILURE;
gsfan 5:78943b3945b5 313 break;
gsfan 5:78943b3945b5 314 case 'Z':
gsfan 5:78943b3945b5 315 case 'H':
gsfan 5:78943b3945b5 316 DBG("GSMODE_DATA_RX");
gsfan 5:78943b3945b5 317 _state.mode = MODE_DATA_RX;
gsfan 5:78943b3945b5 318 flg = 0;
gsfan 5:78943b3945b5 319 break;
gsfan 5:78943b3945b5 320 case 'y':
gsfan 5:78943b3945b5 321 DBG("GSMODE_DATA_RXUDP");
gsfan 5:78943b3945b5 322 _state.mode = MODE_DATA_RXUDP;
gsfan 5:78943b3945b5 323 flg = 0;
gsfan 5:78943b3945b5 324 break;
gsfan 5:78943b3945b5 325 case 'S':
gsfan 5:78943b3945b5 326 case 'u':
gsfan 5:78943b3945b5 327 default:
gsfan 5:78943b3945b5 328 WARN("unknown [ESC] %02x", dat);
gsfan 5:78943b3945b5 329 break;
gsfan 5:78943b3945b5 330 }
gsfan 5:78943b3945b5 331 _state.escape = 0;
gsfan 5:78943b3945b5 332 } else {
gsfan 5:78943b3945b5 333 if (dat == 0x1b) {
gsfan 5:78943b3945b5 334 _state.escape = 1;
gsfan 5:78943b3945b5 335 } else
gsfan 5:78943b3945b5 336 if (dat == '\n') {
gsfan 5:78943b3945b5 337 parseResponse();
gsfan 5:78943b3945b5 338 } else
gsfan 5:78943b3945b5 339 if (dat != '\r') {
gsfan 5:78943b3945b5 340 // command
gsfan 5:78943b3945b5 341 _buf_gswifi.queue(dat);
gsfan 5:78943b3945b5 342 }
gsfan 5:78943b3945b5 343 }
gsfan 5:78943b3945b5 344 break;
gsfan 5:78943b3945b5 345
gsfan 5:78943b3945b5 346 case MODE_DATA_RX:
gsfan 5:78943b3945b5 347 case MODE_DATA_RXUDP:
gsfan 5:78943b3945b5 348 switch (flg) {
gsfan 5:78943b3945b5 349 case 0:
gsfan 5:78943b3945b5 350 // CID
gsfan 5:78943b3945b5 351 _state.cid = x2i(dat);
gsfan 5:78943b3945b5 352 flg ++;
gsfan 5:78943b3945b5 353 if (_state.mode == MODE_DATA_RX) {
gsfan 5:78943b3945b5 354 flg = 3;
gsfan 5:78943b3945b5 355 }
gsfan 5:78943b3945b5 356 len = 0;
gsfan 5:78943b3945b5 357 break;
gsfan 5:78943b3945b5 358 case 1:
gsfan 5:78943b3945b5 359 // IP (UDP)
gsfan 5:78943b3945b5 360 if ((dat >= '0' && dat <= '9') || dat == '.') {
gsfan 5:78943b3945b5 361 tmp[len] = dat;
gsfan 5:78943b3945b5 362 len ++;
gsfan 5:78943b3945b5 363 } else
gsfan 5:78943b3945b5 364 if (len < sizeof(tmp) - 1) {
gsfan 5:78943b3945b5 365 tmp[len] = 0;
gsfan 5:78943b3945b5 366 strncpy(_con[_state.cid].ip, tmp, sizeof(_con[_state.cid].ip));
gsfan 5:78943b3945b5 367 flg ++;
gsfan 5:78943b3945b5 368 len = 0;
gsfan 5:78943b3945b5 369 }
gsfan 5:78943b3945b5 370 break;
gsfan 5:78943b3945b5 371 case 2:
gsfan 5:78943b3945b5 372 // port
gsfan 5:78943b3945b5 373 if (dat >= '0' && dat <= '9') {
gsfan 5:78943b3945b5 374 tmp[len] = dat;
gsfan 5:78943b3945b5 375 len ++;
gsfan 5:78943b3945b5 376 } else {
gsfan 5:78943b3945b5 377 tmp[len] = 0;
gsfan 5:78943b3945b5 378 _con[_state.cid].port = atoi(tmp);
gsfan 5:78943b3945b5 379 flg ++;
gsfan 5:78943b3945b5 380 len = 0;
gsfan 5:78943b3945b5 381 }
gsfan 5:78943b3945b5 382 break;
gsfan 5:78943b3945b5 383 case 3:
gsfan 5:78943b3945b5 384 // length
gsfan 5:78943b3945b5 385 tmp[len] = dat;
gsfan 5:78943b3945b5 386 len ++;
gsfan 5:78943b3945b5 387 if (len >= 4) {
gsfan 5:78943b3945b5 388 tmp[len] = 0;
gsfan 5:78943b3945b5 389 len = atoi(tmp);
gsfan 5:78943b3945b5 390 flg ++;
gsfan 5:78943b3945b5 391 }
gsfan 5:78943b3945b5 392 break;
gsfan 5:78943b3945b5 393 case 4:
gsfan 5:78943b3945b5 394 // data
gsfan 5:78943b3945b5 395 if (_con[_state.cid].buf != NULL) {
gsfan 5:78943b3945b5 396 _con[_state.cid].buf->queue(dat);
gsfan 5:78943b3945b5 397 }
gsfan 5:78943b3945b5 398 len --;
gsfan 5:78943b3945b5 399
gsfan 5:78943b3945b5 400 if (len == 0 || _con[_state.cid].buf->isFull()) {
gsfan 5:78943b3945b5 401 DBG("recv binary %d", _state.cid);
gsfan 5:78943b3945b5 402 _state.escape = 0;
gsfan 5:78943b3945b5 403 _state.mode = MODE_COMMAND;
gsfan 5:78943b3945b5 404 // recv interrupt
gsfan 5:78943b3945b5 405 /*
gsfan 5:78943b3945b5 406 if (_gs_sock[_cid].protocol == GSPROT_HTTPGET && _gs_sock[_cid].onGsReceive != NULL) {
gsfan 5:78943b3945b5 407 _gs_sock[_cid].onGsReceive(_cid, _gs_sock[_cid].data->use());
gsfan 5:78943b3945b5 408 _gs_sock[_cid].received = 0;
gsfan 5:78943b3945b5 409 }
gsfan 5:78943b3945b5 410 */
gsfan 5:78943b3945b5 411 }
gsfan 5:78943b3945b5 412 break;
gsfan 5:78943b3945b5 413 }
gsfan 5:78943b3945b5 414
gsfan 5:78943b3945b5 415 break;
gsfan 5:78943b3945b5 416 }
gsfan 5:78943b3945b5 417
gsfan 5:78943b3945b5 418 } // while
gsfan 5:78943b3945b5 419 }
gsfan 5:78943b3945b5 420
gsfan 5:78943b3945b5 421 void GSwifi::parseResponse () {
gsfan 5:78943b3945b5 422 int i;
gsfan 5:78943b3945b5 423 char buf[CFG_CMD_SIZE];
gsfan 5:78943b3945b5 424
gsfan 5:78943b3945b5 425 while (_buf_gswifi.available()) {
gsfan 5:78943b3945b5 426 i = 0;
gsfan 5:78943b3945b5 427 while (_buf_gswifi.available() && i < sizeof(buf)) {
gsfan 5:78943b3945b5 428 _buf_gswifi.dequeue(&buf[i]);
gsfan 5:78943b3945b5 429 if (buf[i] == '\n') {
gsfan 5:78943b3945b5 430 break;
gsfan 5:78943b3945b5 431 }
gsfan 5:78943b3945b5 432 i ++;
gsfan 5:78943b3945b5 433 }
gsfan 5:78943b3945b5 434 if (i == 0) continue;
gsfan 5:78943b3945b5 435 buf[i] = 0;
gsfan 5:78943b3945b5 436 DBG("parseResponse: %s", buf);
gsfan 5:78943b3945b5 437
gsfan 5:78943b3945b5 438 if (_state.cmdres != RES_NULL) {
gsfan 5:78943b3945b5 439 parseCmdResponse(buf);
gsfan 5:78943b3945b5 440 DBG("parseCmdResponse %d %d", _state.cmdres, _state.retres);
gsfan 5:78943b3945b5 441 }
gsfan 5:78943b3945b5 442
gsfan 5:78943b3945b5 443 if (strncmp(buf, "CONNECT ", 8) == 0 && buf[8] >= '0' && buf[8] <= 'F' && buf[9] != 0) {
gsfan 5:78943b3945b5 444 int cid;
gsfan 5:78943b3945b5 445 char *tmp, *tmp2;
gsfan 5:78943b3945b5 446 cid = x2i(buf[8]);
gsfan 5:78943b3945b5 447 _state.acid = x2i(buf[10]);
gsfan 5:78943b3945b5 448 tmp = buf + 12;
gsfan 5:78943b3945b5 449 tmp2 = strstr(tmp, " ");
gsfan 5:78943b3945b5 450 tmp2[0] = 0;
gsfan 5:78943b3945b5 451 strncpy(_con[_state.acid].ip, tmp, sizeof(_con[_state.acid].ip));
gsfan 5:78943b3945b5 452 tmp = tmp2 + 1;
gsfan 5:78943b3945b5 453 _con[_state.acid].port = atoi(tmp);
gsfan 5:78943b3945b5 454 _con[_state.acid].parent = cid;
gsfan 5:78943b3945b5 455 if (_con[_state.acid].buf == NULL)
gsfan 5:78943b3945b5 456 _con[_state.acid].buf = new CircBuffer<char>(CFG_DATA_SIZE);
gsfan 5:78943b3945b5 457 _con[_state.acid].buf->flush();
gsfan 5:78943b3945b5 458 _con[_state.acid].connected = true;
gsfan 5:78943b3945b5 459 DBG("connect %d -> %d", cid, _state.acid);
gsfan 5:78943b3945b5 460 } else
gsfan 5:78943b3945b5 461 if (strncmp(buf, "DISCONNECT ", 11) == 0) {
gsfan 5:78943b3945b5 462 int cid;
gsfan 5:78943b3945b5 463 cid = x2i(buf[11]);
gsfan 5:78943b3945b5 464 DBG("disconnect %d", cid);
gsfan 5:78943b3945b5 465 _con[cid].connected = false;
gsfan 5:78943b3945b5 466 } else
gsfan 5:78943b3945b5 467 if (strncmp(buf, "DISASSOCIATED", 13) == 0 ||
gsfan 5:78943b3945b5 468 strncmp(buf, "Disassociated", 13) == 0 ||
gsfan 5:78943b3945b5 469 strncmp(buf, "Disassociation Event", 20) == 0 ||
gsfan 5:78943b3945b5 470 strncmp(buf, "UnExpected Warm Boot", 20) == 0) {
gsfan 5:78943b3945b5 471 _state.associated = false;
gsfan 5:78943b3945b5 472 for (i = 0; i < 16; i ++) {
gsfan 5:78943b3945b5 473 _con[i].connected = false;
gsfan 5:78943b3945b5 474 }
gsfan 5:78943b3945b5 475 } else
gsfan 5:78943b3945b5 476 if (strncmp(buf, "Out of StandBy-Timer", 20) == 0 ||
gsfan 5:78943b3945b5 477 strncmp(buf, "Out of StandBy-Alarm", 20) == 0) {
gsfan 5:78943b3945b5 478 _state.status = STAT_WAKEUP;
gsfan 5:78943b3945b5 479 } else
gsfan 5:78943b3945b5 480 if (strncmp(buf, "Out of Deep Sleep", 17) == 0 ) {
gsfan 5:78943b3945b5 481 _state.status = STAT_READY;
gsfan 5:78943b3945b5 482 } else
gsfan 5:78943b3945b5 483 if (strncmp(buf, "Out of", 6) == 0) {
gsfan 5:78943b3945b5 484 }
gsfan 5:78943b3945b5 485 }
gsfan 5:78943b3945b5 486 }
gsfan 5:78943b3945b5 487
gsfan 5:78943b3945b5 488 void GSwifi::parseCmdResponse (char *buf) {
gsfan 5:78943b3945b5 489
gsfan 5:78943b3945b5 490 if (strcmp(buf, "OK") == 0) {
gsfan 5:78943b3945b5 491 _state.retres = RES_OK;
gsfan 5:78943b3945b5 492 } else
gsfan 5:78943b3945b5 493 if (strncmp(buf, "ERROR", 5) == 0) {
gsfan 5:78943b3945b5 494 _state.retres = RES_FAILURE;
gsfan 5:78943b3945b5 495 }
gsfan 5:78943b3945b5 496
gsfan 5:78943b3945b5 497 switch(_state.cmdres) {
gsfan 5:78943b3945b5 498 case RES_NORMAL:
gsfan 5:78943b3945b5 499 _state.cmdres = RES_OK;
gsfan 5:78943b3945b5 500 break;
gsfan 5:78943b3945b5 501 case RES_WPS:
gsfan 5:78943b3945b5 502 if (_state.n == 0 && strncmp(buf, "SSID", 4) == 0) {
gsfan 5:78943b3945b5 503 _state.n ++;
gsfan 5:78943b3945b5 504 } else
gsfan 5:78943b3945b5 505 if (_state.n == 1 && strncmp(buf, "CHANNEL", 7) == 0) {
gsfan 5:78943b3945b5 506 _state.n ++;
gsfan 5:78943b3945b5 507 } else
gsfan 5:78943b3945b5 508 if (_state.n == 2 && strncmp(buf, "PASSPHRASE", 10) == 0) {
gsfan 5:78943b3945b5 509 _state.n ++;
gsfan 5:78943b3945b5 510 _state.cmdres = RES_OK;
gsfan 5:78943b3945b5 511 }
gsfan 5:78943b3945b5 512 break;
gsfan 5:78943b3945b5 513 case RES_CONNECT:
gsfan 5:78943b3945b5 514 if (strncmp(buf, "CONNECT ", 8) == 0 && buf[9] == 0) {
gsfan 5:78943b3945b5 515 _state.cid = x2i(buf[8]);
gsfan 5:78943b3945b5 516 _state.cmdres = RES_OK;
gsfan 5:78943b3945b5 517 if (_con[_state.cid].buf == NULL)
gsfan 5:78943b3945b5 518 _con[_state.cid].buf = new CircBuffer<char>(CFG_DATA_SIZE);
gsfan 5:78943b3945b5 519 _con[_state.cid].buf->flush();
gsfan 5:78943b3945b5 520 _con[_state.cid].connected = true;
gsfan 5:78943b3945b5 521 INFO("connect: %d", _state.cid);
gsfan 5:78943b3945b5 522 }
gsfan 5:78943b3945b5 523 break;
gsfan 5:78943b3945b5 524 case RES_DHCP:
gsfan 5:78943b3945b5 525 if (_state.n == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) {
gsfan 5:78943b3945b5 526 _state.n ++;
gsfan 5:78943b3945b5 527 } else
gsfan 5:78943b3945b5 528 if (_state.n == 1) {
gsfan 5:78943b3945b5 529 char *tmp, *tmp2;
gsfan 5:78943b3945b5 530 tmp = buf + 1;
gsfan 5:78943b3945b5 531 tmp2 = strstr(tmp, ":");
gsfan 5:78943b3945b5 532 tmp2[0] = 0;
gsfan 5:78943b3945b5 533 strncpy(_ip, tmp, sizeof(_ip));
gsfan 5:78943b3945b5 534 tmp = tmp2 + 2;
gsfan 5:78943b3945b5 535 tmp2 = strstr(tmp, ":");
gsfan 5:78943b3945b5 536 tmp2[0] = 0;
gsfan 5:78943b3945b5 537 strncpy(_netmask, tmp, sizeof(_netmask));
gsfan 5:78943b3945b5 538 tmp = tmp2 + 2;
gsfan 5:78943b3945b5 539 strncpy(_gateway, tmp, sizeof(_gateway));
gsfan 5:78943b3945b5 540 _state.n ++;
gsfan 5:78943b3945b5 541 _state.cmdres = RES_OK;
gsfan 5:78943b3945b5 542 INFO("ip: %s\r\nnetmask: %s\r\ngateway: %s", _ip, _netmask, _gateway);
gsfan 5:78943b3945b5 543 }
gsfan 5:78943b3945b5 544 break;
gsfan 5:78943b3945b5 545 case RES_MACADDRESS:
gsfan 5:78943b3945b5 546 if (buf[2] == ':' && buf[5] == ':') {
gsfan 5:78943b3945b5 547 /*
gsfan 5:78943b3945b5 548 int mac1, mac2, mac3, mac4, mac5, mac6;
gsfan 5:78943b3945b5 549 sscanf(buf, "%x:%x:%x:%x:%x:%x", &mac1, &mac2, &mac3, &mac4, &mac5, &mac6);
gsfan 5:78943b3945b5 550 _mac[0] = mac1;
gsfan 5:78943b3945b5 551 _mac[1] = mac2;
gsfan 5:78943b3945b5 552 _mac[2] = mac3;
gsfan 5:78943b3945b5 553 _mac[3] = mac4;
gsfan 5:78943b3945b5 554 _mac[4] = mac5;
gsfan 5:78943b3945b5 555 _mac[5] = mac6;
gsfan 5:78943b3945b5 556 */
gsfan 5:78943b3945b5 557 _state.cmdres = RES_OK;
gsfan 5:78943b3945b5 558 }
gsfan 5:78943b3945b5 559 break;
gsfan 5:78943b3945b5 560 case RES_DNSLOOKUP:
gsfan 5:78943b3945b5 561 if (strncmp(buf, "IP:", 3) == 0) {
gsfan 5:78943b3945b5 562 strncpy(_resolv, &buf[3], sizeof(_resolv));
gsfan 5:78943b3945b5 563 _state.cmdres = RES_OK;
gsfan 5:78943b3945b5 564 INFO("resolv: %s", _resolv);
gsfan 5:78943b3945b5 565 }
gsfan 5:78943b3945b5 566 break;
gsfan 5:78943b3945b5 567 case RES_HTTP:
gsfan 5:78943b3945b5 568 if (buf[0] >= '0' && buf[0] <= 'F') {
gsfan 5:78943b3945b5 569 _state.cid = x2i(buf[0]);
gsfan 5:78943b3945b5 570 _state.cmdres = RES_OK;
gsfan 5:78943b3945b5 571 INFO("http: %d", _state.cid);
gsfan 5:78943b3945b5 572 }
gsfan 5:78943b3945b5 573 break;
gsfan 5:78943b3945b5 574 case RES_RSSI:
gsfan 5:78943b3945b5 575 if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) {
gsfan 5:78943b3945b5 576 _rssi = atoi(buf);
gsfan 5:78943b3945b5 577 _state.cmdres = RES_OK;
gsfan 5:78943b3945b5 578 INFO("rssi: %d", _rssi);
gsfan 5:78943b3945b5 579 }
gsfan 5:78943b3945b5 580 break;
gsfan 5:78943b3945b5 581 case RES_TIME:
gsfan 5:78943b3945b5 582 if (buf[0] >= '0' && buf[0] <= '9') {
gsfan 5:78943b3945b5 583 int year, month, day, hour, min, sec;
gsfan 5:78943b3945b5 584 struct tm t;
gsfan 5:78943b3945b5 585 sscanf(buf, "%d/%d/%d,%d:%d:%d", &day, &month, &year, &hour, &min, &sec);
gsfan 5:78943b3945b5 586 t.tm_sec = sec;
gsfan 5:78943b3945b5 587 t.tm_min = min;
gsfan 5:78943b3945b5 588 t.tm_hour = hour;
gsfan 5:78943b3945b5 589 t.tm_mday = day;
gsfan 5:78943b3945b5 590 t.tm_mon = month - 1;
gsfan 5:78943b3945b5 591 t.tm_year = year - 1900;
gsfan 5:78943b3945b5 592 _time = mktime(&t);
gsfan 5:78943b3945b5 593 _state.cmdres = RES_OK;
gsfan 5:78943b3945b5 594 }
gsfan 5:78943b3945b5 595 break;
gsfan 5:78943b3945b5 596 }
gsfan 5:78943b3945b5 597 }
gsfan 5:78943b3945b5 598
gsfan 5:78943b3945b5 599 int GSwifi::send(const char * str, int len, Response res, int timeout)
gsfan 5:78943b3945b5 600 {
gsfan 5:78943b3945b5 601 Timer tmr;
gsfan 5:78943b3945b5 602 int result = 0;
gsfan 5:78943b3945b5 603
gsfan 5:78943b3945b5 604 if (res == RES_NULL) {
gsfan 5:78943b3945b5 605 for (int i = 0; i < len; i++)
gsfan 5:78943b3945b5 606 result = (putc(str[i]) == str[i]) ? result + 1 : result;
gsfan 5:78943b3945b5 607 } else {
gsfan 5:78943b3945b5 608 _state.cmdres = res;
gsfan 5:78943b3945b5 609 _state.retres = RES_NULL;
gsfan 5:78943b3945b5 610
gsfan 5:78943b3945b5 611 tmr.start();
gsfan 5:78943b3945b5 612 for (int i = 0; i < len; i++)
gsfan 5:78943b3945b5 613 result = (putc(str[i]) == str[i]) ? result + 1 : result;
gsfan 5:78943b3945b5 614
gsfan 5:78943b3945b5 615 while (1) {
gsfan 5:78943b3945b5 616 if (tmr.read_ms() > timeout || _state.retres == RES_FAILURE) {
gsfan 5:78943b3945b5 617 result = -1;
gsfan 5:78943b3945b5 618 break;
gsfan 5:78943b3945b5 619 }
gsfan 5:78943b3945b5 620 if (_state.retres == RES_OK && _state.cmdres != res) break;
gsfan 5:78943b3945b5 621 }
gsfan 5:78943b3945b5 622 }
gsfan 5:78943b3945b5 623
gsfan 5:78943b3945b5 624 _state.cmdres = RES_NULL;
gsfan 5:78943b3945b5 625 _state.retres = RES_NULL;
gsfan 5:78943b3945b5 626 return result;
gsfan 5:78943b3945b5 627 }
gsfan 5:78943b3945b5 628
gsfan 5:78943b3945b5 629 bool GSwifi::readRemote(int cid, char **ip, int *port) {
gsfan 5:78943b3945b5 630 *ip = _con[cid].ip;
gsfan 5:78943b3945b5 631 *port = _con[cid].port;
gsfan 5:78943b3945b5 632 return true;
gsfan 5:78943b3945b5 633 }
gsfan 5:78943b3945b5 634
gsfan 5:78943b3945b5 635 int GSwifi::readCID () {
gsfan 5:78943b3945b5 636 return _state.cid;
gsfan 5:78943b3945b5 637 }
gsfan 5:78943b3945b5 638
gsfan 5:78943b3945b5 639 int GSwifi::readACID () {
gsfan 5:78943b3945b5 640 int r = -1;
gsfan 5:78943b3945b5 641 if (_state.acid >= 0 && _con[_state.acid].connected == true) {
gsfan 5:78943b3945b5 642 r = _state.acid;
gsfan 5:78943b3945b5 643 _state.acid = -1;
gsfan 5:78943b3945b5 644 }
gsfan 5:78943b3945b5 645 return r;
gsfan 5:78943b3945b5 646 }
gsfan 5:78943b3945b5 647
gsfan 5:78943b3945b5 648 int GSwifi::x2i (char c) {
gsfan 5:78943b3945b5 649 if (c >= '0' && c <= '9') {
gsfan 5:78943b3945b5 650 return c - '0';
gsfan 5:78943b3945b5 651 } else
gsfan 5:78943b3945b5 652 if (c >= 'A' && c <= 'F') {
gsfan 5:78943b3945b5 653 return c - 'A' + 10;
gsfan 5:78943b3945b5 654 } else
gsfan 5:78943b3945b5 655 if (c >= 'a' && c <= 'f') {
gsfan 5:78943b3945b5 656 return c - 'a' + 10;
gsfan 5:78943b3945b5 657 }
gsfan 5:78943b3945b5 658 return 0;
gsfan 5:78943b3945b5 659 }
gsfan 5:78943b3945b5 660
gsfan 5:78943b3945b5 661 char GSwifi::i2x (int i) {
gsfan 5:78943b3945b5 662 if (i >= 0 && i <= 9) {
gsfan 5:78943b3945b5 663 return i + '0';
gsfan 5:78943b3945b5 664 } else
gsfan 5:78943b3945b5 665 if (i >= 10 && i <= 15) {
gsfan 5:78943b3945b5 666 return i - 10 + 'A';
gsfan 5:78943b3945b5 667 }
gsfan 5:78943b3945b5 668 return 0;
gsfan 5:78943b3945b5 669 }