Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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:59:38 by
1.7.2