[LR11x0] Added support for WiFi scanning

pull/1089/head
jgromes 2024-05-05 11:35:35 +02:00
rodzic bb7fffe95d
commit 86cdefe8a2
6 zmienionych plików z 616 dodań i 14 usunięć

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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);
}
}
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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)
/*!
\}
*/

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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);