Toyomasa Watarai / Mbed OS Mbed-example-WS-W27

Dependencies:   MMA7660 LM75B

Committer:
MACRUM
Date:
Sat Jun 30 01:40:30 2018 +0000
Revision:
0:119624335925
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MACRUM 0:119624335925 1 /* SPWFSA04 Device
MACRUM 0:119624335925 2 * Copyright (c) 2015 ARM Limited
MACRUM 0:119624335925 3 *
MACRUM 0:119624335925 4 * Licensed under the Apache License, Version 2.0 (the "License");
MACRUM 0:119624335925 5 * you may not use this file except in compliance with the License.
MACRUM 0:119624335925 6 * You may obtain a copy of the License at
MACRUM 0:119624335925 7 *
MACRUM 0:119624335925 8 * http://www.apache.org/licenses/LICENSE-2.0
MACRUM 0:119624335925 9 *
MACRUM 0:119624335925 10 * Unless required by applicable law or agreed to in writing, software
MACRUM 0:119624335925 11 * distributed under the License is distributed on an "AS IS" BASIS,
MACRUM 0:119624335925 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MACRUM 0:119624335925 13 * See the License for the specific language governing permissions and
MACRUM 0:119624335925 14 * limitations under the License.
MACRUM 0:119624335925 15 */
MACRUM 0:119624335925 16
MACRUM 0:119624335925 17 #include "SPWFSA04.h"
MACRUM 0:119624335925 18 #include "SpwfSAInterface.h"
MACRUM 0:119624335925 19 #include "mbed_debug.h"
MACRUM 0:119624335925 20
MACRUM 0:119624335925 21 #if MBED_CONF_IDW0XX1_EXPANSION_BOARD == IDW04A1
MACRUM 0:119624335925 22
MACRUM 0:119624335925 23 SPWFSA04::SPWFSA04(PinName tx, PinName rx,
MACRUM 0:119624335925 24 PinName rts, PinName cts,
MACRUM 0:119624335925 25 SpwfSAInterface &ifce, bool debug,
MACRUM 0:119624335925 26 PinName wakeup, PinName reset)
MACRUM 0:119624335925 27 : SPWFSAxx(tx, rx, rts, cts, ifce, debug, wakeup, reset) {
MACRUM 0:119624335925 28 }
MACRUM 0:119624335925 29
MACRUM 0:119624335925 30 bool SPWFSA04::open(const char *type, int* spwf_id, const char* addr, int port)
MACRUM 0:119624335925 31 {
MACRUM 0:119624335925 32 int socket_id;
MACRUM 0:119624335925 33 int value;
MACRUM 0:119624335925 34 int trials;
MACRUM 0:119624335925 35
MACRUM 0:119624335925 36 if(!_parser.send("AT+S.SOCKON=%s,%d,NULL,%s", addr, port, type))
MACRUM 0:119624335925 37 {
MACRUM 0:119624335925 38 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d)\r\n", __LINE__);
MACRUM 0:119624335925 39 return false;
MACRUM 0:119624335925 40 }
MACRUM 0:119624335925 41
MACRUM 0:119624335925 42 /* handle both response possibilities here before returning
MACRUM 0:119624335925 43 * otherwise module seems to remain in inconsistent state.
MACRUM 0:119624335925 44 */
MACRUM 0:119624335925 45
MACRUM 0:119624335925 46 if(!_parser.recv("AT-S.")) { // get prefix
MACRUM 0:119624335925 47 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d)\r\n", __LINE__);
MACRUM 0:119624335925 48 empty_rx_buffer();
MACRUM 0:119624335925 49 return false;
MACRUM 0:119624335925 50 }
MACRUM 0:119624335925 51
MACRUM 0:119624335925 52 /* wait for next character */
MACRUM 0:119624335925 53 trials = 0;
MACRUM 0:119624335925 54 while((value = _parser.getc()) < 0) {
MACRUM 0:119624335925 55 if(++trials >= SPWFXX_MAX_TRIALS) {
MACRUM 0:119624335925 56 debug("\r\nSPWF> `SPWFSA04::open`: error opening socket (%d)\r\n", __LINE__);
MACRUM 0:119624335925 57 empty_rx_buffer();
MACRUM 0:119624335925 58 return false;
MACRUM 0:119624335925 59 }
MACRUM 0:119624335925 60 }
MACRUM 0:119624335925 61
MACRUM 0:119624335925 62 switch(value) {
MACRUM 0:119624335925 63 case 'O':
MACRUM 0:119624335925 64 /* get next character */
MACRUM 0:119624335925 65 value = _parser.getc();
MACRUM 0:119624335925 66 if(value != 'n') {
MACRUM 0:119624335925 67 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d) (%d, \'%c\')\r\n",
MACRUM 0:119624335925 68 __LINE__, value, value);
MACRUM 0:119624335925 69 empty_rx_buffer();
MACRUM 0:119624335925 70 return false;
MACRUM 0:119624335925 71 }
MACRUM 0:119624335925 72
MACRUM 0:119624335925 73 /* get socket id */
MACRUM 0:119624335925 74 if(!(_parser.recv(":%*u.%*u.%*u.%*u:%d\n", &socket_id)
MACRUM 0:119624335925 75 && _recv_delim_lf()
MACRUM 0:119624335925 76 && _recv_ok())) {
MACRUM 0:119624335925 77 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d)\r\n", __LINE__);
MACRUM 0:119624335925 78 empty_rx_buffer();
MACRUM 0:119624335925 79 return false;
MACRUM 0:119624335925 80 }
MACRUM 0:119624335925 81 debug_if(_dbg_on, "AT^ AT-S.On:%s:%d\r\n", addr, socket_id);
MACRUM 0:119624335925 82
MACRUM 0:119624335925 83 *spwf_id = socket_id;
MACRUM 0:119624335925 84 return true;
MACRUM 0:119624335925 85 case 'E':
MACRUM 0:119624335925 86 int err_nr;
MACRUM 0:119624335925 87 if(_parser.recv("RROR:%d:%255[^\n]\n", &err_nr, _msg_buffer) && _recv_delim_lf()) {
MACRUM 0:119624335925 88 debug_if(_dbg_on, "AT^ AT-S.ERROR:%d:%s (%d)\r\n", err_nr, _msg_buffer, __LINE__);
MACRUM 0:119624335925 89 } else {
MACRUM 0:119624335925 90 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d)\r\n", __LINE__);
MACRUM 0:119624335925 91 empty_rx_buffer();
MACRUM 0:119624335925 92 }
MACRUM 0:119624335925 93 break;
MACRUM 0:119624335925 94 default:
MACRUM 0:119624335925 95 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d) (%d, \'%c\')\r\n",
MACRUM 0:119624335925 96 __LINE__, value, value);
MACRUM 0:119624335925 97 empty_rx_buffer();
MACRUM 0:119624335925 98 break;
MACRUM 0:119624335925 99 }
MACRUM 0:119624335925 100
MACRUM 0:119624335925 101 return false;
MACRUM 0:119624335925 102 }
MACRUM 0:119624335925 103
MACRUM 0:119624335925 104 int SPWFSA04::_read_in(char* buffer, int spwf_id, uint32_t amount) {
MACRUM 0:119624335925 105 int ret = -1;
MACRUM 0:119624335925 106 int received, cumulative;
MACRUM 0:119624335925 107
MACRUM 0:119624335925 108 MBED_ASSERT(buffer != NULL);
MACRUM 0:119624335925 109
MACRUM 0:119624335925 110 /* block asynchronous indications */
MACRUM 0:119624335925 111 if(!_winds_off()) {
MACRUM 0:119624335925 112 return -1;
MACRUM 0:119624335925 113 }
MACRUM 0:119624335925 114
MACRUM 0:119624335925 115 /* read in data */
MACRUM 0:119624335925 116 if(_parser.send("AT+S.SOCKR=%d,%d", spwf_id, (unsigned int)amount)) {
MACRUM 0:119624335925 117 if(!(_parser.recv("AT-S.Reading:%d:%d\n", &received, &cumulative) &&
MACRUM 0:119624335925 118 _recv_delim_lf())) {
MACRUM 0:119624335925 119 debug_if(_dbg_on, "\r\nSPWF> failed to receive AT-S.Reading (%s, %d)\r\n", __func__, __LINE__);
MACRUM 0:119624335925 120 empty_rx_buffer();
MACRUM 0:119624335925 121 } else {
MACRUM 0:119624335925 122 /* set high timeout */
MACRUM 0:119624335925 123 _parser.set_timeout(SPWF_READ_BIN_TIMEOUT);
MACRUM 0:119624335925 124 /* read in binary data */
MACRUM 0:119624335925 125 int read = _parser.read(buffer, amount);
MACRUM 0:119624335925 126 /* reset timeout value */
MACRUM 0:119624335925 127 _parser.set_timeout(_timeout);
MACRUM 0:119624335925 128 if(read > 0) {
MACRUM 0:119624335925 129 if(_recv_ok()) {
MACRUM 0:119624335925 130 ret = amount;
MACRUM 0:119624335925 131
MACRUM 0:119624335925 132 /* remove from pending sizes
MACRUM 0:119624335925 133 * (MUST be done before next async indications handling (e.g. `_winds_on()`)) */
MACRUM 0:119624335925 134 _remove_pending_pkt_size(spwf_id, amount);
MACRUM 0:119624335925 135 } else {
MACRUM 0:119624335925 136 debug_if(_dbg_on, "\r\nSPWF> failed to receive OK (%s, %d)\r\n", __func__, __LINE__);
MACRUM 0:119624335925 137 empty_rx_buffer();
MACRUM 0:119624335925 138 }
MACRUM 0:119624335925 139 } else {
MACRUM 0:119624335925 140 debug_if(_dbg_on, "\r\nSPWF> failed to read binary data (%s, %d)\r\n", __func__, __LINE__);
MACRUM 0:119624335925 141 empty_rx_buffer();
MACRUM 0:119624335925 142 }
MACRUM 0:119624335925 143 }
MACRUM 0:119624335925 144 } else {
MACRUM 0:119624335925 145 debug_if(_dbg_on, "%s(%d): failed to send SOCKR\r\n", __func__, __LINE__);
MACRUM 0:119624335925 146 }
MACRUM 0:119624335925 147
MACRUM 0:119624335925 148 debug_if(_dbg_on, "\r\nSPWF> %s():\t%d:%d\r\n", __func__, spwf_id, amount);
MACRUM 0:119624335925 149
MACRUM 0:119624335925 150 /* unblock asynchronous indications */
MACRUM 0:119624335925 151 _winds_on();
MACRUM 0:119624335925 152
MACRUM 0:119624335925 153 return ret;
MACRUM 0:119624335925 154 }
MACRUM 0:119624335925 155
MACRUM 0:119624335925 156 /* betzw - TODO: improve performance! */
MACRUM 0:119624335925 157 bool SPWFSA04::_recv_ap(nsapi_wifi_ap_t *ap)
MACRUM 0:119624335925 158 {
MACRUM 0:119624335925 159 bool ret;
MACRUM 0:119624335925 160 int curr;
MACRUM 0:119624335925 161 unsigned int channel;
MACRUM 0:119624335925 162 int trials;
MACRUM 0:119624335925 163
MACRUM 0:119624335925 164 ap->security = NSAPI_SECURITY_UNKNOWN;
MACRUM 0:119624335925 165
MACRUM 0:119624335925 166 /* determine list end */
MACRUM 0:119624335925 167 curr = _parser.getc();
MACRUM 0:119624335925 168 if(curr == 'A') { // assume end of list ("AT-S.OK")
MACRUM 0:119624335925 169 if(!(_parser.recv("T-S.OK\n") && _recv_delim_lf())) {
MACRUM 0:119624335925 170 empty_rx_buffer();
MACRUM 0:119624335925 171 }
MACRUM 0:119624335925 172 return false;
MACRUM 0:119624335925 173 }
MACRUM 0:119624335925 174
MACRUM 0:119624335925 175 /* run to 'horizontal tab' */
MACRUM 0:119624335925 176 trials = 0;
MACRUM 0:119624335925 177 while(_parser.getc() != '\x09') {
MACRUM 0:119624335925 178 if(trials++ > SPWFXX_MAX_TRIALS) {
MACRUM 0:119624335925 179 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__);
MACRUM 0:119624335925 180 empty_rx_buffer();
MACRUM 0:119624335925 181 return false;
MACRUM 0:119624335925 182 }
MACRUM 0:119624335925 183 }
MACRUM 0:119624335925 184
MACRUM 0:119624335925 185 /* read in next line */
MACRUM 0:119624335925 186 ret = _parser.recv("%255[^\n]\n", _msg_buffer) && _recv_delim_lf();
MACRUM 0:119624335925 187
MACRUM 0:119624335925 188 /* parse line - first phase */
MACRUM 0:119624335925 189 if(ret) {
MACRUM 0:119624335925 190 int val = sscanf(_msg_buffer,
MACRUM 0:119624335925 191 " %*s %hhx:%hhx:%hhx:%hhx:%hhx:%hhx CHAN: %u RSSI: %hhd SSID: \'%*255[^\']\'",
MACRUM 0:119624335925 192 &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4], &ap->bssid[5],
MACRUM 0:119624335925 193 &channel, &ap->rssi);
MACRUM 0:119624335925 194 if(val < 8) {
MACRUM 0:119624335925 195 ret = false;
MACRUM 0:119624335925 196 }
MACRUM 0:119624335925 197 }
MACRUM 0:119624335925 198
MACRUM 0:119624335925 199 /* parse line - second phase */
MACRUM 0:119624335925 200 if(ret) { // ret == true
MACRUM 0:119624335925 201 char value;
MACRUM 0:119624335925 202 char *rest, *first, *last;
MACRUM 0:119624335925 203
MACRUM 0:119624335925 204 /* decide about position of `CAPS:` */
MACRUM 0:119624335925 205 first = strchr(_msg_buffer, '\'');
MACRUM 0:119624335925 206 if(first == NULL) {
MACRUM 0:119624335925 207 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__);
MACRUM 0:119624335925 208 empty_rx_buffer();
MACRUM 0:119624335925 209 return false;
MACRUM 0:119624335925 210 }
MACRUM 0:119624335925 211 last = strrchr(_msg_buffer, '\'');
MACRUM 0:119624335925 212 if((last == NULL) || (last < (first+1))) {
MACRUM 0:119624335925 213 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__);
MACRUM 0:119624335925 214 empty_rx_buffer();
MACRUM 0:119624335925 215 return false;
MACRUM 0:119624335925 216 }
MACRUM 0:119624335925 217 rest = strstr(last, "CAPS:");
MACRUM 0:119624335925 218 if(rest == NULL) {
MACRUM 0:119624335925 219 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__);
MACRUM 0:119624335925 220 empty_rx_buffer();
MACRUM 0:119624335925 221 return false;
MACRUM 0:119624335925 222 }
MACRUM 0:119624335925 223
MACRUM 0:119624335925 224 /* substitute '\'' with '\0' */
MACRUM 0:119624335925 225 *last = '\0';
MACRUM 0:119624335925 226
MACRUM 0:119624335925 227 /* copy values */
MACRUM 0:119624335925 228 memcpy(&ap->ssid, first+1, sizeof(ap->ssid)-1);
MACRUM 0:119624335925 229 ap->ssid[sizeof(ap->ssid)-1] = '\0';
MACRUM 0:119624335925 230 ap->channel = channel;
MACRUM 0:119624335925 231
MACRUM 0:119624335925 232 /* skip `CAPS: 0421 ` */
MACRUM 0:119624335925 233 if(strlen(rest) < 11) {
MACRUM 0:119624335925 234 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__);
MACRUM 0:119624335925 235 empty_rx_buffer();
MACRUM 0:119624335925 236 return false;
MACRUM 0:119624335925 237 }
MACRUM 0:119624335925 238 rest += 11;
MACRUM 0:119624335925 239
MACRUM 0:119624335925 240 /* get next character */
MACRUM 0:119624335925 241 value = *rest++;
MACRUM 0:119624335925 242 if(value != 'W') { // no security
MACRUM 0:119624335925 243 ap->security = NSAPI_SECURITY_NONE;
MACRUM 0:119624335925 244 return true;
MACRUM 0:119624335925 245 }
MACRUM 0:119624335925 246
MACRUM 0:119624335925 247 /* determine security */
MACRUM 0:119624335925 248 {
MACRUM 0:119624335925 249 char buffer[10];
MACRUM 0:119624335925 250
MACRUM 0:119624335925 251 if(!(sscanf(rest, "%s%*[\x20]", (char*)&buffer) > 0)) { // '\0x20' == <space>
MACRUM 0:119624335925 252 return true;
MACRUM 0:119624335925 253 } else if(strncmp("EP", buffer, 10) == 0) {
MACRUM 0:119624335925 254 ap->security = NSAPI_SECURITY_WEP;
MACRUM 0:119624335925 255 return true;
MACRUM 0:119624335925 256 } else if(strncmp("PA2", buffer, 10) == 0) {
MACRUM 0:119624335925 257 ap->security = NSAPI_SECURITY_WPA2;
MACRUM 0:119624335925 258 return true;
MACRUM 0:119624335925 259 } else if(strncmp("PA", buffer, 10) != 0) {
MACRUM 0:119624335925 260 return true;
MACRUM 0:119624335925 261 }
MACRUM 0:119624335925 262
MACRUM 0:119624335925 263 /* got a "WPA", check for "WPA2" */
MACRUM 0:119624335925 264 rest += strlen(buffer);
MACRUM 0:119624335925 265 value = *rest++;
MACRUM 0:119624335925 266 if(value == '\0') { // no further protocol
MACRUM 0:119624335925 267 ap->security = NSAPI_SECURITY_WPA;
MACRUM 0:119624335925 268 return true;
MACRUM 0:119624335925 269 } else { // assume "WPA2"
MACRUM 0:119624335925 270 ap->security = NSAPI_SECURITY_WPA_WPA2;
MACRUM 0:119624335925 271 return true;
MACRUM 0:119624335925 272 }
MACRUM 0:119624335925 273 }
MACRUM 0:119624335925 274 } else { // ret == false
MACRUM 0:119624335925 275 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__);
MACRUM 0:119624335925 276 empty_rx_buffer();
MACRUM 0:119624335925 277 }
MACRUM 0:119624335925 278
MACRUM 0:119624335925 279 return ret;
MACRUM 0:119624335925 280 }
MACRUM 0:119624335925 281
MACRUM 0:119624335925 282 nsapi_size_or_error_t SPWFSA04::scan(WiFiAccessPoint *res, unsigned limit)
MACRUM 0:119624335925 283 {
MACRUM 0:119624335925 284 unsigned int cnt = 0, found;
MACRUM 0:119624335925 285 nsapi_wifi_ap_t ap;
MACRUM 0:119624335925 286
MACRUM 0:119624335925 287 if (!_parser.send("AT+S.SCAN=s,")) {
MACRUM 0:119624335925 288 return NSAPI_ERROR_DEVICE_ERROR;
MACRUM 0:119624335925 289 }
MACRUM 0:119624335925 290
MACRUM 0:119624335925 291 if(!(_parser.recv("AT-S.Parsing Networks:%u\n", &found) && _recv_delim_lf())) {
MACRUM 0:119624335925 292 debug_if(_dbg_on, "SPWF> error start network scanning\r\n");
MACRUM 0:119624335925 293 empty_rx_buffer();
MACRUM 0:119624335925 294 return NSAPI_ERROR_DEVICE_ERROR;
MACRUM 0:119624335925 295 }
MACRUM 0:119624335925 296
MACRUM 0:119624335925 297 debug_if(_dbg_on, "AT^ AT-S.Parsing Networks:%u\r\n", found);
MACRUM 0:119624335925 298
MACRUM 0:119624335925 299 if(found > 0) {
MACRUM 0:119624335925 300 while (_recv_ap(&ap)) {
MACRUM 0:119624335925 301 if (cnt < limit) {
MACRUM 0:119624335925 302 res[cnt] = WiFiAccessPoint(ap);
MACRUM 0:119624335925 303 }
MACRUM 0:119624335925 304
MACRUM 0:119624335925 305 if (!((limit != 0) && ((cnt + 1) > limit))) {
MACRUM 0:119624335925 306 cnt++;
MACRUM 0:119624335925 307 }
MACRUM 0:119624335925 308 }
MACRUM 0:119624335925 309 } else {
MACRUM 0:119624335925 310 if(!_recv_ok()) {
MACRUM 0:119624335925 311 empty_rx_buffer();
MACRUM 0:119624335925 312 }
MACRUM 0:119624335925 313 }
MACRUM 0:119624335925 314
MACRUM 0:119624335925 315 return cnt;
MACRUM 0:119624335925 316 }
MACRUM 0:119624335925 317
MACRUM 0:119624335925 318 #endif // MBED_CONF_IDW0XX1_EXPANSION_BOARD