Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
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:22:12 by 1.7.2