Hola a todos
Hoy queremos presentarles un proyecto al que nos dimos cuenta a través de una solicitud de cliente. Le mostramos un detector de direcciones MAC con nuestra placa de desarrollo ESP32 C.
No se requiere más hardware que esta placa. El Mac-Detector analiza consecutivamente las direcciones almacenadas en el código y las envía en el monitor serie tan pronto como se acerca un dispositivo. Para ello, utilizamos el modo Promiscuous, que se puede utilizar mucho más fácilmente con el ESP32 que con el predecesor ESP8266. La detección de presencia funciona de forma bastante fiable, pero es importante tener en cuenta que el escáner sólo emite algo cuando el dispositivo WiFi está "despierto" y se comunica. Por lo tanto, la dirección puede tardar algún tiempo en aparecer en el monitor serie. Dependiendo del dispositivo utilizado y su configuración, a menudo ahorran energía y desactivan los componentes no utilizados. Varios iPhones han demostrado ser particularmente interesados en comunicarse.
Simplemente ingrese las direcciones deseadas en :adress list, ready.
Aquí está el código:
#include <Wifi.H> #include <Alambre.H> #include "esp_wifi.h" Cadena maclist[64][3]; Int recuento de listas = 0; Cadena KnownMac[10][2] = { lista de aparar {"Chef1","8C1ABF8A6A36"}, {"Chef2","E894BA82BC83"}, {"NOMBRE","MACADDRESS"}, {"NOMBRE","MACADDRESS"}, {"NOMBRE","MACADDRESS"}, {"NOMBRE","MACADDRESS"}, {"NOMBRE","MACADDRESS"}, {"NOMBRE","MACADDRESS"}, {"NOMBRE","MACADDRESS"} }; Cadena defaultTTL = "60"; Tiempo máximo (apx segundos) transcurrido antes de que el dispositivo se conderese sin conexión Const wifi_promiscuous_filter_t filt={ .filter_mask=WIFI_PROMIS_FILTER_MASK_MGMT|WIFI_PROMIS_FILTER_MASK_DATA }; Typedef Estructura { uint8_t Mac[6]; } __attribute__((Embalado)) MacAddr; Typedef Estructura { int16_t fctl; int16_t Duración; MacAddr allí; MacAddr Sentado; MacAddr Bssid; int16_t seqctl; Unsigned Char Carga útil[]; } __attribute__((Embalado)) WifiMgmtHdr; #define maxCh 13 canal máximo -> EE.UU. 11, UE 13, Japón 14 Int curChannel = 1; Vacío Sniffer(Vacío* Buf, wifi_promiscuous_pkt_type_t Tipo) { Aquí es donde los paquetes terminan después de que se olfatean wifi_promiscuous_pkt_t *P = (wifi_promiscuous_pkt_t*)Buf; Int Len = P->rx_ctrl.sig_len; WifiMgmtHdr *Wh = (WifiMgmtHdr*)P->Carga útil; Len -= Sizeof(WifiMgmtHdr); Si (Len < 0){ Serial.println("Receuved 0"); devolución; } Cadena Paquete; Cadena Mac; Int fctl = ntohs(Wh->fctl); Para(Int Ⅰ.=8;Ⅰ.<=8+6+1;Ⅰ.++){ Esto lee el primer par de bytes del paquete. Aquí es donde usted puede leer el paquete entero substituya el "8+6+1" con "p->rx_ctrl.sig_len" Paquete += Cadena(P->Carga útil[Ⅰ.],Hexagonal); } Para(Int Ⅰ.=4;Ⅰ.<=15;Ⅰ.++){ Esto elimina los bits 'nibble' de la estadística y el final de los datos que queremos. Así que sólo obtenemos la dirección mac. Mac += Paquete[Ⅰ.]; } Mac.Touppercase(); Int Añadido = 0; Para(Int Ⅰ.=0;Ⅰ.<=63;Ⅰ.++){ comprueba si la dirección MAC se ha agregado antes Si(Mac == maclist[Ⅰ.][0]){ maclist[Ⅰ.][1] = defaultTTL; Si(maclist[Ⅰ.][2] == "OFFLINE"){ maclist[Ⅰ.][2] = "0"; } Añadido = 1; } } Si(Añadido == 0){ Si es nuevo. añadirlo a la matriz. maclist[recuento de listas][0] = Mac; maclist[recuento de listas][1] = defaultTTL; Serial.println(mac); recuento de listas ++; Si(recuento de listas >= 64){ Serial.println("Demasiadas direcciones"); recuento de listas = 0; } } } Vacío Configuración() { Serial.Comenzar(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(Verdad); esp_wifi_set_promiscuous_filter(&filt); esp_wifi_set_promiscuous_rx_cb(&Sniffer); esp_wifi_set_channel(curChannel, WIFI_SECOND_CHAN_NONE); Serial.println("¡Comienza!"); } Vacío Purga(){ Esto administra el TTL Para(Int Ⅰ.=0;Ⅰ.<=63;Ⅰ.++){ Si(!(maclist[Ⅰ.][0] == "")){ Int Ttl = (maclist[yo][1].toInt()); ttl --; Si(ttl <= 0){ //Serial.println("OFFLINE: "+ maclist [i] [0]); Maclist[yo][2] = "DESCONECTADO"; Maclist[yo][1] = defaultTTL; }más{ Maclist[yo][1] = Cuerda(ttl); } } } } vacío tiempo de actualizacion(){ // Esto actualiza el tiempo que el dispositivo ha estado en línea durante para(En t yo=0;yo<=63;yo++){ Si(!(Maclist[yo][0] == "")){ Si(Maclist[yo][2] == "")Maclist[yo][2] = "0"; Si(!(Maclist[yo][2] == "DESCONECTADO")){ En t tiempo aquí = (Maclist[yo][2].toInt()); tiempo aquí ++; Maclist[yo][2] = Cuerda(tiempo aquí); } // Serial.println (maclist [i] [0] + ":" + maclist [i] [2]); } } } vacío showpeople(){ // Esto comprueba si el MAC está en la lista calculada y luego lo muestra en el OLED y / o lo imprime en serie. Cuerda forScreen = ""; para(En t yo=0;yo<=63;yo++){ Cuerda tmp1 = Maclist[yo][0]; Si(!(tmp1 == "")){ para(En t j=0;j<=9;j++){ Cuerda tmp2 = KnownMac[j][1]; Si(tmp1 == tmp2){ forScreen += (KnownMac[j][0] + " : " + Maclist[yo][2] + "\norte"); De serie.impresión(KnownMac[j][0] + " : " + tmp1 + " : " + Maclist[yo][2] + "\ n - \ n"); } } } } } vacío lazo() { //Serial.println("Changed channel: "+ String (curChannel)); Si(curChannel > maxCh){ curChannel = 1; } esp_wifi_set_channel(curChannel, WIFI_SECOND_CHAN_NONE); retrasar(1000); tiempo de actualizacion(); purga(); showpeople(); curChannel++; }
En einem folgendem Beitrag werden wir versuchen die Anwesenheitserkennung mittels BLE umzusetzten. Bis zum nächsten mal :)
5 comentarios
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.