Problema Esp8266 soft AP mode + mDNS Responder

Ciao a tutti, mi trovo con un problema comune ad altri utenti a quanto leggo dalle mie ricerche su Google, ma nonostante i numerosi metodi suggeriti nei vari forum e sulle pagine di risoluzione problemi segnalati sul github degli esp non trovo soluzione.

Uso Arduino IDE 1.8.5 con questo link:http://arduino.esp8266.com/stable/package_esp8266com_index.json
messo tra le opzioni del board manager per programmare un NodeMCU 1.0 e riesco ad utilizzare tranquillamente gli esempi presenti tra quelli per gli esp denominati:

mDNS_Web_Server
e
WiFiAccessPoint

Ma se carico questo sketch che è il misto dei due precedenti esempi, la pagina web funziona solo se mi collego all'ip dell'access point (ovvero 192.168.4.1). Se provo a collegarmi alla pagina http://esp8266.local/ ottengo dal browser un errore di risoluzione dell'indirizzo.
Da quanto ho letto era un errore che poi è stato fixato, ma a me il problema persiste! Qualcuno mi aiuta a capire il problema ?

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
const char *ssid = "ESPap";
ESP8266WebServer server(80);


void handleRoot() {
  server.send(200, "text/html", "<h1>You are connected</h1>");
}


void setup() {
  Serial.begin(9600);
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid);
  IPAddress myIP = WiFi.softAPIP();
  if (!MDNS.begin("esp8266", myIP)) {
    Serial.println("Error setting up MDNS responder!");
    while (1) {
      delay(1000);
    }
  }
  MDNS.addService("http", "tcp", 80);
  server.on("/", handleRoot);
  server.begin();
}

void loop() {
  server.handleClient();
}

Se non ho capito male tu ti colleghi all'AP dell'ESP8266 e poi, con un dispositivo che non spieghi, metti nel browser http://esp8266.local/
Quello che probabilmente succede è che il dispositivo su cui hai il browser non gestisce il Multicast DNS (noto anche come bonjour). Ad esempio Windows non lo supporta tranne forse nelle ultimissime versioni del 10 si è convinta a supportarlo.

Per risolvere devi fare in modo che l'ESP8266 metta su un server DNS.

Mi collego con uno smartphone Android con browser Google Chrome e e con lo sketch di esempio che testa proprio la funzionalità del mdns responder funziona

Con il mio sketch che utilizza la modalità ap dell'esp invece non funziona

Scusate ma non capisco bene lo scopo. Si vuole fare del povero ESP un access point/router, oppure tutto risiede sullo stesso ESP?

Perché se la risposta è la prima, non so proprio dire se si possa fare (non lo escludo del tutto ma "a naso" mi pare un tantino eccessivo) ma comunque nei commenti del mDNS si legge:

_ - Install host software:_

E comunque se usi altro device (EDIT: vedo che parli di Android...) non funziona.

Se la risposta è la seconda, visto che l'ESP ha un IP fisso non basta mettere nel file hosts del client Windows (c:\windows\system32\drivers\etc) l'associazione tra quell'IP ed il nome che vuoi usare? O richiamare da browser direttamente l'IP?

Con Android funziona di sicuro perché ho un altro progetto che usa questo sistema su scheda Ethernet + arduinoUNO E funziona tranquillamente...poi tra l'altro come ho già detto, lo stesso schetch d' esempio della libreria ESP che usa mdns: dal telefonino apro tranquillamente la pagina scrivendo:
esp8266.local

Il problema ce l'ho solo se l esp fa da Access point.
se l esp è un client del mio router il servizio funziona regolarmente (mi collego sempre dallo stesso telefono)

Ho appena provato il tuo sketch e ottengo lo stesso risultato. Ma a me non funziona neanche l'esempio mDNS_Web_Server, Android 5 e Firefox. Potrebbe essere colpa dell'Access Point che uso, un pennino collegato al PC. Magari riprovo a casa.

se usi PC devi installare obbligatoriamente il software Apple Bonjour che permette al pc di ricoscere queato tipo di servizi.

se puoi prova ad installare Bonjour e poi provi lo sketch mDNS_Web_Server (dovrebbe funzionare come funziona a me)

poi riprova il mio sketch e vediamo se hai ancora il problema (come me) o no

Ho trovato un post che dice

On Android, the situation is actually pretty good, from a developer point of view: the Network Service Discovery API has been introduced back with the first release of Jelly Bean 4.1 but the implementation was not completed until Android Lollipop 5.1, when the custom attributes were actually added to the APIs.

E io ho il 5.1.1
Preso da qui

Ho appena provato proprio mDNS_Web_Server. A casa proverò sempre con Android 5.1.1 e anche con un altro tablet con LineageOS13 (android 6). La differenza è che c'è un vero router a cui collegarmi. Inoltre potrei far girare WireShark per vedere se vedo il pacchetto UDP di richiesta da parte di Android e i pacchetti di risposta.

qui intanto c'era la discussione sullo stesso problema trovato anni fa e segnalato come risoltosul github degli esp:

ho provato le soluzioni proposte ma mi da sempre lo stesso risultato...web server funzionante...nessun errore sulla seriale ma pagina raggiungibile solo da ip e non da esp8266.local

NON riguarda questo specifico problema, ma un problema simile con Arduino Yún a cui Astro dette una risposta ...
... provate a leggere QUI, magari trovate una soluzione ::slight_smile:

Guglielmo

Appunto per questo voglio vedere cosa succede con WireShark. Trattandosi di comunicazioni broadcast, cioè mandate a tutti nella rete, dovrei vedere cosa succede, perché a me non funziona neanche l'esempio.

A casa so già che il metodo di trovare dispositivi mediante UDP broadcast funziona perché mi ha funzionato per altre applicazioni. Devo però vedere se effettivamente il mio Android supporta mDNS che sarebbe il Bonjour di Apple che lo ha inventato. La mia opinione è che si tratta di un servizio comodo ma bistrattato da Microsoft, in questo caso sono un po' stronzi, mi sembra.

gpb01:
NON riguarda questo specifico problema, ma un problema simile con Arduino Yún a cui Astro dette una risposta ...
... provate a leggere QUI, magari trovate una soluzione ::slight_smile:

Guglielmo

Suppongo che in quel caso il problema dovrei averlo anche con lo sketch d'esempio che usa la funzione mDNS.. invece quella continua a funzionare.
E' l'accoppiata Esp in modalità AP + mDNS che non funziona ! :frowning:

Ho provato a usare la versione "staging" delle board ESP, ma per un motivo che non mi spiego, appena scarico qualsiasi versione non del ramo "stable" e provo a compilare, ottengo un errore nell'IDE del tipo

board esp non conosciuta (+ o -) e ho provato anche a disinstallare completamente le board aggiuntive, disinstallare Arduino Ide e reinstallare il tutto.

Purtroppo ieri ho avuto da fare e mi son dimenticato della prova (e di altre cose di cui piangerò le conseguenze).

Ho quindi rifatto la prova in ufficio con Wireshark, ho il tablet e l'ESP8266 con l'esempio mDNS di cui abbiamo parlato.

Gli IP sono questi
Router 192.168.137.1
Tablet 192.168.137.128
ESP 192.168.137.27

Metto nel browser esp8266.local e quindi invio

Su Wireshark vedo molte righe ma qui le separo per chiarezza.

1912 456.310430 192.168.137.128 8.8.8.8 DNS 73 Standard query 0x5651 A esp8266.local
1915 456.348623 8.8.8.8 192.168.137.128 DNS 148 Standard query response 0x5651 No such name A esp8266.local SOA a.root-servers.net
1928 456.554230 192.168.137.128 8.8.8.8 DNS 77 Standard query 0x73f2 A www.esp8266.local
1932 456.592395 8.8.8.8 192.168.137.128 DNS 152 Standard query response 0x73f2 No such name A www.esp8266.local SOA a.root-servers.net

Queste righe indicano che il tablet esegue una normale richiesta DNS ai server di Google (8.8.8.8 ) i quali ovviamente rispondono che esp8266.local e www.esp8266.local non esistono.

Poi c'è questa riga che non so interpretare

1942	456.746610	192.168.137.128	224.0.0.251	MDNS	135	Standard query 0x0003 PTR _08FF1091._sub._googlecast._tcp.local, "QM" question PTR _CC1AD845._sub._googlecast._tcp.local, "QM" question PTR _4574A331._sub._googlecast._tcp.local, "QM" question PTR _googlecast._tcp.local, "QM" question

Wireshark mi dice che ha a che fare con il protocollo MDNS ma è un collegamento verso l'esterno.

Nel frattempo ci sono i famosi pacchetti UDP

1913	456.318993	192.168.137.128	192.168.137.1	UDP	42	46737 ? 4886 Len=0

Il tablet manda parecchi pacchetti UDP, una ventina,ma non sono broadcast, li manda al router. E sembrano vuoti (Len=0).

Può essere che l'implementazione di mDNS sul mio Android non sia corretta, o non ci sia proprio, ma non ho mai visto uno scambio di pacchetti per il protocollo mDNS quindi può essere benissimo che la mia interpretazione sia errata.

Una domanda, sul tablet hai DNS manualmente impostati su 8.8.8.8 oppure come DNS usi il router che a sua volta usa quelli di Google ?

Non conosco cosi tanto bene il servizio bonjour e come laori il mDNS ma FORSE funziona solo se usi come DNS il router che sa che esp8266.local corrisponde all'ip dell'esp perchè l'esp glielo ha comunicato.

Immagino che se usi DNS manualmente impostati su quelli di Google nelle opzioni del tablet, il dispositivo indirizza la richiesta di risoluzione al dns di google che ovviamente non può sapere la risposta.

Comunque mi sono ritrovato un altro problema !!! Anche questo a quanto leggo su internet sembrerebbe risolto tempo fa. Riguarda un bug della libreria WiFi di Arduino che richiamando:

WiFi.macAddress(mac);

restituisce il mac address ma invertito! (Ho trovato questa discussione che parla di problema simile)

Sbaglio qualcosa io o potrebbe essere un problema della libreria wifi degli esp ?

Io non ricordo di aver inserito manualmente i DNS di Google e ti confesso che anche io mi sono chiesto come mai usasse quelli. Il mio sospetto è sia Android su questo tablet Samsung che di suo utilizza i DNS di Google ma devo indagare ulteriormente.
Il tablet usa direttamente i DNS di Google, non chiede prima al router altrimenti vedrei la richiesta.
Wireshark è installato sul PC che fa da router e AccessPoint usando una pennetta WiFi e VirtualRouter. Quindi vedo tutto quello che arriva o passa dal router.

Come ho appena fatto in un altro thread che parlava SOLO di WeMos, ricordo sempre che questo è il forum di Arduino.cc dove si fornisce assistenza per problemi relativi a problematiche che coinvolgono Arduino, i suoi collegamenti e la sua programmazione.

Quindi, ben vengano domande che riguardano moduli ESP8266 collegati ad Arduino, ma domande per moduli che nulla hanno a che vedere con Arduino, basati su altri progetti che hanno semplicemente utilizzato/sfruttato l'IDE per sviluppare un loro "core" e facilitare la programmazione delle loro schede, come le schede NodeMCU, vanno poste sui relativi forum di supporto.

Grazie.

Guglielmo

P.S.: Come vedete NON ho chiuso il thread, ma ... non esagerate eh ... :wink:

Trovata soluzione guardando l'esempio CaptivePortal disponibile per gli esp. Diciamo che non funziona nel modo in cui pensavo, ma funziona. Ecco il codice completo che ho testato:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <DNSServer.h>
const char *ssid = "ESPap";
ESP8266WebServer server(80);
byte mac[6];
IPAddress apIP(192, 168, 4, 1);
IPAddress netMsk(255, 255, 255, 0);
const byte DNS_PORT = 53;
DNSServer dnsServer;
const char *myHostname = "esp8266";

void handleRoot() {
  server.send(200, "text/html", "<h1>You are connected</h1>");
}


void setup() {
  Serial.begin(9600);
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, netMsk);
  WiFi.softAP(ssid);
  delay(500); // Without delay I've seen the IP address blank
  IPAddress IP = WiFi.softAPIP();
  dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
  dnsServer.start(DNS_PORT, "*", apIP);
  server.on("/", handleRoot);
  server.begin();
  if (!MDNS.begin("esp8266", IP)) {
    Serial.println("Error setting up MDNS responder!");
    while (1) {
      delay(1000);
    }
  }
  MDNS.addService("http", "tcp", 80);
  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 loop() {
  dnsServer.processNextRequest();
  server.handleClient();
}

In pratica così facendo, metto il modalità AP l'esp, mi collego alla sua rete ed una volta fatto qualsiasi pagina venga richiesta mi rimanda al suo ip.

Anche la stringa dell'hostname rimanderà quindi a quell ip, ottenendo l'apertura della pagina.
Solo che non è proprio una soluzione pulita.

Se quando ti connetti come Access Point l'ESP è l'unico dispositivo a cui ti vuoi collegare è invece la soluzione migliore e l'MDNS sarebbe uno spreco.
Ha anche il pregio di funzionare anche con Windows e con tutti i dispositivi che non hanno il supporto nativo per l'MDNS.

I dispositivi che si configurano mettendo a disposizione un Access Point fanno tutti così.