Ciao a tutti
Oggi vogliamo presentarvi un progetto al quale siamo diventati consapevoli attraverso una richiesta del cliente. Vi mostriamo un rilevatore di indirizzi MAC con il nostro ESP32 Dev Board C.
Non è richiesto più hardware di questa scheda. Il Mac-Detector esegue la scansione consecutivamente per gli indirizzi memorizzati nel codice e li emette nel monitor seriale non appena un dispositivo si avvicina. A questo scopo, utilizziamo la modalità Promiscuous, che può essere utilizzata molto più facilmente con l'ESP32 che con il predecessore ESP8266. Il rilevamento della presenza funziona in modo abbastanza affidabile, ma è importante notare che lo scanner emette qualcosa solo quando il dispositivo WiFi è "sveglio" e comunica. Quindi potrebbe volerci un po' di tempo prima che l'indirizzo appaia nel monitor seriale. A seconda del dispositivo utilizzato e della sua configurazione, spesso risparmiano energia e spengono i componenti inutilizzati. Vari iPhone si sono dimostrati particolarmente desiderosi di comunicare.
Basta inserire gli indirizzi desiderati sotto :adress list, ready.
Ecco il codice:
#include <Wifi.H> #include <Filo.H> #include "esp_wifi.h" Stringa maclist[64][3]; Int listcount = 0; Stringa KnownMac[10][2] = { lista di indirizzi {"Chef1","8C1ABF8A6A36"}, {"Chef2","E894BA82BC83"}, {"NOME","MACADDRESS" (MACADDRESS)}, {"NOME","MACADDRESS" (MACADDRESS)}, {"NOME","MACADDRESS" (MACADDRESS)}, {"NOME","MACADDRESS" (MACADDRESS)}, {"NOME","MACADDRESS" (MACADDRESS)}, {"NOME","MACADDRESS" (MACADDRESS)}, {"NOME","MACADDRESS" (MACADDRESS)} }; Stringa defaultTTL (predefinitoTTL) = "60"; Tempo massimo (secondi Apx) trascorso prima che il dispositivo venga consiroffline Const wifi_promiscuous_filter_t filt={ .filter_mask=WIFI_PROMIS_FILTER_MASK_MGMT|WIFI_PROMIS_FILTER_MASK_DATA }; Typedef Struct { uint8_t Mac[6]; } __attribute__((Pranzo)) MacAddr; Typedef Struct { int16_t fctl; int16_t Durata; MacAddr lì; MacAddr Sab; MacAddr Bssid; int16_t seqctl; Unsigned Char Payload[]; } __attribute__((Pranzo)) WifiMgmtHdr; # define maxCh (maxCh) 13 Massimo Canale -> Stati Uniti - 11, UE - 13, Giappone - 14 Int curCanale = 1; Vuoto Sniffer(Vuoto* Buf, wifi_promiscuous_pkt_type_t digitare) { Questo è dove i pacchetti finiscono dopo che vengono annusati wifi_promiscuous_pkt_t *P = (wifi_promiscuous_pkt_t*)Buf; Int Len = P->rx_ctrl.sig_len; WifiMgmtHdr *Wh = (WifiMgmtHdr*)P->Payload; Len -= Sizeof(WifiMgmtHdr); Se (Len < 0){ Seriale.println("Receuved 0"); Ritorno; } Stringa Pacchetto; Stringa Mac; Int fctl = ntohs(Wh->fctl); Per(Int Ho.=8;Ho.<=8+6+1;Ho.++){ Legge il primo paio di byte del pacchetto. Questo è dove è possibile leggere l'intero pacchetto sostituire il "8 , 6 , 1 " con "p->rx_ctrl.sig_len" Pacchetto += Stringa(P->Payload[Ho.],Hex); } Per(Int Ho.=4;Ho.<=15;Ho.++){ Questo rimuove i bit 'nibble' dalla statistica e dalla fine dei dati che vogliamo. Quindi otteniamo solo l'indirizzo mac. Mac += Pacchetto[Ho.]; } Mac.Caso toupper(); Int Aggiunto = 0; Per(Int Ho.=0;Ho.<=63;Ho.++){ controlla se l'indirizzo MAC è stato aggiunto prima Se(Mac == maclist[Ho.][0]){ maclist[Ho.][1] = defaultTTL (predefinitoTTL); Se(maclist[Ho.][2] == "OFFLINE"){ maclist[Ho.][2] = "0"; } Aggiunto = 1; } } Se(Aggiunto == 0){ Se il suo nuovo. aggiungerlo all'array. maclist[listcount][0] = Mac; maclist[listcount][1] = defaultTTL (predefinitoTTL); Serial.println(mac); listcount ++; Se(listcount >= 64){ Seriale.println("Troppi indirizzi"); listcount = 0; } } } Vuoto Installazione() { Seriale.Iniziare(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(Vero); esp_wifi_set_promiscuous_filter(&filt); esp_wifi_set_promiscuous_rx_cb(&Sniffer); esp_wifi_set_channel(curCanale, WIFI_SECOND_CHAN_NONE); Seriale.println("Inizia!"); } Vuoto epurazione(){ In questo modo viene gestita la versione TTL Per(Int Ho.=0;Ho.<=63;Ho.++){ Se(!(maclist[Ho.][0] == "")){ Int Ttl = (maclist[Ho][1].ToInt()); Ttl --; Se(Ttl <= 0){ Serial.println("OFFLINE: " : maclist[i][0]); maclist[Ho][2] = "OFFLINE"; maclist[Ho][1] = defaultTTL (predefinitoTTL); }Altro{ maclist[Ho][1] = Stringa(Ttl); } } } } Vuoto updatetime (tempo di aggiornamento)(){ Questo aggiorna l'ora in cui il dispositivo è stato online per Per(Int Ho=0;Ho<=63;Ho++){ Se(!(maclist[Ho][0] == "")){ Se(maclist[Ho][2] == "")maclist[Ho][2] = "0"; Se(!(maclist[Ho][2] == "OFFLINE")){ Int timehere = (maclist[Ho][2].ToInt()); timehere ++; maclist[Ho][2] = Stringa(timehere); } Serial.println(maclist[i][0] : " : " : maclist[i][i][2]); } } } Vuoto showpeople(){ Questo controlla se il MAC è nell'elenco dei conti e quindi lo visualizza sull'OLED e/o lo stampa su seriale. Stringa forScreen = ""; Per(Int Ho=0;Ho<=63;Ho++){ Stringa tmp1 = maclist[Ho][0]; Se(!(tmp1 == "")){ Per(Int J=0;J<=9;J++){ Stringa tmp2 = KnownMac[J][1]; Se(tmp1 == tmp2){ forScreen += (KnownMac[J][0] + " : " + maclist[Ho][2] + "N"); Seriale.Stampare(KnownMac[J][0] + " : " + tmp1 + " : " + maclist[Ho][2] + "N -- n"); } } } } } Vuoto Ciclo() { Serial.println("Changed channel:" - Stringa(curChannel)); Se(curCanale > maxCh (maxCh)){ curCanale = 1; } esp_wifi_set_channel(curCanale, WIFI_SECOND_CHAN_NONE); Ritardo(1000); updatetime (tempo di aggiornamento)(); epurazione(); showpeople(); curCanale++; }
In einem folgendem Beitrag werden wir versuchen die Anwesenheitserkennung mittels BLE umzusetzten. Bis zum n'chsten mal :)
5 commenti
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.