问题
项目需求:侦查到wifi信号,匹配IEEE官方批准的mac地址数据库,获得准确的company_id。
问题:瑞昱提供的官方底层未开放专门扫描的mac地址的api。
解决思路:修改底层文件。其实比较简单,他底层写了这个接口,只是不知道啥原因没有开放出来,往wifi类里面把这个接口开放出来就能用了。
步骤
安装完Realtek Ameba Boards开发板后,如果由于网速问题导致板卡下载失败,可以通过离线下载的方式下载开发板,具体方式很多教程都有。下载好后,打开文件→示例→wifi→ScanNetWorks。
原本的ScanNetWorks只会打印 SSID(wifi名称)、RSSI(信号强度)、encryptionTypeEx(加密类型详情) 和 encryptionType(加密类型)。
源码:
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));
}
}
添加mac接口:
需要用到四个文件:
WiFi.cpp 和 WiFi.h 路径:C:\Users\用户名\AppData\Local\Arduino15\packages\realtek\hardware\AmebaD\3.1.7\libraries\WiFi\src\
wifi_drv.cpp 和 wifi_drv.h 路径:C:\Users\PS97\AppData\Local\Arduino15\packages\realtek\hardware\AmebaD\3.1.7\cores\ambd\
一般库文件都是只读模式,所以只能去对应路径以文本形式修改,或者解除只读模式(不建议)。
WiFi.h
在 class WiFiClass 的 public 里面添加
uint8_t BSSID(uint8_t networkItem, uint8_t* mac); // BSSID就是底层未开放出来的MAC
uint8_t CHANNEL(uint8_t networkItem); // 通道也是未开放出来
class WiFiClass {
public:
uint8_t BSSID(uint8_t networkItem, uint8_t* mac);
uint8_t CHANNEL(uint8_t networkItem);
}
WiFi.cpp
// 随便找个位置添加以下函数
uint8_t WiFiClass::BSSID(uint8_t networkItem, uint8_t* mac) {
WiFiDrv::getBSSIDNetworks(networkItem, mac);
// printf(" record_mac: %02X : %02X : %02X : %02X : %02X : %02X\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return 1;
}
uint8_t WiFiClass::CHANNEL(uint8_t networkItem){
return WiFiDrv::getCHANNELworks(networkItem);
}
wifi_drv.h
在 class WiFiDrv 的 private里面添加
static uint8_t _networkChannel[WL_NETWORKS_LIST_MAXNUM];
static rtw_mac_t _networkBssid[WL_NETWORKS_LIST_MAXNUM];
在 class WiFiDrv 的 public 里面添加
static uint8_t* getBSSIDNetworks(uint8_t networkItem, uint8_t* data);
static uint8_t getCHANNELworks(uint8_t networkItem);
wifi_drv.cpp
1、在文件头部申明的时候添加红色部分
// Array of data to cache the information related to the networks discovered
uint8_t WiFiDrv::_networkCount = 0;
char WiFiDrv::_networkSsid[][WL_SSID_MAX_LENGTH] = {{"1"}, {"2"}, {"3"}, {"4"}, {"5"}};
int32_t WiFiDrv::_networkRssi[WL_NETWORKS_LIST_MAXNUM] = {0};
uint32_t WiFiDrv::_networkEncr[WL_NETWORKS_LIST_MAXNUM] = {0};
rtw_mac_t WiFiDrv::_networkBssid[WL_NETWORKS_LIST_MAXNUM]= {0}; //
uint8_t WiFiDrv::_networkChannel[WL_NETWORKS_LIST_MAXNUM] = {0};
2、修改rtw_result_t WiFiDrv::wifidrv_scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result ):添加
_networkBssid[_networkCount] = record->BSSID;
_networkChannel[_networkCount] = record->channel;
rtw_result_t WiFiDrv::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;
_networkBssid[_networkCount] = record->BSSID;
_networkChannel[_networkCount] = record->channel;
// printf(" record_mac: %02X : %02X : %02X : %02X : %02X : %02X\r\n", record->BSSID.octet[0], record->BSSID.octet[1], record->BSSID.octet[2], record->BSSID.octet[3], record->BSSID.octet[4], record->BSSID.octet[5]);
_networkCount++;
}
}
return RTW_SUCCESS;
}
3、在空白位置添加
uint8_t* WiFiDrv::getBSSIDNetworks(uint8_t networkItem, uint8_t* data) {
if (networkItem >= WL_NETWORKS_LIST_MAXNUM) {
return NULL;
}
data[0] = _networkBssid[networkItem].octet[0];
data[1] = _networkBssid[networkItem].octet[1];
data[2] = _networkBssid[networkItem].octet[2];
data[3] = _networkBssid[networkItem].octet[3];
data[4] = _networkBssid[networkItem].octet[4];
data[5] = _networkBssid[networkItem].octet[5];
// printf(" record_mac: %02X : %02X : %02X : %02X : %02X : %02X\r\n", _networkBssid[networkItem].octet[0], _networkBssid[networkItem].octet[1], _networkBssid[networkItem].octet[2], _networkBssid[networkItem].octet[3], _networkBssid[networkItem].octet[4], _networkBssid[networkItem].octet[5]);
return data;
}
uint8_t WiFiDrv::getCHANNELworks(uint8_t networkItem){
if (networkItem >= WL_NETWORKS_LIST_MAXNUM) {
//return NULL;
return 0;
}
return _networkChannel[networkItem];
}
ScanNetworks.ino
修改完成后保存好,然后回到ScanNetworks.ino中,
WiFi.BSSID(thisNet,mac); // 调用api获取扫描到的wifi信号的mac地址(注意:如果是手机热点之类的信号,可能获取到的是虚地址)
修改后的代码:
void listNetworks() {
// scan for nearby networks:
uint8_t mac[6]; // 添加
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++) {
WiFi.BSSID(thisNet,mac); // 添加
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));
Serial.print(WiFi.CHANNEL(thisNet)); // 添加 打印通道
printf("\tMAC: %02X : %02X : %02X : %02X : %02X : %02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); // 添加 打印mac地址
}
}