[LR11x0] Added support for WiFi scanning
This commit is contained in:
parent
bb7fffe95d
commit
86cdefe8a2
6 changed files with 616 additions and 14 deletions
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
RadioLib LR11x0 WiFi scan Blocking Example
|
||||
|
||||
This example performs a passive scan of WiFi networks.
|
||||
The scan shows basic information about the networks,
|
||||
such as the frequency, country code and SSID.
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
Using blocking scan is not recommended, as depending
|
||||
on the scan settings, the program may be blocked
|
||||
for several seconds! Instead, interrupt scan is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---wifi-scan
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//LR1110 radio = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[LR1110] Running WiFi scan ... "));
|
||||
|
||||
// scan all WiFi signals with default scan configuration
|
||||
uint8_t count = 0;
|
||||
int state = radio.wifiScan('*', &count);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the table header
|
||||
Serial.print(F("[LR1110] Reading "));
|
||||
Serial.print(count);
|
||||
Serial.println(F(" scan results:"));
|
||||
Serial.println(F(" # | WiFi type\t| Frequency\t| MAC Address\t | Country\t| RSSI [dBm]\t| SSID"));
|
||||
|
||||
// read all results one by one
|
||||
// this result type contains the most information, including the SSID
|
||||
LR11x0WifiResultExtended_t result;
|
||||
for(int i = 0; i < count; i++) {
|
||||
if(i < 10) { Serial.print(" "); } Serial.print(i); Serial.print(" | ");
|
||||
state = radio.getWifiScanResult(&result, i);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Failed to read result, code "));
|
||||
Serial.println(state);
|
||||
continue;
|
||||
}
|
||||
|
||||
// print the basic information
|
||||
Serial.print(F("802.11")); Serial.print(result.type); Serial.print("\t| ");
|
||||
Serial.print(result.channelFreq); Serial.print(" MHz\t| ");
|
||||
|
||||
// print MAC address
|
||||
for(int j = 0; j < 6; j++) {
|
||||
if(result.mac[j] < 0x10) { Serial.print("0"); }
|
||||
Serial.print(result.mac[j], HEX);
|
||||
if(j < 5) { Serial.print(":"); }
|
||||
}
|
||||
Serial.print(" | ");
|
||||
|
||||
// print the two-letter country code
|
||||
String country = result.countryCode;
|
||||
Serial.print(country);
|
||||
Serial.print(" \t| ");
|
||||
|
||||
// print the RSSI
|
||||
Serial.print(result.rssi);
|
||||
Serial.print("\t| ");
|
||||
|
||||
// print the network SSID
|
||||
Serial.println((char*)result.ssid);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before scanning again
|
||||
delay(1000);
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
RadioLib LR11x0 WiFi scan Interrupt Example
|
||||
|
||||
This example performs a passive scan of WiFi networks.
|
||||
The scan shows basic information about the networks,
|
||||
such as the frequency, country code and SSID.
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
Using blocking scan is not recommended, as depending
|
||||
on the scan settings, the program may be blocked
|
||||
for several seconds! Instead, interrupt scan is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---wifi-scan
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//LR1110 radio = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when WiFi scan is complete
|
||||
radio.setIrqAction(setFlag);
|
||||
|
||||
// scan all WiFi signals with default scan configuration
|
||||
Serial.print(F("[LR1110] Starting passive WiFi scan ... "));
|
||||
state = radio.startWifiScan('*');
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
// flag to indicate that a scan was completed
|
||||
volatile bool scanFlag = false;
|
||||
|
||||
// this function is called when a scan is completed
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// scan is complete, set the flag
|
||||
scanFlag = true;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(scanFlag) {
|
||||
// reset flag
|
||||
scanFlag = false;
|
||||
|
||||
// get the number of scan results
|
||||
uint8_t count = 0;
|
||||
Serial.print(F("[LR1110] Reading WiFi scan results ... "));
|
||||
int state = radio.getWifiScanResultsCount(&count);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the table header
|
||||
Serial.print(F("[LR1110] Reading "));
|
||||
Serial.print(count);
|
||||
Serial.println(F(" scan results:"));
|
||||
Serial.println(F(" # | WiFi type\t| Frequency\t| MAC Address\t | Country\t| RSSI [dBm]\t| SSID"));
|
||||
|
||||
// read all results one by one
|
||||
// this result type contains the most information, including the SSID
|
||||
LR11x0WifiResultExtended_t result;
|
||||
for(int i = 0; i < count; i++) {
|
||||
if(i < 10) { Serial.print(" "); } Serial.print(i); Serial.print(" | ");
|
||||
state = radio.getWifiScanResult(&result, i);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Failed to read result, code "));
|
||||
Serial.println(state);
|
||||
continue;
|
||||
}
|
||||
|
||||
// print the basic information
|
||||
Serial.print(F("802.11")); Serial.print(result.type); Serial.print("\t| ");
|
||||
Serial.print(result.channelFreq); Serial.print(" MHz\t| ");
|
||||
|
||||
// print MAC address
|
||||
for(int j = 0; j < 6; j++) {
|
||||
if(result.mac[j] < 0x10) { Serial.print("0"); }
|
||||
Serial.print(result.mac[j], HEX);
|
||||
if(j < 5) { Serial.print(":"); }
|
||||
}
|
||||
Serial.print(" | ");
|
||||
|
||||
// print the two-letter country code
|
||||
String country = result.countryCode;
|
||||
Serial.print(country);
|
||||
Serial.print(" \t| ");
|
||||
|
||||
// print the RSSI
|
||||
Serial.print(result.rssi);
|
||||
Serial.print("\t| ");
|
||||
|
||||
// print the network SSID
|
||||
Serial.println((char*)result.ssid);
|
||||
}
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// start scanning again
|
||||
Serial.print(F("[LR1110] Starting passive WiFi scan ... "));
|
||||
state = radio.startWifiScan('*');
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
}
|
11
keywords.txt
11
keywords.txt
|
@ -91,6 +91,11 @@ AS923 KEYWORD1
|
|||
KR920 KEYWORD1
|
||||
IN865 KEYWORD1
|
||||
|
||||
# LR11x0 scan results
|
||||
LR11x0WifiResult_t KEYWORD1
|
||||
LR11x0WifiResultFull_t KEYWORD1
|
||||
LR11x0WifiResultExtended_t KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
@ -243,6 +248,12 @@ setAutoAck KEYWORD2
|
|||
# LR11x0
|
||||
beginLRFHSS KEYWORD2
|
||||
setLrFhssConfig KEYWORD2
|
||||
startWifiScan KEYWORD2
|
||||
getWifiScanResultsCount KEYWORD2
|
||||
getWifiScanResult KEYWORD2
|
||||
wifiScan KEYWORD2
|
||||
setWiFiScanAction KEYWORD2
|
||||
clearWiFiScanAction KEYWORD2
|
||||
|
||||
# RTTY
|
||||
idle KEYWORD2
|
||||
|
|
|
@ -563,6 +563,13 @@
|
|||
*/
|
||||
#define RADIOLIB_LORAWAN_NO_DOWNLINK (-1116)
|
||||
|
||||
// LR11x0-specific status codes
|
||||
|
||||
/*!
|
||||
\brief The selected 802.11 WiFi type is invalid.
|
||||
*/
|
||||
#define RADIOLIB_ERR_INVALID_WIFI_TYPE (-1200)
|
||||
|
||||
/*!
|
||||
\}
|
||||
*/
|
||||
|
|
|
@ -1335,6 +1335,168 @@ int16_t LR11x0::setLrFhssConfig(uint8_t bw, uint8_t cr, uint8_t hdrCount, uint16
|
|||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t LR11x0::startWifiScan(char wifiType, uint8_t mode, uint16_t chanMask, uint8_t numScans, uint16_t timeout) {
|
||||
uint8_t type;
|
||||
switch(wifiType) {
|
||||
case('b'):
|
||||
type = RADIOLIB_LR11X0_WIFI_SCAN_802_11_B;
|
||||
break;
|
||||
case('g'):
|
||||
type = RADIOLIB_LR11X0_WIFI_SCAN_802_11_G;
|
||||
break;
|
||||
case('n'):
|
||||
type = RADIOLIB_LR11X0_WIFI_SCAN_802_11_N;
|
||||
break;
|
||||
case('*'):
|
||||
type = RADIOLIB_LR11X0_WIFI_SCAN_ALL;
|
||||
break;
|
||||
default:
|
||||
return(RADIOLIB_ERR_INVALID_WIFI_TYPE);
|
||||
}
|
||||
|
||||
// go to standby
|
||||
int16_t state = standby();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// reset cumulative timings
|
||||
state = wifiResetCumulTimings();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set DIO mapping
|
||||
state = setDioIrqParams(RADIOLIB_LR11X0_IRQ_WIFI_DONE, 0);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// start scan with the maximum number of results and abort on timeout
|
||||
this->wifiScanMode = mode;
|
||||
state = wifiScan(type, chanMask, this->wifiScanMode, RADIOLIB_LR11X0_WIFI_MAX_NUM_RESULTS, numScans, timeout, RADIOLIB_LR11X0_WIFI_ABORT_ON_TIMEOUT_ENABLED);
|
||||
return(state);
|
||||
}
|
||||
|
||||
void LR11x0::setWiFiScanAction(void (*func)(void)) {
|
||||
this->setIrqAction(func);
|
||||
}
|
||||
|
||||
void LR11x0::clearWiFiScanAction() {
|
||||
this->clearIrqAction();
|
||||
}
|
||||
|
||||
int16_t LR11x0::getWifiScanResultsCount(uint8_t* count) {
|
||||
// clear IRQ first, as this is likely to be called right after scan has finished
|
||||
int16_t state = clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
uint8_t buff[1] = { 0 };
|
||||
state = this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_GET_NB_RESULTS, false, buff, sizeof(buff));
|
||||
|
||||
// pass the replies
|
||||
if(count) { *count = buff[0]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::getWifiScanResult(LR11x0WifiResult_t* result, uint8_t index, bool brief) {
|
||||
if(!result) {
|
||||
return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
|
||||
}
|
||||
|
||||
// read a single result
|
||||
uint8_t format = brief ? RADIOLIB_LR11X0_WIFI_RESULT_TYPE_BASIC : RADIOLIB_LR11X0_WIFI_RESULT_TYPE_COMPLETE;
|
||||
uint8_t raw[RADIOLIB_LR11X0_WIFI_RESULT_MAX_LEN] = { 0 };
|
||||
int16_t state = wifiReadResults(index, 1, format, raw);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// parse the information
|
||||
switch(raw[0] & 0x03) {
|
||||
case(RADIOLIB_LR11X0_WIFI_SCAN_802_11_B):
|
||||
result->type = 'b';
|
||||
break;
|
||||
case(RADIOLIB_LR11X0_WIFI_SCAN_802_11_G):
|
||||
result->type = 'g';
|
||||
break;
|
||||
case(RADIOLIB_LR11X0_WIFI_SCAN_802_11_N):
|
||||
result->type = 'n';
|
||||
break;
|
||||
}
|
||||
result->dataRateId = (raw[0] & 0xFC) >> 2;
|
||||
result->channelFreq = 2407 + (raw[1] & 0x0F)*5;
|
||||
result->origin = (raw[1] & 0x30) >> 4;
|
||||
result->ap = (raw[1] & 0x40) != 0;
|
||||
result->rssi = (float)raw[2] / -2.0f;;
|
||||
memcpy(result->mac, &raw[3], RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN);
|
||||
|
||||
if(!brief) {
|
||||
if(this->wifiScanMode == RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON) {
|
||||
LR11x0WifiResultExtended_t* resultExtended = (LR11x0WifiResultExtended_t*)result;
|
||||
resultExtended->rate = raw[3];
|
||||
resultExtended->service = (((uint16_t)raw[4] << 8) | ((uint16_t)raw[5]));
|
||||
resultExtended->length = (((uint16_t)raw[6] << 8) | ((uint16_t)raw[7]));
|
||||
resultExtended->frameType = raw[9] & 0x03;
|
||||
resultExtended->frameSubType = (raw[9] & 0x3C) >> 2;
|
||||
resultExtended->toDistributionSystem = (raw[9] & 0x40) != 0;
|
||||
resultExtended->fromDistributionSystem = (raw[9] & 0x80) != 0;
|
||||
memcpy(resultExtended->mac0, &raw[10], RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN);
|
||||
memcpy(resultExtended->mac, &raw[16], RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN);
|
||||
memcpy(resultExtended->mac2, &raw[22], RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN);
|
||||
resultExtended->timestamp = (((uint64_t)raw[28] << 56) | ((uint64_t)raw[29] << 48)) |
|
||||
(((uint64_t)raw[30] << 40) | ((uint64_t)raw[31] << 32)) |
|
||||
(((uint64_t)raw[32] << 24) | ((uint64_t)raw[33] << 16)) |
|
||||
(((uint64_t)raw[34] << 8) | (uint64_t)raw[35]);
|
||||
resultExtended->periodBeacon = (((uint16_t)raw[36] << 8) | ((uint16_t)raw[37])) * 1024UL;
|
||||
resultExtended->seqCtrl = (((uint16_t)raw[38] << 8) | ((uint16_t)raw[39]));
|
||||
memcpy(resultExtended->ssid, &raw[40], RADIOLIB_LR11X0_WIFI_RESULT_SSID_LEN);
|
||||
resultExtended->currentChannel = raw[72];
|
||||
memcpy(resultExtended->countryCode, &raw[73], 2);
|
||||
resultExtended->countryCode[2] = '\0';
|
||||
resultExtended->ioReg = raw[75];
|
||||
resultExtended->fcsCheckOk = (raw[76] != 0);
|
||||
resultExtended->phiOffset = (((uint16_t)raw[77] << 8) | ((uint16_t)raw[78]));
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
LR11x0WifiResultFull_t* resultFull = (LR11x0WifiResultFull_t*)result;
|
||||
resultFull->frameType = raw[3] & 0x03;
|
||||
resultFull->frameSubType = (raw[3] & 0x3C) >> 2;
|
||||
resultFull->toDistributionSystem = (raw[3] & 0x40) != 0;
|
||||
resultFull->fromDistributionSystem = (raw[3] & 0x80) != 0;
|
||||
memcpy(resultFull->mac, &raw[4], RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN);
|
||||
resultFull->phiOffset = (((uint16_t)raw[10] << 8) | ((uint16_t)raw[11]));
|
||||
resultFull->timestamp = (((uint64_t)raw[12] << 56) | ((uint64_t)raw[13] << 48)) |
|
||||
(((uint64_t)raw[14] << 40) | ((uint64_t)raw[15] << 32)) |
|
||||
(((uint64_t)raw[16] << 24) | ((uint64_t)raw[17] << 16)) |
|
||||
(((uint64_t)raw[18] << 8) | (uint64_t)raw[19]);
|
||||
resultFull->periodBeacon = (((uint16_t)raw[20] << 8) | ((uint16_t)raw[21])) * 1024UL;
|
||||
}
|
||||
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t LR11x0::wifiScan(uint8_t wifiType, uint8_t* count, uint8_t mode, uint16_t chanMask, uint8_t numScans, uint16_t timeout) {
|
||||
if(!count) {
|
||||
return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
|
||||
}
|
||||
|
||||
// start scan
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("WiFi scan start");
|
||||
int16_t state = startWifiScan(wifiType, mode, chanMask, numScans, timeout);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// wait for scan finished or timeout
|
||||
RadioLibTime_t softTimeout = 30UL * 1000UL;
|
||||
RadioLibTime_t start = this->mod->hal->millis();
|
||||
while(!this->mod->hal->digitalRead(this->mod->getIrq())) {
|
||||
this->mod->hal->yield();
|
||||
if(this->mod->hal->millis() - start > softTimeout) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout waiting for IRQ");
|
||||
this->standby();
|
||||
return(RADIOLIB_ERR_RX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("WiFi scan done in %d ms", this->mod->hal->millis() - start);
|
||||
|
||||
// read number of results
|
||||
return(getWifiScanResultsCount(count));
|
||||
}
|
||||
|
||||
int16_t LR11x0::modSetup(float tcxoVoltage, uint8_t modem) {
|
||||
this->mod->init();
|
||||
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
|
||||
|
@ -2282,7 +2444,9 @@ int16_t LR11x0::wifiScan(uint8_t type, uint16_t mask, uint8_t acqMode, uint8_t n
|
|||
(uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
|
||||
abortOnTimeout
|
||||
};
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_SCAN, true, buff, sizeof(buff)));
|
||||
|
||||
// call the SPI write stream directly to skip waiting for BUSY - it will be set to high once the scan starts
|
||||
return(this->mod->SPIwriteStream(RADIOLIB_LR11X0_CMD_WIFI_SCAN, buff, sizeof(buff), false, false));
|
||||
}
|
||||
|
||||
int16_t LR11x0::wifiScanTimeLimit(uint8_t type, uint16_t mask, uint8_t acqMode, uint8_t nbMaxRes, uint16_t timePerChan, uint16_t timeout) {
|
||||
|
@ -2315,19 +2479,9 @@ int16_t LR11x0::wifiCountryCodeTimeLimit(uint16_t mask, uint8_t nbMaxRes, uint16
|
|||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_COUNTRY_CODE_TIME_LIMIT, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::wifiGetNbResults(uint8_t* nbResults) {
|
||||
uint8_t buff[1] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_GET_NB_RESULTS, false, buff, sizeof(buff));
|
||||
|
||||
// pass the replies
|
||||
if(nbResults) { *nbResults = buff[0]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::wifiReadResults(uint8_t index, uint8_t nbResults, uint8_t format, uint8_t* results) {
|
||||
uint8_t reqBuff[3] = { index, nbResults, format };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_READ_RESULTS, false, results, nbResults, reqBuff, sizeof(reqBuff)));
|
||||
uint8_t buff[3] = { index, nbResults, format };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_READ_RESULTS, false, results, RADIOLIB_LR11X0_WIFI_RESULT_MAX_LEN, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::wifiResetCumulTimings(void) {
|
||||
|
|
|
@ -472,10 +472,15 @@
|
|||
#define RADIOLIB_LR11X0_WIFI_ACQ_MODE_SSID_BEACON (0x05UL << 0) // 7 0 SSID beacon
|
||||
#define RADIOLIB_LR11X0_WIFI_ABORT_ON_TIMEOUT_ENABLED (0x01UL << 0) // 7 0 abort scanning on preamble timeout: enabled
|
||||
#define RADIOLIB_LR11X0_WIFI_ABORT_ON_TIMEOUT_DISABLED (0x00UL << 0) // 7 0 disabled
|
||||
#define RADIOLIB_LR11X0_WIFI_MAX_NUM_RESULTS (32) // 7 0 maximum possible number of Wi-Fi scan results
|
||||
#define RADIOLIB_LR11X0_WIFI_ALL_CHANNELS (0x3FFFUL) // 16 0 scan all channels
|
||||
|
||||
// RADIOLIB_LR11X0_CMD_WIFI_READ_RESULTS
|
||||
#define RADIOLIB_LR11X0_WIFI_RESULT_TYPE_COMPLETE (0x01UL << 0) // 7 0 Wi-Fi scan result type: complete
|
||||
#define RADIOLIB_LR11X0_WIFI_RESULT_TYPE_BASIC (0x04UL << 0) // 7 0 basic
|
||||
#define RADIOLIB_LR11X0_WIFI_RESULT_MAX_LEN (79) // 7 0 maximum possible Wi-Fi scan size
|
||||
#define RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN (6) // 7 0 MAC address length in bytes
|
||||
#define RADIOLIB_LR11X0_WIFI_RESULT_SSID_LEN (32) // 7 0 SSID length in bytes
|
||||
|
||||
// RADIOLIB_LR11X0_CMD_GNSS_SET_CONSTELLATION_TO_USE
|
||||
#define RADIOLIB_LR11X0_GNSS_CONSTELLATION_GPS (0x01UL << 0) // 7 0 GNSS constellation to use: GPS
|
||||
|
@ -536,10 +541,108 @@
|
|||
// RADIOLIB_LR11X0_REG_LORA_HIGH_POWER_FIX
|
||||
#define RADIOLIB_LR11X0_LORA_HIGH_POWER_FIX (0x00UL << 30) // 30 30 fix for errata
|
||||
|
||||
/*!
|
||||
\struct LR11x0WifiResult_t
|
||||
\brief Structure to save result of passive WiFi scan.
|
||||
This result only saves the basic information.
|
||||
*/
|
||||
struct LR11x0WifiResult_t {
|
||||
/*! \brief WiFi (802.11) signal type, 'b', 'n' or 'g' */
|
||||
char type;
|
||||
|
||||
/*! \brief Data rate ID holding information about modulation and coding rate. See LR11x0 user manual for details. */
|
||||
uint8_t dataRateId;
|
||||
|
||||
/*! \brief Channel frequency in MHz */
|
||||
uint16_t channelFreq;
|
||||
|
||||
/*! \brief MAC address origin: from gateway (1), phone (2) or undetermined (3) */
|
||||
uint8_t origin;
|
||||
|
||||
/*! \brief Whether this signal was sent by an access point (true) or end device (false) */
|
||||
bool ap;
|
||||
|
||||
/*! \brief RSSI in dBm */
|
||||
float rssi;
|
||||
|
||||
/*! \brief MAC address */
|
||||
uint8_t mac[RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN];
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct LR11x0WifiResultFull_t
|
||||
\brief Structure to save result of passive WiFi scan.
|
||||
This result saves additional information alongside that in LR11x0WifiResult_t.
|
||||
*/
|
||||
struct LR11x0WifiResultFull_t: public LR11x0WifiResult_t {
|
||||
/*! \brief Frame type. See LR11x0 user manual for details. */
|
||||
uint8_t frameType;
|
||||
|
||||
/*! \brief Frame sub type. See LR11x0 user manual for details. */
|
||||
uint8_t frameSubType;
|
||||
|
||||
/*! \brief Frame sent from client station to distribution system. */
|
||||
bool toDistributionSystem;
|
||||
|
||||
/*! \brief Frame sent from distribution system to client station. */
|
||||
bool fromDistributionSystem;
|
||||
|
||||
/*! \brief See LR11x0 user manual for details. */
|
||||
uint16_t phiOffset;
|
||||
|
||||
/*! \brief Number of microseconds the AP has been active. */
|
||||
uint64_t timestamp;
|
||||
|
||||
/*! \brief Beacon period in microseconds. */
|
||||
uint32_t periodBeacon;
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct LR11x0WifiResultExtended_t
|
||||
\brief Structure to save result of passive WiFi scan.
|
||||
This result saves additional information alongside that in LR11x0WifiResultFull_t.
|
||||
Only scans performed with RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON acquisition mode
|
||||
can yield this result!
|
||||
*/
|
||||
struct LR11x0WifiResultExtended_t: public LR11x0WifiResultFull_t {
|
||||
/*! \brief Data rate. See LR11x0 user manual for details. */
|
||||
uint8_t rate;
|
||||
|
||||
/*! \brief Refer to IEEE Std 802.11, 2016, Part 11: Wireless LAN MAC and PHY Spec. */
|
||||
uint16_t service;
|
||||
|
||||
/*! \brief Refer to IEEE Std 802.11, 2016, Part 11: Wireless LAN MAC and PHY Spec. */
|
||||
uint16_t length;
|
||||
|
||||
/*! \brief MAC address 0 */
|
||||
uint8_t mac0[RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN];
|
||||
|
||||
/*! \brief MAC address 2 */
|
||||
uint8_t mac2[RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN];
|
||||
|
||||
/*! \brief Refer to IEEE Std 802.11, 2016, Part 11: Wireless LAN MAC and PHY Spec. */
|
||||
uint16_t seqCtrl;
|
||||
|
||||
/*! \brief SSID */
|
||||
uint8_t ssid[RADIOLIB_LR11X0_WIFI_RESULT_SSID_LEN];
|
||||
|
||||
/*! \brief WiFi channel number */
|
||||
uint8_t currentChannel;
|
||||
|
||||
/*! \brief Two-letter country code (null-terminated string). */
|
||||
char countryCode[3];
|
||||
|
||||
/*! \brief Refer to IEEE Std 802.11, 2016, Part 11: Wireless LAN MAC and PHY Spec. */
|
||||
uint8_t ioReg;
|
||||
|
||||
/*! \brief True if frame check sequences is valid, false otherwise. */
|
||||
bool fcsCheckOk;
|
||||
};
|
||||
|
||||
/*!
|
||||
\class LR11x0
|
||||
\brief
|
||||
\brief Base class for %LR11x0 series. All derived classes for %LR11x0 (e.g. LR1110 or LR1120) inherit from this base class.
|
||||
This class should not be instantiated directly from user code, only from its derived classes.
|
||||
*/
|
||||
class LR11x0: public PhysicalLayer {
|
||||
public:
|
||||
|
@ -1053,6 +1156,69 @@ class LR11x0: public PhysicalLayer {
|
|||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setLrFhssConfig(uint8_t bw, uint8_t cr, uint8_t hdrCount = 3, uint16_t hopSeed = 0x13A);
|
||||
|
||||
/*!
|
||||
\brief Start passive WiFi scan. BUSY pin will be de-activated when the scan is finished.
|
||||
\param wifiType Type of WiFi (802.11) signals to scan, 'b', 'n', 'g' or '*' for all signals.
|
||||
\param mode Scan acquisition mode, one of RADIOLIB_LR11X0_WIFI_ACQ_MODE_*.
|
||||
The type of results available after the scan depends on this mode.
|
||||
Defaults to RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON, which provides the most information.
|
||||
\param chanMask Bit mask of WiFi channels to scan, defaults to all channels.
|
||||
More channels leads to longer overall scan duration.
|
||||
\param numScans Number of scans to perform per each enabled channel. Defaults to 16 scans.
|
||||
More scans leads to longer overall scan duration.
|
||||
\param timeout Timeout of each scan in milliseconds. Defaults to 100 ms
|
||||
Longer timeout leads to longer overall scan duration.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startWifiScan(char wifiType, uint8_t mode = RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON, uint16_t chanMask = RADIOLIB_LR11X0_WIFI_ALL_CHANNELS, uint8_t numScans = 16, uint16_t timeout = 100);
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a WiFi scan is completed.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setWiFiScanAction(void (*func)(void));
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a WiFi scan is completed.
|
||||
*/
|
||||
void clearWiFiScanAction();
|
||||
|
||||
/*!
|
||||
\brief Get number of WiFi scan results after the scan is finished.
|
||||
\param count Pointer to a variable that will hold the number of scan results.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t getWifiScanResultsCount(uint8_t* count);
|
||||
|
||||
/*!
|
||||
\brief Retrieve passive WiFi scan result.
|
||||
\param result Pointer to structure to hold the result data.
|
||||
\param index Result index, starting from 0. The number of scan results can be retrieved by calling getWifiScanResultsCount.
|
||||
\param brief Whether to only retrieve the results in brief format. If set to false, only information in LR11x0WifiResult_t
|
||||
will be retrieved. If set to true, information in LR11x0WifiResultFull_t will be retrieved. In addition, if WiFi scan mode
|
||||
was set to RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON, all information in LR11x0WifiResultExtended_t will be retrieved.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t getWifiScanResult(LR11x0WifiResult_t* result, uint8_t index, bool brief = false);
|
||||
|
||||
/*!
|
||||
\brief Blocking WiFi scan method. Performs a full passive WiFi scan.
|
||||
This method may block for several seconds!
|
||||
\param wifiType Type of WiFi (802.11) signals to scan, 'b', 'n', 'g' or '*' for all signals.
|
||||
\param count Pointer to a variable that will hold the number of scan results.
|
||||
\param mode Scan acquisition mode, one of RADIOLIB_LR11X0_WIFI_ACQ_MODE_*.
|
||||
The type of results available after the scan depends on this mode.
|
||||
Defaults to RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON, which provides the most information.
|
||||
\param chanMask Bit mask of WiFi channels to scan, defaults to all channels.
|
||||
More channels leads to longer overall scan duration.
|
||||
\param numScans Number of scans to perform per each enabled channel. Defaults to 16 scans.
|
||||
More scans leads to longer overall scan duration.
|
||||
\param timeout Timeout of each scan in milliseconds. Defaults to 100 ms
|
||||
Longer timeout leads to longer overall scan duration.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t wifiScan(uint8_t wifiType, uint8_t* count, uint8_t mode = RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON, uint16_t chanMask = RADIOLIB_LR11X0_WIFI_ALL_CHANNELS, uint8_t numScans = 16, uint16_t timeout = 100);
|
||||
|
||||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||
protected:
|
||||
|
@ -1229,6 +1395,8 @@ class LR11x0: public PhysicalLayer {
|
|||
|
||||
float dataRateMeasured = 0;
|
||||
|
||||
uint8_t wifiScanMode = 0;
|
||||
|
||||
int16_t modSetup(float tcxoVoltage, uint8_t modem);
|
||||
static int16_t SPIparseStatus(uint8_t in);
|
||||
static int16_t SPIcheckStatus(Module* mod);
|
||||
|
|
Loading…
Add table
Reference in a new issue