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.
SPWFSA01.cpp
00001 /* SPWFSA01 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 "SPWFSA01.h" 00018 #include "SpwfSAInterface.h" 00019 #include "mbed_debug.h" 00020 00021 #if MBED_CONF_IDW0XX1_EXPANSION_BOARD == IDW01M1 00022 00023 SPWFSA01::SPWFSA01(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 SPWFSA01::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,%s,ind", addr, port, type)) 00037 { 00038 debug_if(_dbg_on, "\r\nSPWF> `SPWFSA01::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 /* wait for first character */ 00047 trials = 0; 00048 while((value = _parser.getc()) < 0) { 00049 if(trials++ > SPWFXX_MAX_TRIALS) { 00050 debug("\r\nSPWF> error opening socket (%d)\r\n", __LINE__); 00051 empty_rx_buffer(); 00052 return false; 00053 } 00054 } 00055 00056 if(value != _cr_) { // Note: this is different to what the spec exactly says 00057 debug_if(_dbg_on, "\r\nSPWF> error opening socket (%d)\r\n", __LINE__); 00058 empty_rx_buffer(); 00059 return false; 00060 } 00061 00062 if(!_recv_delim_lf()) { // Note: this is different to what the spec exactly says 00063 debug_if(_dbg_on, "\r\nSPWF> error opening socket (%d)\r\n", __LINE__); 00064 empty_rx_buffer(); 00065 return false; 00066 } 00067 00068 value = _parser.getc(); 00069 switch(value) { 00070 case ' ': 00071 if(_parser.recv("ID: %d\n", &socket_id) 00072 && _recv_ok()) { 00073 debug_if(_dbg_on, "AT^ ID: %d\r\n", socket_id); 00074 00075 *spwf_id = socket_id; 00076 return true; 00077 } else { 00078 empty_rx_buffer(); 00079 } 00080 break; 00081 case 'E': 00082 if(_parser.recv("RROR: %255[^\n]\n", _msg_buffer) && _recv_delim_lf()) { 00083 debug_if(_dbg_on, "AT^ ERROR: %s (%d)\r\n", _msg_buffer, __LINE__); 00084 } else { 00085 debug_if(_dbg_on, "\r\nSPWF> error opening socket (%d)\r\n", __LINE__); 00086 empty_rx_buffer(); 00087 } 00088 break; 00089 default: 00090 debug_if(_dbg_on, "\r\nSPWF> error opening socket (value=%d, %d)\r\n", value, __LINE__); 00091 break; 00092 } 00093 00094 return false; 00095 } 00096 00097 int SPWFSA01::_read_in(char* buffer, int spwf_id, uint32_t amount) { 00098 int ret = -1; 00099 00100 MBED_ASSERT(buffer != NULL); 00101 00102 /* block asynchronous indications */ 00103 if(!_winds_off()) { 00104 return -1; 00105 } 00106 00107 /* read in data */ 00108 if(_parser.send("AT+S.SOCKR=%d,%u", spwf_id, (unsigned int)amount)) { 00109 /* set high timeout */ 00110 _parser.set_timeout(SPWF_READ_BIN_TIMEOUT); 00111 /* read in binary data */ 00112 int read = _parser.read(buffer, amount); 00113 /* reset timeout value */ 00114 _parser.set_timeout(_timeout); 00115 if(read > 0) { 00116 if(_recv_ok()) { 00117 ret = amount; 00118 00119 /* remove from pending sizes 00120 * (MUST be done before next async indications handling (e.g. `_winds_on()`)) */ 00121 _remove_pending_pkt_size(spwf_id, amount); 00122 } else { 00123 debug_if(_dbg_on, "\r\nSPWF> failed to receive OK (%s, %d)\r\n", __func__, __LINE__); 00124 empty_rx_buffer(); 00125 } 00126 } else { 00127 debug_if(_dbg_on, "\r\nSPWF> failed to read binary data (%u:%d), (%s, %d)\r\n", amount, read, __func__, __LINE__); 00128 empty_rx_buffer(); 00129 } 00130 } else { 00131 debug_if(_dbg_on, "\r\nSPWF> failed to send SOCKR (%s, %d)\r\n", __func__, __LINE__); 00132 } 00133 00134 debug_if(_dbg_on, "\r\nSPWF> %s():\t%d:%d\r\n", __func__, spwf_id, amount); 00135 00136 /* unblock asynchronous indications */ 00137 _winds_on(); 00138 00139 return ret; 00140 } 00141 00142 /* betzw - TODO: improve performance! */ 00143 bool SPWFSA01::_recv_ap(nsapi_wifi_ap_t *ap) 00144 { 00145 bool ret; 00146 unsigned int channel; 00147 int trials; 00148 00149 ap->security = NSAPI_SECURITY_UNKNOWN; 00150 00151 /* check for end of list */ 00152 if(_recv_delim_cr_lf()) { 00153 return false; 00154 } 00155 00156 /* run to 'horizontal tab' */ 00157 trials = 0; 00158 while(_parser.getc() != '\x09') { 00159 if(trials++ > SPWFXX_MAX_TRIALS) { 00160 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00161 return false; 00162 } 00163 } 00164 00165 /* read in next line */ 00166 ret = _parser.recv("%255[^\n]\n", _msg_buffer) && _recv_delim_lf(); 00167 00168 /* parse line - first phase */ 00169 if(ret) { 00170 int val = sscanf(_msg_buffer, 00171 " %*s %hhx:%hhx:%hhx:%hhx:%hhx:%hhx CHAN: %u RSSI: %hhd SSID: \'%*255[^\']\'", 00172 &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4], &ap->bssid[5], 00173 &channel, &ap->rssi); 00174 if(val < 8) { 00175 ret = false; 00176 } 00177 } 00178 00179 /* parse line - second phase */ 00180 if(ret) { // ret == true 00181 char value; 00182 char *rest, *first, *last; 00183 00184 /* decide about position of `CAPS:` */ 00185 first = strchr(_msg_buffer, '\''); 00186 if(first == NULL) { 00187 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00188 return false; 00189 } 00190 last = strrchr(_msg_buffer, '\''); 00191 if((last == NULL) || (last < (first+1))) { 00192 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00193 return false; 00194 } 00195 rest = strstr(last, "CAPS:"); 00196 if(rest == NULL) { 00197 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00198 return false; 00199 } 00200 00201 /* substitute '\'' with '\0' */ 00202 *last = '\0'; 00203 00204 /* copy values */ 00205 memcpy(&ap->ssid, first+1, sizeof(ap->ssid)-1); 00206 ap->ssid[sizeof(ap->ssid)-1] = '\0'; 00207 ap->channel = channel; 00208 00209 /* skip `CAPS: 0421 ` */ 00210 if(strlen(rest) < 11) { 00211 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00212 return false; 00213 } 00214 rest += 11; 00215 00216 /* get next character */ 00217 value = *rest++; 00218 if(value != 'W') { // no security 00219 ap->security = NSAPI_SECURITY_NONE; 00220 return true; 00221 } 00222 00223 /* determine security */ 00224 { 00225 char buffer[10]; 00226 00227 if(!(sscanf(rest, "%s%*[\x20]", (char*)&buffer) > 0)) { // '\0x20' == <space> 00228 return true; 00229 } else if(strncmp("EP", buffer, 10) == 0) { 00230 ap->security = NSAPI_SECURITY_WEP; 00231 return true; 00232 } else if(strncmp("PA2", buffer, 10) == 0) { 00233 ap->security = NSAPI_SECURITY_WPA2; 00234 return true; 00235 } else if(strncmp("PA", buffer, 10) != 0) { 00236 return true; 00237 } 00238 00239 /* got a "WPA", check for "WPA2" */ 00240 rest += strlen(buffer); 00241 value = *rest++; 00242 if(value == '\0') { // no further protocol 00243 ap->security = NSAPI_SECURITY_WPA; 00244 return true; 00245 } else { // assume "WPA2" 00246 ap->security = NSAPI_SECURITY_WPA_WPA2; 00247 return true; 00248 } 00249 } 00250 } else { // ret == false 00251 debug("\r\nSPWF> WARNING: might happen in case of RX buffer overflow! (%s, %d)\r\n", __func__, __LINE__); 00252 } 00253 00254 return ret; 00255 } 00256 00257 int SPWFSA01::scan(WiFiAccessPoint *res, unsigned limit) 00258 { 00259 unsigned cnt = 0; 00260 nsapi_wifi_ap_t ap; 00261 00262 if (!_parser.send("AT+S.SCAN=a,s")) { 00263 return NSAPI_ERROR_DEVICE_ERROR; 00264 } 00265 00266 while (_recv_ap(&ap)) { 00267 if (cnt < limit) { 00268 res[cnt] = WiFiAccessPoint(ap); 00269 } 00270 00271 cnt++; 00272 if (limit != 0 && cnt >= limit) { 00273 break; 00274 } 00275 } 00276 00277 if(!_recv_ok()) { 00278 empty_rx_buffer(); 00279 } 00280 00281 return cnt; 00282 } 00283 00284 #endif // MBED_CONF_IDW0XX1_EXPANSION_BOARD
Generated on Tue Jul 12 2022 16:59:38 by
1.7.2