Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
SPWFSA04.cpp
00001 /* SPWFSA04 Device 00002 * Copyright (c) 2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "SPWFSA04.h" 00018 #include "SpwfSAInterface.h" 00019 #include "mbed_debug.h" 00020 00021 #if MBED_CONF_IDW0XX1_EXPANSION_BOARD == IDW04A1 00022 00023 SPWFSA04::SPWFSA04(PinName tx, PinName rx, 00024 PinName rts, PinName cts, 00025 SpwfSAInterface &ifce, bool debug, 00026 PinName wakeup, PinName reset) 00027 : SPWFSAxx(tx, rx, rts, cts, ifce, debug, wakeup, reset) { 00028 } 00029 00030 bool SPWFSA04::open(const char *type, int* spwf_id, const char* addr, int port) 00031 { 00032 int socket_id; 00033 int value; 00034 int trials; 00035 00036 if(!_parser.send("AT+S.SOCKON=%s,%d,NULL,%s", addr, port, type)) 00037 { 00038 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d)\r\n", __LINE__); 00039 return false; 00040 } 00041 00042 /* handle both response possibilities here before returning 00043 * otherwise module seems to remain in inconsistent state. 00044 */ 00045 00046 if(!_parser.recv("AT-S.")) { // get prefix 00047 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d)\r\n", __LINE__); 00048 empty_rx_buffer(); 00049 return false; 00050 } 00051 00052 /* wait for next character */ 00053 trials = 0; 00054 while((value = _parser.getc()) < 0) { 00055 if(++trials >= SPWFXX_MAX_TRIALS) { 00056 debug("\r\nSPWF> `SPWFSA04::open`: error opening socket (%d)\r\n", __LINE__); 00057 empty_rx_buffer(); 00058 return false; 00059 } 00060 } 00061 00062 switch(value) { 00063 case 'O': 00064 /* get next character */ 00065 value = _parser.getc(); 00066 if(value != 'n') { 00067 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d) (%d, \'%c\')\r\n", 00068 __LINE__, value, value); 00069 empty_rx_buffer(); 00070 return false; 00071 } 00072 00073 /* get socket id */ 00074 if(!(_parser.recv(":%*u.%*u.%*u.%*u:%d\n", &socket_id) 00075 && _recv_delim_lf() 00076 && _recv_ok())) { 00077 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d)\r\n", __LINE__); 00078 empty_rx_buffer(); 00079 return false; 00080 } 00081 debug_if(_dbg_on, "AT^ AT-S.On:%s:%d\r\n", addr, socket_id); 00082 00083 *spwf_id = socket_id; 00084 return true; 00085 case 'E': 00086 int err_nr; 00087 if(_parser.recv("RROR:%d:%255[^\n]\n", &err_nr, _msg_buffer) && _recv_delim_lf()) { 00088 debug_if(_dbg_on, "AT^ AT-S.ERROR:%d:%s (%d)\r\n", err_nr, _msg_buffer, __LINE__); 00089 } else { 00090 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d)\r\n", __LINE__); 00091 empty_rx_buffer(); 00092 } 00093 break; 00094 default: 00095 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA04::open`: error opening socket (%d) (%d, \'%c\')\r\n", 00096 __LINE__, value, value); 00097 empty_rx_buffer(); 00098 break; 00099 } 00100 00101 return false; 00102 } 00103 00104 int SPWFSA04::_read_in(char* buffer, int spwf_id, uint32_t amount) { 00105 int ret = -1; 00106 int received, cumulative; 00107 00108 MBED_ASSERT(buffer != NULL); 00109 00110 /* block asynchronous indications */ 00111 if(!_winds_off()) { 00112 return -1; 00113 } 00114 00115 /* read in data */ 00116 if(_parser.send("AT+S.SOCKR=%d,%d", spwf_id, (unsigned int)amount)) { 00117 if(!(_parser.recv("AT-S.Reading:%d:%d\n", &received, &cumulative) && 00118 _recv_delim_lf())) { 00119 debug_if(_dbg_on, "\r\nSPWF> failed to receive AT-S.Reading (%s, %d)\r\n", __func__, __LINE__); 00120 empty_rx_buffer(); 00121 } else { 00122 /* set high timeout */ 00123 _parser.set_timeout(SPWF_READ_BIN_TIMEOUT); 00124 /* read in binary data */ 00125 int read = _parser.read(buffer, amount); 00126 /* reset timeout value */ 00127 _parser.set_timeout(_timeout); 00128 if(read > 0) { 00129 if(_recv_ok()) { 00130 ret = amount; 00131 00132 /* remove from pending sizes 00133 * (MUST be done before next async indications handling (e.g. `_winds_on()`)) */ 00134 _remove_pending_pkt_size(spwf_id, amount); 00135 } else { 00136 debug_if(_dbg_on, "\r\nSPWF> failed to receive OK (%s, %d)\r\n", __func__, __LINE__); 00137 empty_rx_buffer(); 00138 } 00139 } else { 00140 debug_if(_dbg_on, "\r\nSPWF> failed to read binary data (%s, %d)\r\n", __func__, __LINE__); 00141 empty_rx_buffer(); 00142 } 00143 } 00144 } else { 00145 debug_if(_dbg_on, "%s(%d): failed to send SOCKR\r\n", __func__, __LINE__); 00146 } 00147 00148 debug_if(_dbg_on, "\r\nSPWF> %s():\t%d:%d\r\n", __func__, spwf_id, amount); 00149 00150 /* unblock asynchronous indications */ 00151 _winds_on(); 00152 00153 return ret; 00154 } 00155 00156 /* betzw - TODO: improve performance! */ 00157 bool SPWFSA04::_recv_ap(nsapi_wifi_ap_t *ap) 00158 { 00159 bool ret; 00160 int curr; 00161 unsigned int channel; 00162 int trials; 00163 00164 ap->security = NSAPI_SECURITY_UNKNOWN; 00165 00166 /* determine list end */ 00167 curr = _parser.getc(); 00168 if(curr == 'A') { // assume end of list ("AT-S.OK") 00169 if(!(_parser.recv("T-S.OK\n") && _recv_delim_lf())) { 00170 empty_rx_buffer(); 00171 } 00172 return false; 00173 } 00174 00175 /* run to 'horizontal tab' */ 00176 trials = 0; 00177 while(_parser.getc() != '\x09') { 00178 if(trials++ > SPWFXX_MAX_TRIALS) { 00179 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00180 empty_rx_buffer(); 00181 return false; 00182 } 00183 } 00184 00185 /* read in next line */ 00186 ret = _parser.recv("%255[^\n]\n", _msg_buffer) && _recv_delim_lf(); 00187 00188 /* parse line - first phase */ 00189 if(ret) { 00190 int val = sscanf(_msg_buffer, 00191 " %*s %hhx:%hhx:%hhx:%hhx:%hhx:%hhx CHAN: %u RSSI: %hhd SSID: \'%*255[^\']\'", 00192 &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4], &ap->bssid[5], 00193 &channel, &ap->rssi); 00194 if(val < 8) { 00195 ret = false; 00196 } 00197 } 00198 00199 /* parse line - second phase */ 00200 if(ret) { // ret == true 00201 char value; 00202 char *rest, *first, *last; 00203 00204 /* decide about position of `CAPS:` */ 00205 first = strchr(_msg_buffer, '\''); 00206 if(first == NULL) { 00207 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00208 empty_rx_buffer(); 00209 return false; 00210 } 00211 last = strrchr(_msg_buffer, '\''); 00212 if((last == NULL) || (last < (first+1))) { 00213 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00214 empty_rx_buffer(); 00215 return false; 00216 } 00217 rest = strstr(last, "CAPS:"); 00218 if(rest == NULL) { 00219 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00220 empty_rx_buffer(); 00221 return false; 00222 } 00223 00224 /* substitute '\'' with '\0' */ 00225 *last = '\0'; 00226 00227 /* copy values */ 00228 memcpy(&ap->ssid, first+1, sizeof(ap->ssid)-1); 00229 ap->ssid[sizeof(ap->ssid)-1] = '\0'; 00230 ap->channel = channel; 00231 00232 /* skip `CAPS: 0421 ` */ 00233 if(strlen(rest) < 11) { 00234 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00235 empty_rx_buffer(); 00236 return false; 00237 } 00238 rest += 11; 00239 00240 /* get next character */ 00241 value = *rest++; 00242 if(value != 'W') { // no security 00243 ap->security = NSAPI_SECURITY_NONE; 00244 return true; 00245 } 00246 00247 /* determine security */ 00248 { 00249 char buffer[10]; 00250 00251 if(!(sscanf(rest, "%s%*[\x20]", (char*)&buffer) > 0)) { // '\0x20' == <space> 00252 return true; 00253 } else if(strncmp("EP", buffer, 10) == 0) { 00254 ap->security = NSAPI_SECURITY_WEP; 00255 return true; 00256 } else if(strncmp("PA2", buffer, 10) == 0) { 00257 ap->security = NSAPI_SECURITY_WPA2; 00258 return true; 00259 } else if(strncmp("PA", buffer, 10) != 0) { 00260 return true; 00261 } 00262 00263 /* got a "WPA", check for "WPA2" */ 00264 rest += strlen(buffer); 00265 value = *rest++; 00266 if(value == '\0') { // no further protocol 00267 ap->security = NSAPI_SECURITY_WPA; 00268 return true; 00269 } else { // assume "WPA2" 00270 ap->security = NSAPI_SECURITY_WPA_WPA2; 00271 return true; 00272 } 00273 } 00274 } else { // ret == false 00275 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00276 empty_rx_buffer(); 00277 } 00278 00279 return ret; 00280 } 00281 00282 nsapi_size_or_error_t SPWFSA04::scan(WiFiAccessPoint *res, unsigned limit) 00283 { 00284 unsigned int cnt = 0, found; 00285 nsapi_wifi_ap_t ap; 00286 00287 if (!_parser.send("AT+S.SCAN=s,")) { 00288 return NSAPI_ERROR_DEVICE_ERROR; 00289 } 00290 00291 if(!(_parser.recv("AT-S.Parsing Networks:%u\n", &found) && _recv_delim_lf())) { 00292 debug_if(_dbg_on, "SPWF> error start network scanning\r\n"); 00293 empty_rx_buffer(); 00294 return NSAPI_ERROR_DEVICE_ERROR; 00295 } 00296 00297 debug_if(_dbg_on, "AT^ AT-S.Parsing Networks:%u\r\n", found); 00298 00299 if(found > 0) { 00300 while (_recv_ap(&ap)) { 00301 if (cnt < limit) { 00302 res[cnt] = WiFiAccessPoint(ap); 00303 } 00304 00305 if (!((limit != 0) && ((cnt + 1) > limit))) { 00306 cnt++; 00307 } 00308 } 00309 } else { 00310 if(!_recv_ok()) { 00311 empty_rx_buffer(); 00312 } 00313 } 00314 00315 return cnt; 00316 } 00317 00318 #endif // MBED_CONF_IDW0XX1_EXPANSION_BOARD
Generated on Tue Jul 12 2022 16:22:12 by 1.7.2