cc

Dependencies:   ATParser

Committer:
mansiag
Date:
Mon Oct 24 10:37:26 2016 +0000
Revision:
22:2eb9b3c54506
Parent:
21:cd722edbb644
Child:
23:0b01aa59bb6f
Return -1 when timeout (for supporting non-blocking mode).

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mridup 0:9e5d98ceea74 1 /* SPWFInterface Example
mridup 0:9e5d98ceea74 2 * Copyright (c) 2015 ARM Limited
mridup 0:9e5d98ceea74 3 *
mridup 0:9e5d98ceea74 4 * Licensed under the Apache License, Version 2.0 (the "License");
mridup 0:9e5d98ceea74 5 * you may not use this file except in compliance with the License.
mridup 0:9e5d98ceea74 6 * You may obtain a copy of the License at
mridup 0:9e5d98ceea74 7 *
mridup 0:9e5d98ceea74 8 * http://www.apache.org/licenses/LICENSE-2.0
mridup 0:9e5d98ceea74 9 *
mridup 0:9e5d98ceea74 10 * Unless required by applicable law or agreed to in writing, software
mridup 0:9e5d98ceea74 11 * distributed under the License is distributed on an "AS IS" BASIS,
mridup 0:9e5d98ceea74 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mridup 0:9e5d98ceea74 13 * See the License for the specific language governing permissions and
mridup 0:9e5d98ceea74 14 * limitations under the License.
mridup 0:9e5d98ceea74 15 */
mridup 0:9e5d98ceea74 16
mridup 0:9e5d98ceea74 17 #include "SPWFSA01.h"
mridup 13:f21e4e73bbb6 18 #include "mbed_debug.h"
mridup 0:9e5d98ceea74 19
mridup 20:01031cd39e73 20 #define SPWFSA01_CONNECT_TIMEOUT 15000
mridup 20:01031cd39e73 21 #define SPWFSA01_SEND_TIMEOUT 500
mridup 20:01031cd39e73 22 #define SPWFSA01_RECV_TIMEOUT 1500//some commands like AT&F/W takes some time to get the result back!
mridup 20:01031cd39e73 23 #define SPWFSA01_MISC_TIMEOUT 500
mridup 20:01031cd39e73 24 #define SPWFSA01_SOCKQ_TIMEOUT 3000
mridup 0:9e5d98ceea74 25
mridup 0:9e5d98ceea74 26 SPWFSA01::SPWFSA01(PinName tx, PinName rx, bool debug)
mridup 0:9e5d98ceea74 27 : _serial(tx, rx, 1024), _parser(_serial),
mridup 14:868b0fd4e84a 28 _wakeup(D14, PIN_INPUT, PullNone, 0), _reset(D15, PIN_INPUT, PullNone, 1),
mridup 14:868b0fd4e84a 29 //PC_12->D15, PC_8->D14 (re-wires needed in-case used, currently not used)
mridup 13:f21e4e73bbb6 30 dbg_on(debug)
mridup 0:9e5d98ceea74 31 //Pin PC_8 is wakeup pin
mridup 0:9e5d98ceea74 32 //Pin PA_12 is reset pin
mridup 0:9e5d98ceea74 33 {
mridup 0:9e5d98ceea74 34 _serial.baud(115200);
mridup 0:9e5d98ceea74 35 _reset.output();
mridup 0:9e5d98ceea74 36 _wakeup.output();
mridup 0:9e5d98ceea74 37 _parser.debugOn(debug);
mridup 0:9e5d98ceea74 38 }
mridup 0:9e5d98ceea74 39
mridup 0:9e5d98ceea74 40 bool SPWFSA01::startup(int mode)
mridup 0:9e5d98ceea74 41 {
mridup 0:9e5d98ceea74 42 setTimeout(SPWFSA01_RECV_TIMEOUT);
mridup 0:9e5d98ceea74 43
mridup 0:9e5d98ceea74 44 /*Test module before reset*/
mridup 0:9e5d98ceea74 45 waitSPWFReady();
mridup 0:9e5d98ceea74 46 /*Reset module*/
mridup 0:9e5d98ceea74 47 reset();
mridup 0:9e5d98ceea74 48
mridup 0:9e5d98ceea74 49 /*set local echo to 0*/
mridup 8:a4425b8dd2e4 50 if(!(_parser.send("AT+S.SCFG=localecho1,%d\r", 0) && _parser.recv("OK")))
mridup 0:9e5d98ceea74 51 {
mridup 13:f21e4e73bbb6 52 debug_if(dbg_on, "SPWF> error local echo set\r\n");
mridup 0:9e5d98ceea74 53 return false;
mridup 0:9e5d98ceea74 54 }
mridup 0:9e5d98ceea74 55 /*reset factory settings*/
mridup 0:9e5d98ceea74 56 if(!(_parser.send("AT&F") && _parser.recv("OK")))
mridup 0:9e5d98ceea74 57 {
mridup 13:f21e4e73bbb6 58 debug_if(dbg_on, "SPWF> error AT&F\r\n");
mridup 0:9e5d98ceea74 59 return false;
mridup 0:9e5d98ceea74 60 }
mridup 0:9e5d98ceea74 61
mridup 0:9e5d98ceea74 62 /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/
mridup 0:9e5d98ceea74 63 if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", mode) && _parser.recv("OK")))
mridup 0:9e5d98ceea74 64 {
mridup 13:f21e4e73bbb6 65 debug_if(dbg_on, "SPWF> error wifi mode set\r\n");
mridup 0:9e5d98ceea74 66 return false;
mridup 0:9e5d98ceea74 67 }
mridup 0:9e5d98ceea74 68
mridup 0:9e5d98ceea74 69 /* save current setting in flash */
mridup 0:9e5d98ceea74 70 if(!(_parser.send("AT&W") && _parser.recv("OK")))
mridup 0:9e5d98ceea74 71 {
mridup 13:f21e4e73bbb6 72 debug_if(dbg_on, "SPWF> error AT&W\r\n");
mridup 0:9e5d98ceea74 73 return false;
mridup 0:9e5d98ceea74 74 }
mridup 0:9e5d98ceea74 75
mridup 0:9e5d98ceea74 76 /*reset again and send AT command and check for result (AT->OK)*/
mridup 0:9e5d98ceea74 77 reset();
mridup 0:9e5d98ceea74 78
mridup 0:9e5d98ceea74 79 return true;
mridup 0:9e5d98ceea74 80 }
mridup 0:9e5d98ceea74 81
mridup 0:9e5d98ceea74 82 bool SPWFSA01::hw_reset(void)
mridup 0:9e5d98ceea74 83 {
mridup 0:9e5d98ceea74 84 /* reset the pin PC12 */
mridup 0:9e5d98ceea74 85 _reset.write(0);
mridup 0:9e5d98ceea74 86 wait_ms(200);
mridup 0:9e5d98ceea74 87 _reset.write(1);
mridup 0:9e5d98ceea74 88 wait_ms(100);
mridup 0:9e5d98ceea74 89 return 1;
mridup 0:9e5d98ceea74 90 }
mridup 0:9e5d98ceea74 91
mridup 0:9e5d98ceea74 92 bool SPWFSA01::reset(void)
mridup 0:9e5d98ceea74 93 {
mridup 0:9e5d98ceea74 94 if(!_parser.send("AT+CFUN=1")) return false;
mridup 0:9e5d98ceea74 95 while(1) {
mridup 8:a4425b8dd2e4 96 if (_parser.recv("+WIND:32:WiFi Hardware Started\r")) {
mridup 0:9e5d98ceea74 97 return true;
mridup 0:9e5d98ceea74 98 }
mridup 0:9e5d98ceea74 99 }
mridup 0:9e5d98ceea74 100 }
mridup 0:9e5d98ceea74 101
mridup 0:9e5d98ceea74 102 void SPWFSA01::waitSPWFReady(void)
mridup 0:9e5d98ceea74 103 {
mridup 0:9e5d98ceea74 104 //wait_ms(200);
mridup 0:9e5d98ceea74 105 while(1)
mridup 0:9e5d98ceea74 106 if(_parser.send("AT") && _parser.recv("OK"))
mridup 0:9e5d98ceea74 107 //till we get OK from AT command
mridup 0:9e5d98ceea74 108 //printf("\r\nwaiting for reset to complete..\n");
mridup 0:9e5d98ceea74 109 return;
mridup 0:9e5d98ceea74 110
mridup 0:9e5d98ceea74 111 }
mridup 0:9e5d98ceea74 112
mridup 0:9e5d98ceea74 113 /* Security Mode
mridup 0:9e5d98ceea74 114 None = 0,
mridup 0:9e5d98ceea74 115 WEP = 1,
mridup 0:9e5d98ceea74 116 WPA_Personal = 2,
mridup 0:9e5d98ceea74 117 */
mridup 0:9e5d98ceea74 118 bool SPWFSA01::connect(const char *ap, const char *passPhrase, int securityMode)
mridup 0:9e5d98ceea74 119 {
mridup 0:9e5d98ceea74 120 uint32_t n1, n2, n3, n4;
mridup 0:9e5d98ceea74 121
mridup 0:9e5d98ceea74 122 //AT+S.SCFG=wifi_wpa_psk_text,%s\r
mridup 0:9e5d98ceea74 123 if(!(_parser.send("AT+S.SCFG=wifi_wpa_psk_text,%s", passPhrase) && _parser.recv("OK")))
mridup 0:9e5d98ceea74 124 {
mridup 13:f21e4e73bbb6 125 debug_if(dbg_on, "SPWF> error pass set\r\n");
mridup 0:9e5d98ceea74 126 return false;
mridup 0:9e5d98ceea74 127 }
mridup 0:9e5d98ceea74 128 //AT+S.SSIDTXT=%s\r
mridup 0:9e5d98ceea74 129 if(!(_parser.send("AT+S.SSIDTXT=%s", ap) && _parser.recv("OK")))
mridup 0:9e5d98ceea74 130 {
mridup 13:f21e4e73bbb6 131 debug_if(dbg_on, "SPWF> error ssid set\r\n");
mridup 0:9e5d98ceea74 132 return false;
mridup 0:9e5d98ceea74 133 }
mridup 0:9e5d98ceea74 134 //AT+S.SCFG=wifi_priv_mode,%d\r
mridup 0:9e5d98ceea74 135 if(!(_parser.send("AT+S.SCFG=wifi_priv_mode,%d", securityMode) && _parser.recv("OK")))
mridup 0:9e5d98ceea74 136 {
mridup 13:f21e4e73bbb6 137 debug_if(dbg_on, "SPWF> error security mode set\r\n");
mridup 0:9e5d98ceea74 138 return false;
mridup 0:9e5d98ceea74 139 }
mridup 0:9e5d98ceea74 140 //"AT+S.SCFG=wifi_mode,%d\r"
mridup 0:9e5d98ceea74 141 /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/
mridup 0:9e5d98ceea74 142 if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", 1) && _parser.recv("OK")))
mridup 0:9e5d98ceea74 143 {
mridup 13:f21e4e73bbb6 144 debug_if(dbg_on, "SPWF> error wifi mode set\r\n");
mridup 0:9e5d98ceea74 145 return false;
mridup 0:9e5d98ceea74 146 }
mridup 0:9e5d98ceea74 147 //AT&W
mridup 0:9e5d98ceea74 148 /* save current setting in flash */
mridup 0:9e5d98ceea74 149 if(!(_parser.send("AT&W") && _parser.recv("OK")))
mridup 0:9e5d98ceea74 150 {
mridup 13:f21e4e73bbb6 151 debug_if(dbg_on, "SPWF> error AT&W\r\n");
mridup 0:9e5d98ceea74 152 return false;
mridup 0:9e5d98ceea74 153 }
mridup 0:9e5d98ceea74 154 //reset module
mridup 0:9e5d98ceea74 155 reset();
mridup 0:9e5d98ceea74 156
mridup 0:9e5d98ceea74 157 while(1)
mansiag 18:fd46c2ca8eb7 158 if((_parser.recv("+WIND:24:WiFi Up:%u.%u.%u.%u",&n1, &n2, &n3, &n4)))
mridup 0:9e5d98ceea74 159 {
mridup 0:9e5d98ceea74 160 break;
mridup 8:a4425b8dd2e4 161 }
mridup 0:9e5d98ceea74 162
mridup 0:9e5d98ceea74 163 return true;
mridup 0:9e5d98ceea74 164 }
mridup 0:9e5d98ceea74 165
mridup 0:9e5d98ceea74 166 bool SPWFSA01::disconnect(void)
mridup 0:9e5d98ceea74 167 {
mridup 0:9e5d98ceea74 168 //"AT+S.SCFG=wifi_mode,%d\r"
mridup 0:9e5d98ceea74 169 /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/
mridup 0:9e5d98ceea74 170 if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", 0) && _parser.recv("OK")))
mridup 0:9e5d98ceea74 171 {
mridup 13:f21e4e73bbb6 172 debug_if(dbg_on, "SPWF> error wifi mode set\r\n");
mridup 0:9e5d98ceea74 173 return false;
mridup 0:9e5d98ceea74 174 }
mridup 0:9e5d98ceea74 175 //AT&W
mridup 0:9e5d98ceea74 176 /* save current setting in flash */
mridup 0:9e5d98ceea74 177 if(!(_parser.send("AT&W") && _parser.recv("OK")))
mridup 0:9e5d98ceea74 178 {
mridup 13:f21e4e73bbb6 179 debug_if(dbg_on, "SPWF> error AT&W\r\n");
mridup 0:9e5d98ceea74 180 return false;
mridup 0:9e5d98ceea74 181 }
mridup 0:9e5d98ceea74 182 //reset module
mridup 0:9e5d98ceea74 183 reset();
mridup 0:9e5d98ceea74 184 return true;
mridup 0:9e5d98ceea74 185 }
mridup 0:9e5d98ceea74 186
mridup 5:f17d6351e942 187 bool SPWFSA01::dhcp(int mode)
mridup 0:9e5d98ceea74 188 {
mridup 0:9e5d98ceea74 189 //only 3 valid modes
mridup 5:f17d6351e942 190 //0->off(ip_addr must be set by user), 1->on(auto set by AP), 2->on&customize(miniAP ip_addr can be set by user)
mridup 0:9e5d98ceea74 191 if(mode < 0 || mode > 2) {
mridup 0:9e5d98ceea74 192 return false;
mridup 0:9e5d98ceea74 193 }
mridup 5:f17d6351e942 194
mridup 5:f17d6351e942 195 return _parser.send("AT+S.SCFG=ip_use_dhcp,%d\r", mode)
mridup 0:9e5d98ceea74 196 && _parser.recv("OK");
mridup 0:9e5d98ceea74 197 }
mridup 0:9e5d98ceea74 198
mridup 0:9e5d98ceea74 199
mridup 0:9e5d98ceea74 200 const char *SPWFSA01::getIPAddress(void)
mridup 0:9e5d98ceea74 201 {
mridup 0:9e5d98ceea74 202 uint32_t n1, n2, n3, n4;
mridup 0:9e5d98ceea74 203
mridup 0:9e5d98ceea74 204 if (!(_parser.send("AT+S.STS=ip_ipaddr")
mridup 1:becf69a794fb 205 && _parser.recv("# ip_ipaddr = %u.%u.%u.%u", &n1, &n2, &n3, &n4)
mridup 0:9e5d98ceea74 206 && _parser.recv("OK"))) {
mridup 13:f21e4e73bbb6 207 debug_if(dbg_on, "SPWF> getIPAddress error\r\n");
mridup 0:9e5d98ceea74 208 return 0;
mridup 0:9e5d98ceea74 209 }
mridup 2:40d183d7dc19 210
mridup 0:9e5d98ceea74 211 sprintf((char*)_ip_buffer,"%u.%u.%u.%u", n1, n2, n3, n4);
mridup 0:9e5d98ceea74 212
mridup 0:9e5d98ceea74 213 return _ip_buffer;
mridup 0:9e5d98ceea74 214 }
mridup 0:9e5d98ceea74 215
mridup 0:9e5d98ceea74 216 const char *SPWFSA01::getMACAddress(void)
mridup 0:9e5d98ceea74 217 {
mridup 2:40d183d7dc19 218 uint32_t n1, n2, n3, n4, n5, n6;
mridup 1:becf69a794fb 219
mridup 1:becf69a794fb 220 if (!(_parser.send("AT+S.GCFG=nv_wifi_macaddr")
mridup 2:40d183d7dc19 221 && _parser.recv("# nv_wifi_macaddr = %x:%x:%x:%x:%x:%x", &n1, &n2, &n3, &n4, &n5, &n6)
mridup 0:9e5d98ceea74 222 && _parser.recv("OK"))) {
mridup 13:f21e4e73bbb6 223 debug_if(dbg_on, "SPWF> getMACAddress error\r\n");
mridup 0:9e5d98ceea74 224 return 0;
mridup 0:9e5d98ceea74 225 }
mridup 2:40d183d7dc19 226
mridup 2:40d183d7dc19 227 sprintf((char*)_mac_buffer,"%02X:%02X:%02X:%02X:%02X:%02X", n1, n2, n3, n4, n5, n6);
mridup 0:9e5d98ceea74 228
mridup 0:9e5d98ceea74 229 return _mac_buffer;
mridup 0:9e5d98ceea74 230 }
mridup 0:9e5d98ceea74 231
mridup 0:9e5d98ceea74 232 bool SPWFSA01::isConnected(void)
mridup 0:9e5d98ceea74 233 {
mridup 0:9e5d98ceea74 234 return getIPAddress() != 0;
mridup 0:9e5d98ceea74 235 }
mridup 0:9e5d98ceea74 236
mridup 3:2af9df1068a5 237 bool SPWFSA01::open(const char *type, int* id, const char* addr, int port)
mridup 0:9e5d98ceea74 238 {
mridup 13:f21e4e73bbb6 239 Timer timer;
mridup 13:f21e4e73bbb6 240 timer.start();
mridup 3:2af9df1068a5 241
mridup 3:2af9df1068a5 242 if(!_parser.send("AT+S.SOCKON=%s,%d,%s,ind", addr, port, type))
mridup 3:2af9df1068a5 243 {
mridup 13:f21e4e73bbb6 244 debug_if(dbg_on, "SPWF> error opening socket\r\n");
mridup 3:2af9df1068a5 245 return false;
mridup 3:2af9df1068a5 246 }
mridup 3:2af9df1068a5 247
mridup 3:2af9df1068a5 248 while(1)
mridup 3:2af9df1068a5 249 {
mridup 3:2af9df1068a5 250 if( _parser.recv(" ID: %d", id)
mridup 3:2af9df1068a5 251 && _parser.recv("OK"))
mridup 3:2af9df1068a5 252 break;
mridup 13:f21e4e73bbb6 253
mridup 13:f21e4e73bbb6 254 if (timer.read_ms() > SPWFSA01_CONNECT_TIMEOUT) {
mridup 13:f21e4e73bbb6 255 return false;
mridup 13:f21e4e73bbb6 256 }
mridup 13:f21e4e73bbb6 257
mridup 3:2af9df1068a5 258 //TODO:implement time-out functionality in case of no response
mridup 4:042d5b9bb6e7 259 //if(timeout) return false;
mridup 7:551de95939e2 260 //TODO: deal with errors like "ERROR: Failed to resolve name"
mridup 11:643a8c0f07ea 261 //TODO: deal with errors like "ERROR: Data mode not available"
mridup 3:2af9df1068a5 262 }
mridup 0:9e5d98ceea74 263
mridup 3:2af9df1068a5 264 return true;
mridup 0:9e5d98ceea74 265 }
mridup 0:9e5d98ceea74 266
mridup 0:9e5d98ceea74 267 bool SPWFSA01::send(int id, const void *data, uint32_t amount)
mridup 11:643a8c0f07ea 268 {
mridup 11:643a8c0f07ea 269 char _buf[18];
mridup 11:643a8c0f07ea 270
mridup 11:643a8c0f07ea 271 setTimeout(SPWFSA01_SEND_TIMEOUT);
mridup 11:643a8c0f07ea 272
mridup 11:643a8c0f07ea 273 sprintf((char*)_buf,"AT+S.SOCKW=%d,%d\r", id, amount);
mridup 11:643a8c0f07ea 274
mridup 0:9e5d98ceea74 275 //May take a second try if device is busy
mridup 0:9e5d98ceea74 276 for (unsigned i = 0; i < 2; i++) {
mridup 11:643a8c0f07ea 277 if (_parser.write((char*)_buf, strlen(_buf)) >=0
mridup 7:551de95939e2 278 && _parser.write((char*)data, (int)amount) >= 0
mridup 7:551de95939e2 279 && _parser.recv("OK")) {
mridup 0:9e5d98ceea74 280 return true;
mridup 0:9e5d98ceea74 281 }
mridup 0:9e5d98ceea74 282 }
mridup 0:9e5d98ceea74 283
mridup 0:9e5d98ceea74 284 return false;
mridup 0:9e5d98ceea74 285 }
mridup 0:9e5d98ceea74 286
mansiag 19:df8d7f70a740 287 /*
mridup 0:9e5d98ceea74 288 int32_t SPWFSA01::recv(int id, void *data, uint32_t amount)
mridup 0:9e5d98ceea74 289 {
mansiag 15:e56c9e744ab6 290 uint32_t recv_amount;
mridup 0:9e5d98ceea74 291 int recv_id;
mansiag 15:e56c9e744ab6 292 bool wind_recv = true;
mansiag 15:e56c9e744ab6 293
mridup 7:551de95939e2 294 if (!(_parser.recv("+WIND:55:Pending Data:%d:%u", &recv_id, &recv_amount)
mansiag 15:e56c9e744ab6 295 && recv_id == id
mansiag 15:e56c9e744ab6 296 && recv_amount <= amount
mansiag 15:e56c9e744ab6 297 && recv_amount%730
mansiag 15:e56c9e744ab6 298 && _parser.send("AT+S.SOCKQ=%d", id) //send a query (will be required for secure sockets)
mansiag 15:e56c9e744ab6 299 && _parser.recv(" DATALEN: %u", &recv_amount)
mansiag 15:e56c9e744ab6 300 && _parser.recv("OK")
mansiag 15:e56c9e744ab6 301 && recv_amount > 0
mansiag 15:e56c9e744ab6 302 && _parser.send("AT+S.SOCKR=%d,%d", id, recv_amount)
mansiag 15:e56c9e744ab6 303 && (_parser.read((char*)data, recv_amount) >0)
mansiag 15:e56c9e744ab6 304 && _parser.recv("OK"))) {
mansiag 15:e56c9e744ab6 305 if(!(recv_amount%730))
mansiag 15:e56c9e744ab6 306 {
mansiag 15:e56c9e744ab6 307 // receive all the WIND messages
mansiag 15:e56c9e744ab6 308 do {
mansiag 15:e56c9e744ab6 309 if (!(_parser.recv("+WIND:55:Pending Data:%d:%u", &recv_id, &recv_amount)
mansiag 15:e56c9e744ab6 310 && recv_id == id
mansiag 15:e56c9e744ab6 311 && recv_amount <= amount
mansiag 15:e56c9e744ab6 312 && recv_amount > 0))
mansiag 15:e56c9e744ab6 313 wind_recv = false;
mansiag 15:e56c9e744ab6 314 } while (!(recv_amount%730) && wind_recv);
mansiag 15:e56c9e744ab6 315
mansiag 15:e56c9e744ab6 316 // Read all the data pending on a socket
mansiag 15:e56c9e744ab6 317 if(!( recv_amount > 0
mansiag 15:e56c9e744ab6 318 && _parser.send("AT+S.SOCKR=%d,%d", id, recv_amount)
mansiag 15:e56c9e744ab6 319 && (_parser.read((char*)data, recv_amount) >0)
mansiag 15:e56c9e744ab6 320 && _parser.recv("OK"))) {
mansiag 15:e56c9e744ab6 321 return -1;
mansiag 15:e56c9e744ab6 322 }
mridup 13:f21e4e73bbb6 323 }
mansiag 15:e56c9e744ab6 324 else {
mansiag 15:e56c9e744ab6 325 return -2;
mridup 13:f21e4e73bbb6 326 }
mansiag 15:e56c9e744ab6 327 }
mridup 0:9e5d98ceea74 328 return recv_amount;
mridup 0:9e5d98ceea74 329 }
mansiag 19:df8d7f70a740 330 */
mansiag 19:df8d7f70a740 331
mansiag 19:df8d7f70a740 332 int32_t SPWFSA01::recv(int id, void *data, uint32_t amount)
mansiag 19:df8d7f70a740 333 {
mridup 20:01031cd39e73 334 Timer timer;
mridup 20:01031cd39e73 335 timer.start();
mridup 20:01031cd39e73 336
mansiag 19:df8d7f70a740 337 uint32_t recv_amount=0;
mridup 20:01031cd39e73 338 int recv_id;
mridup 20:01031cd39e73 339
mridup 20:01031cd39e73 340 if(!(_parser.recv("+WIND:55:Pending Data:%d:", &recv_id))) {
mridup 20:01031cd39e73 341 //do nothing;
mridup 20:01031cd39e73 342 debug_if(dbg_on, "SPWF> WIND:55 Timeout\r\n");
mridup 20:01031cd39e73 343 }
mansiag 19:df8d7f70a740 344
mansiag 19:df8d7f70a740 345 while(!recv_amount) {
mansiag 19:df8d7f70a740 346 if(!(_parser.send("AT+S.SOCKQ=%d", id) //send a query (will be required for secure sockets)
mansiag 19:df8d7f70a740 347 && _parser.recv(" DATALEN: %u", &recv_amount)
mansiag 19:df8d7f70a740 348 && _parser.recv("OK"))) {
mansiag 19:df8d7f70a740 349 return -2;
mansiag 19:df8d7f70a740 350 }
mridup 20:01031cd39e73 351 if (timer.read_ms() > SPWFSA01_SOCKQ_TIMEOUT) {
mansiag 22:2eb9b3c54506 352 return -1;
mridup 20:01031cd39e73 353 }
mansiag 19:df8d7f70a740 354 }
mansiag 19:df8d7f70a740 355 if(recv_amount > amount)
mansiag 19:df8d7f70a740 356 recv_amount = amount;
mansiag 19:df8d7f70a740 357
mansiag 19:df8d7f70a740 358 _parser.flush();
mansiag 21:cd722edbb644 359 if(!(_parser.send("AT+S.SOCKR=%d,%d", id, recv_amount)))
mansiag 21:cd722edbb644 360 return -2;
mansiag 21:cd722edbb644 361
mansiag 21:cd722edbb644 362 /* only when the data recv is greater than 3 bytes */
mansiag 21:cd722edbb644 363 if(recv_amount > 3) {
mansiag 21:cd722edbb644 364 /* look for WIND messages in data */
mansiag 21:cd722edbb644 365
mansiag 21:cd722edbb644 366 // get first 3 bytes of data
mansiag 21:cd722edbb644 367 for(int i=0;i<3;i++) {
mansiag 21:cd722edbb644 368 int c = -1;
mansiag 21:cd722edbb644 369 while(c < 0) {
mansiag 21:cd722edbb644 370 c = _parser.getc();
mansiag 21:cd722edbb644 371 }
mansiag 21:cd722edbb644 372 ((char *)data)[i] = c;
mansiag 21:cd722edbb644 373 }
mansiag 21:cd722edbb644 374
mansiag 21:cd722edbb644 375 /* 0xD: \r && 0xA: \n */
mansiag 21:cd722edbb644 376 if(((char *)data)[0] == 0xD
mansiag 21:cd722edbb644 377 &&((char *)data)[1] == 0xA
mansiag 21:cd722edbb644 378 &&((char *)data)[2] == '+') {
mansiag 21:cd722edbb644 379 ((char *)data)[0] = 0;
mansiag 21:cd722edbb644 380 while(((char *)data)[0] != 0xA) {
mansiag 21:cd722edbb644 381 ((char *)data)[0] = _parser.getc();
mansiag 21:cd722edbb644 382 }
mansiag 21:cd722edbb644 383
mansiag 21:cd722edbb644 384 // complete data is yet to be read
mansiag 21:cd722edbb644 385 if(!((_parser.read((char*)data, recv_amount) >0)
mansiag 21:cd722edbb644 386 && _parser.recv("OK"))) {
mansiag 21:cd722edbb644 387 return -2;
mansiag 21:cd722edbb644 388 }
mansiag 21:cd722edbb644 389 }
mansiag 21:cd722edbb644 390 else {
mansiag 21:cd722edbb644 391 // data left to be read is 3 bytes less.
mansiag 21:cd722edbb644 392 if(!((_parser.read((char*)data+3, recv_amount-3) >0)
mansiag 21:cd722edbb644 393 && _parser.recv("OK"))) {
mansiag 21:cd722edbb644 394 return -2;
mansiag 19:df8d7f70a740 395 }
mansiag 21:cd722edbb644 396 }
mansiag 21:cd722edbb644 397 }
mansiag 21:cd722edbb644 398 else {
mansiag 21:cd722edbb644 399 if(!((_parser.read((char*)data, recv_amount) >0)
mansiag 21:cd722edbb644 400 && _parser.recv("OK"))) {
mansiag 21:cd722edbb644 401 return -2;
mansiag 21:cd722edbb644 402 }
mansiag 21:cd722edbb644 403 }
mansiag 19:df8d7f70a740 404 return recv_amount;
mansiag 19:df8d7f70a740 405 }
mridup 0:9e5d98ceea74 406
mridup 0:9e5d98ceea74 407 bool SPWFSA01::close(int id)
mridup 0:9e5d98ceea74 408 {
mridup 4:042d5b9bb6e7 409 //May take a second try if device is busy or error is returned
mridup 0:9e5d98ceea74 410 for (unsigned i = 0; i < 2; i++) {
mridup 4:042d5b9bb6e7 411 if (_parser.send("AT+S.SOCKC=%d", id)
mridup 0:9e5d98ceea74 412 && _parser.recv("OK")) {
mridup 0:9e5d98ceea74 413 return true;
mridup 0:9e5d98ceea74 414 }
mridup 7:551de95939e2 415 else
mridup 7:551de95939e2 416 {
mridup 7:551de95939e2 417 if(_parser.recv("ERROR: Pending data"))
mridup 13:f21e4e73bbb6 418 debug_if(dbg_on, "SPWF> ERROR!!!!\r\n");
mridup 7:551de95939e2 419 return false;
mridup 7:551de95939e2 420 }
mridup 6:258b093eec08 421 //TODO: Deal with "ERROR: Pending data" (Closing a socket with pending data)
mridup 0:9e5d98ceea74 422 }
mridup 0:9e5d98ceea74 423
mridup 0:9e5d98ceea74 424 return false;
mridup 0:9e5d98ceea74 425 }
mridup 0:9e5d98ceea74 426
mridup 0:9e5d98ceea74 427 void SPWFSA01::setTimeout(uint32_t timeout_ms)
mridup 0:9e5d98ceea74 428 {
mridup 0:9e5d98ceea74 429 _parser.setTimeout(timeout_ms);
mridup 0:9e5d98ceea74 430 }
mridup 0:9e5d98ceea74 431
mridup 0:9e5d98ceea74 432 bool SPWFSA01::readable()
mridup 0:9e5d98ceea74 433 {
mridup 0:9e5d98ceea74 434 return _serial.readable();
mridup 0:9e5d98ceea74 435 }
mridup 0:9e5d98ceea74 436
mridup 0:9e5d98ceea74 437 bool SPWFSA01::writeable()
mridup 0:9e5d98ceea74 438 {
mridup 0:9e5d98ceea74 439 return _serial.writeable();
mridup 0:9e5d98ceea74 440 }