Hallo iedereen
Vandaag willen we u kennis laten maken met een project waar we via een klantverzoek kennis mee hebben genomen. Wij tonen u een MAC-adresdetector met onze ESP32 Dev Board C.
Niet meer hardware dan dit bord is vereist. De Mac-Detector scant achtereenvolgens naar de adressen die in de code zijn opgeslagen en uitvoert ze in de seriële monitor zodra een apparaat nadert. Hiervoor gebruiken we de Promiscuous-modus, die veel gemakkelijker met de ESP32 kan worden gebruikt dan bij de voorganger ESP8266. De aanwezigheidsdetectie werkt vrij betrouwbaar, maar het is belangrijk op te merken dat de scanner alleen iets uitvoert wanneer het WiFi-apparaat "wakker" is en communiceert. Het kan dus enige tijd duren voordat het adres in de seriële monitor wordt weergegeven. Afhankelijk van het gebruikte apparaat en de configuratie ervan besparen ze vaak energie en schakelen ze ongebruikte componenten uit. Verschillende iPhones hebben bijzonder graag gecommuniceerd.
Voer gewoon de gewenste adressen in onder :adress lijst, klaar.
Hier is de code:
#include <Wifi.H> #include <Draad.H> #include "esp_wifi.h" Tekenreeks maclist[64][3]; Int Listcount = 0; Tekenreeks BekendeMac[10][2] = { adressenlijst {"Chef1","8C1ABF8A6A36"}, {"Chef2","E894BA82BC83"}, {"NAAM","MACADDRESS"}, {"NAAM","MACADDRESS"}, {"NAAM","MACADDRESS"}, {"NAAM","MACADDRESS"}, {"NAAM","MACADDRESS"}, {"NAAM","MACADDRESS"}, {"NAAM","MACADDRESS"} }; Tekenreeks standaardTTL = "60"; Maximale tijd (Apx seconden) verstreken voordat het apparaat offline wordt samengevoegd Const wifi_promiscuous_filter_t filt filt={ .filter_mask=WIFI_PROMIS_FILTER_MASK_MGMT|WIFI_PROMIS_FILTER_MASK_DATA }; Typedef Struct { uint8_t Mac[6]; } __attribute__((Verpakt)) MacAddr MacAddr; Typedef Struct { int16_t fctl; int16_t Duur; MacAddr MacAddr Er; MacAddr MacAddr Zat; MacAddr MacAddr Bssid; int16_t seqctl seqctl; Unsigned Char Nettolading[]; } __attribute__((Verpakt)) WifiMgmtHdr WifiMgmtHdr; #define maxCh 13 max Kanaal -> VS = 11, EU = 13, Japan = 14 Int curChannel curChannel = 1; Void Sniffer(Void* Buf, wifi_promiscuous_pkt_type_t Type) { Dit is waar pakketten eindigen nadat ze gesnoven wifi_promiscuous_pkt_t *P = (wifi_promiscuous_pkt_t*)Buf; Int Len = P->rx_ctrl.sig_len; WifiMgmtHdr WifiMgmtHdr *Wh = (WifiMgmtHdr WifiMgmtHdr*)P->Nettolading; Len -= Grootte van(WifiMgmtHdr WifiMgmtHdr); Als (Len < 0){ Seriële.println("Receuved 0"); Terug; } Tekenreeks Pakket; Tekenreeks Mac; Int fctl = ntohs(Wh->fctl); Voor(Int I.=8;I.<=8+6+1;I.++){ Dit leest de eerste paar bytes van het pakket. Hier kun je het hele pakket lezen als je de "8+6+1" vervangt door "p->rx_ctrl.sig_len" Pakket += Tekenreeks(P->Nettolading[I.],Hex); } Voor(Int I.=4;I.<=15;I.++){ Dit verwijdert de 'knabbelen' bits uit de stat en het einde van de gegevens die we willen. Dus we krijgen alleen het mac adres. Mac += Pakket[I.]; } Mac.Touppercase(); Int Toegevoegd = 0; Voor(Int I.=0;I.<=63;I.++){ controleert of het MAC-adres eerder is toegevoegd Als(Mac == maclist[I.][0]){ maclist[I.][1] = standaardTTL; Als(maclist[I.][2] == "OFFLINE"){ maclist[I.][2] = "0"; } Toegevoegd = 1; } } Als(Toegevoegd == 0){ Als het nieuw is. voeg het toe aan de array. maclist[Listcount][0] = Mac; maclist[Listcount][1] = standaardTTL; Serial.println(mac); Listcount ++; Als(Listcount >= 64){ Seriële.println("Te veel adressen"); Listcount = 0; } } } Void Setup() { Seriële.Beginnen(115200); wifi_init_config_t Cfg = WIFI_INIT_CONFIG_DEFAULT(); esp_wifi_init(&Cfg); esp_wifi_set_storage(WIFI_STORAGE_RAM); esp_wifi_set_mode(WIFI_MODE_NULL); esp_wifi_start(); esp_wifi_set_promiscuous(Waar); esp_wifi_set_promiscuous_filter(&filt filt); esp_wifi_set_promiscuous_rx_cb(&Sniffer); esp_wifi_set_channel(curChannel curChannel, WIFI_SECOND_CHAN_NONE); Seriële.println("Begin!"); } Void Purge(){ Dit beheert de TTL Voor(Int I.=0;I.<=63;I.++){ Als(!(maclist[I.][0] == "")){ Int Ttl = (maclist[I][1].toInt()); Ttl --; Als(Ttl <= 0){ Serial.println("OFFLINE: " + maclist[i][0]); maclist[I][2] = "OFFLINE"; maclist[I][1] = standaardTTL; }Anders{ maclist[I][1] = Tekenreeks(Ttl); } } } } Void updatetijd(){ Hiermee wordt de tijd bijgewerkt waarop het apparaat online is geweest voor Voor(Int I=0;I<=63;I++){ Als(!(maclist[I][0] == "")){ Als(maclist[I][2] == "")maclist[I][2] = "0"; Als(!(maclist[I][2] == "OFFLINE")){ Int timehere = (maclist[I][2].toInt()); timehere ++; maclist[I][2] = Tekenreeks(timehere); } Serial.println(maclist[i][0] + " : + maclist[i][2]); } } } Void showpeople(){ Dit controleert of de MAC in de gereckoneerde lijst staat en geeft deze vervolgens weer op de OLED en/of drukt deze af op serieel. Tekenreeks forScreen = ""; Voor(Int I=0;I<=63;I++){ Tekenreeks tmp1 tmp1 = maclist[I][0]; Als(!(tmp1 tmp1 == "")){ Voor(Int J=0;J<=9;J++){ Tekenreeks tmp2 = BekendeMac[J][1]; Als(tmp1 tmp1 == tmp2){ forScreen += (BekendeMac[J][0] + " : " + maclist[I][2] + "\n"); Seriële.Afdrukken(BekendeMac[J][0] + " : " + tmp1 tmp1 + " : " + maclist[I][2] + "\n -- \n"); } } } } } Void Lus() { Serial.println("Gewijzigd kanaal:" + Tekenreeks(curChannel)); Als(curChannel curChannel > maxCh){ curChannel curChannel = 1; } esp_wifi_set_channel(curChannel curChannel, WIFI_SECOND_CHAN_NONE); Vertraging(1000); updatetijd(); Purge(); showpeople(); curChannel curChannel++; }
In einem folgendem Beitrag werden wir versuchen die Anwesenheitserkennung wantels BLE umzusetzten. Bis zum nächsten mal :)
5 Reacties
Bas
Hans, THX! this did the trick
String packet;
int fctl = ntohs(wh→fctl); for (int i = 8; i <= 8 + 6 + 1; i++) { String packet2 = String(p→payload[i], HEX); if (packet2.length() == 1) { packet3 = “0” + packet2; packet += packet3; } else { packet += packet2; } }String mac;
String packet3;
Hans
Bei diesem code werden nicht alle Mac-Adressen richtig erkannt.
Beispiel:
Korrekte mac-adresse vom Gerät: D4:AE:05:0D:D7:28
Der Code erkennt: D4AE5DD728
Die 0 fehlen.
Erklärung:
Hexadezimal: D4:AE:05:0D:D7:28
Dezimal: 212:174:5:13:215:1C
- Dezimal 05 ist Hexa 5. Das 0 wird gestrichen.
- Dezimal 13 ist Hexa D. Das 0 wird gestrichen.
Der fehlerhafte code-abschnitt habe ich für mich wie folgt gelöst:
String packet; String packet3; String mac; int fctl = ntohs(wh→fctl); for (int i = 8; i <= 8 + 6 + 1; i++) { String packet2 = String(p→payload[i], HEX); if (packet2.length() == 1) { packet3 = “0” + packet2; packet += packet3; } else { packet += packet2; } }Markus Hopfner
Guten Tag (nochmals),
wollte Sie nur nochmals darauf Aufmerksam machen das der Code nicht mit MAC-Adressen mit zwei Nullen in folge funktioniert.
mfg
Markus
Markus Hopfner
Guten Tag,
zuerst einmal vielen dank für den Code.
Mir ist aufgefallen das er nicht funktioniert wenn die MAC eine Doppelnull hat, da wird eine verschluckt. können Sie mir sagen wieso?
Mfg Markus
Willy
Das ist ein interessantes Projekt. Kann ich auch die MAC-Adressen mit einem ESP8266 scannen?
Genauer gesagt will ich den Amazon Dash-Button im WLAN erkennen. Der ESP8266 ist der Hotspot mit dem sich der DASH-Button verbindet. Aber ich weiss nicht wie ich die MAC-Adresse erkennen kann das der Dash-Button sich verbunden hat. Die MAC-Adresse des Dash-Button kenne ich.