Skip to content

Instantly share code, notes, and snippets.

@EstebanFuentealba
Created January 23, 2024 23:30
Show Gist options
  • Save EstebanFuentealba/3da9ccecefa7e1b44d84e7cfaad2f35f to your computer and use it in GitHub Desktop.
Save EstebanFuentealba/3da9ccecefa7e1b44d84e7cfaad2f35f to your computer and use it in GitHub Desktop.
/*
This example prints the Wifi shield's MAC address, and
scans for available Wifi networks using the Wifi shield.
Every ten seconds, it scans again. It doesn't actually
connect to any network, so no encryption scheme is specified.
created 13 July 2010
by dlf (Metodo2 srl)
modified 21 Junn 2012
by Tom Igoe and Jaymes Dec
Example guide:
https://www.amebaiot.com/en/amebad-arduino-scan-wifi/
*/
#include <WiFi.h>
#include <lwip_netconf.h>
#include <wifi_conf.h>
#include <wifi_constants.h>
#include <wifi_structures.h>
#include <wl_definitions.h>
#include <wl_types.h>
// static int16_t w, h, text_size, banner_height, graph24_baseline, graph50_baseline, graph_baseline, graph_height, channel24_width, channel50_width, channel_width;
// Channel legend mapping
static uint16_t channel_legend[] = {
1, 2, 3, 4, 5, 6, 7, // 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, // 8, 9, 10, 11, 12, 13, 14,
32, 0, 0, 0, 40, 0, 0, // 32, 34, 36, 38, 40, 42, 44,
0, 48, 0, 0, 0, 56, 0, // 46, 48, 50, 52, 54, 56, 58,
0, 0, 64, 0, 0, 0, // 60, 62, 64, 68,N/A, 96,
100, 0, 0, 0, 108, 0, 0, //100,102,104,106,108,110,112,
0, 116, 0, 0, 0, 124, 0, //114,116,118,120,122,124,126,
0, 0, 132, 0, 0, 0, 140, //128,N/A,132,134,136,138,140,
0, 0, 0, 149, 0, 0, 0, //142,144,N/A,149,151,153,155,
157, 0, 0, 0, 165, 0, 0, //157,159,161,163,165,167,169,
0, 173}; //171,173
#define SCAN_INTERVAL 3000
// RSSI RANGE
#define RSSI_CEILING -40
#define RSSI_FLOOR -100
static uint16_t channelIdx(int channel)
{
if (channel <= 14) // 2.4 GHz, channel 1-14
{
return channel - 1;
}
if (channel <= 64) // 5 GHz, channel 32 - 64
{
return 14 + ((channel - 32) / 2);
}
if (channel == 68)
{
return 31;
}
if (channel == 96)
{
return 33;
}
if (channel <= 144) // channel 98 - 144
{
return 34 + ((channel - 100) / 2);
}
// channel 149 - 177
return 58 + ((channel - 149) / 2);
}
static uint8_t _networkCount;
static char _networkSsid[WL_NETWORKS_LIST_MAXNUM][WL_SSID_MAX_LENGTH];
static int32_t _networkRssi[WL_NETWORKS_LIST_MAXNUM];
static uint32_t _networkEncr[WL_NETWORKS_LIST_MAXNUM];
static uint8_t _networkChannel[WL_NETWORKS_LIST_MAXNUM];
static uint8_t _networkBand[WL_NETWORKS_LIST_MAXNUM];
static char _networkMac[WL_NETWORKS_LIST_MAXNUM][18];
static rtw_result_t wifidrv_scan_result_handler(rtw_scan_handler_result_t *malloced_scan_result)
{
rtw_scan_result_t *record;
if (malloced_scan_result->scan_complete != RTW_TRUE)
{
record = &malloced_scan_result->ap_details;
record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */
if (_networkCount < WL_NETWORKS_LIST_MAXNUM)
{
strcpy(_networkSsid[_networkCount], (char *)record->SSID.val);
_networkRssi[_networkCount] = record->signal_strength;
_networkEncr[_networkCount] = record->security;
_networkChannel[_networkCount] = record->channel;
_networkBand[_networkCount] = record->band;
sprintf(_networkMac[_networkCount], "%02X:%02X:%02X:%02X:%02X:%02X",
record->BSSID.octet[0], record->BSSID.octet[1], record->BSSID.octet[2],
record->BSSID.octet[3], record->BSSID.octet[4], record->BSSID.octet[5]);
Serial.print(_networkSsid[_networkCount]);
Serial.print("\tSignal: ");
Serial.print(_networkRssi[_networkCount]);
Serial.print(" dBm");
Serial.print("\tEncryptionRaw: ");
printEncryptionTypeEx(_networkEncr[_networkCount]);
Serial.print("\tBand: ");
// Serial.print(_networkBand[_networkCount]);
if(_networkChannel[_networkCount] < 14) {
Serial.print("2.4 Ghz");
} else {
Serial.print("5 Ghz");
}
Serial.print("\tChannel: ");
Serial.print(_networkChannel[_networkCount]);
Serial.print("\tMac: ");
Serial.print(_networkMac[_networkCount]);
Serial.println("");
_networkCount++;
}
}
return RTW_SUCCESS;
}
static int8_t scanNetworks()
{
uint8_t attempts = 10;
_networkCount = 0;
if (wifi_scan_networks(wifidrv_scan_result_handler, NULL) != RTW_SUCCESS)
{
return WL_FAILURE;
}
do
{
delay(SCAN_INTERVAL);
} while ((_networkCount == 0) && (--attempts > 0));
return _networkCount;
}
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while (true);
}
// Print WiFi MAC address:
printMacAddress();
// Serial.println("Scanning available networks...");
// listNetworks();
// scanNetworks();
}
void loop() {
uint8_t ap_count_list[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int32_t peak_list[] = {RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR};
// int16_t peak_id_list[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
int32_t channel;
uint16_t idx;
int32_t rssi;
String ssid;
// int16_t offset;
// scan for existing networks:
Serial.println("Scanning available networks...");
int n = scanNetworks();
if (n == 0)
{
Serial.println("No networks found");
}
else
{
for (int i = 0; i < n; i++)
{
channel = _networkChannel[i];
idx = channelIdx(channel);
rssi = _networkRssi[i];
// channel peak stat
if (peak_list[idx] < rssi)
{
peak_list[idx] = rssi;
// peak_id_list[idx] = i;
}
ap_count_list[idx]++;
}
Serial.print(n);
Serial.println(" networks (2.4 GHz)");
for (idx = 0; idx < 14; idx++)
{
channel = channel_legend[idx];
// offset = (idx + 2) * channel24_width;
if (channel > 0)
{
Serial.print(channel);
}
if (ap_count_list[idx] > 0)
{
Serial.println(ap_count_list[idx]);
}
}
Serial.println("");
Serial.println(" networks (5 GHz)");
// draw 5 GHz graph base axle
for (idx = 14; idx < 71; idx++)
{
channel = channel_legend[idx];
// offset = (idx - 14 + 2) * channel50_width;
if (channel > 0)
{
Serial.println(channel);
}
if (ap_count_list[idx] > 0)
{
Serial.print(ap_count_list[idx]);
}
}
}
Serial.println("");
delay(SCAN_INTERVAL);
}
void printMacAddress() {
// the MAC address of your Wifi shield
byte mac[6];
// print your MAC address:
WiFi.macAddress(mac);
Serial.print("MAC: ");
Serial.print(mac[0], HEX);
Serial.print(":");
Serial.print(mac[1], HEX);
Serial.print(":");
Serial.print(mac[2], HEX);
Serial.print(":");
Serial.print(mac[3], HEX);
Serial.print(":");
Serial.print(mac[4], HEX);
Serial.print(":");
Serial.println(mac[5], HEX);
}
// void listNetworks() {
// // scan for nearby networks:
// Serial.println("** Scan Networks **");
// int numSsid = WiFi.scanNetworks();
// if (numSsid == -1) {
// Serial.println("Couldn't get a wifi connection");
// while (true);
// }
// // print the list of networks seen:
// Serial.print("number of available networks:");
// Serial.println(numSsid);
// // print the network number and name for each network found:
// for (int thisNet = 0; thisNet < numSsid; thisNet++) {
// Serial.print(thisNet);
// Serial.print(") ");
// Serial.print(WiFi.SSID(thisNet));
// Serial.print("\tSignal: ");
// Serial.print(WiFi.RSSI(thisNet));
// Serial.print(" dBm");
// Serial.print("\tEncryptionRaw: ");
// printEncryptionTypeEx(WiFi.encryptionTypeEx(thisNet));
// Serial.print("\tEncryption: ");
// printEncryptionType(WiFi.encryptionType(thisNet));
// }
// }
void printEncryptionTypeEx(uint32_t thisType) {
/* Arduino wifi api use encryption type to mapping to security type.
* This function demonstrate how to get more richful information of security type.
*/
switch (thisType) {
case RTW_SECURITY_OPEN:
Serial.print("Open");
break;
case RTW_SECURITY_WEP_PSK:
Serial.print("WEP");
break;
case RTW_SECURITY_WPA_TKIP_PSK:
Serial.print("WPA TKIP");
break;
case RTW_SECURITY_WPA_AES_PSK:
Serial.print("WPA AES");
break;
case RTW_SECURITY_WPA2_AES_PSK:
Serial.print("WPA2 AES");
break;
case RTW_SECURITY_WPA2_TKIP_PSK:
Serial.print("WPA2 TKIP");
break;
case RTW_SECURITY_WPA2_MIXED_PSK:
Serial.print("WPA2 Mixed");
break;
case RTW_SECURITY_WPA_WPA2_MIXED_PSK:
Serial.print("WPA/WPA2 AES");
break;
case RTW_SECURITY_WPA3_AES_PSK:
Serial.print("WPA3 AES");
break;
case RTW_SECURITY_WPA2_WPA3_MIXED:
Serial.print("WPA2/WPA3");
}
}
void printEncryptionType(int thisType) {
// read the encryption type and print out the name:
switch (thisType) {
case ENC_TYPE_WEP:
Serial.println("WEP");
break;
case ENC_TYPE_WPA:
Serial.println("WPA");
break;
case ENC_TYPE_WPA2:
Serial.println("WPA2");
break;
case ENC_TYPE_WPA3:
Serial.println("WPA3");
break;
case ENC_TYPE_NONE:
Serial.println("None");
break;
case ENC_TYPE_AUTO:
Serial.println("Auto");
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment