2017-06-09 2 views
1

Kann das UPNP-Protokoll für die automatische Portweiterleitung auf dem Router mit ESP8266 verwendet werden?ESP8266 UPnP-Portweiterleitung - IoT

Ich muss auf mein ESP8266-Modul zugreifen können, auch wenn ich nicht zu Hause bin. Derzeit habe ich die Port-Weiterleitung manuell in meinen Router-Einstellungen konfiguriert.

Aber in Zukunft, um mein Projekt zu einem kommerziellen Produkt zu machen, muss es in der Lage sein, eine automatische Portweiterleitung zu machen, da dies eine Barriere für den Durchschnittsbenutzer darstellen würde.

Im Internet fand ich etwas über UPNP auf ESP8266, aber es ging nicht um Portweiterleitung.

Vielen Dank im Voraus!

Antwort

2

Ich sehe nicht warum nicht. UPnP implementiert mehrere Profile, an denen Sie interessiert sind: IGD (Internet Gateway Device), die von den meisten Heimroutern implementiert werden, damit Clientanwendungen im lokalen Netzwerk (z. B. Skype, uTorrent usw.) Ports auf dem NAT des Routers zuordnen können.

UPnP funktioniert über IP multicast, um Geräte zu ermitteln und anzukündigen, die UPnP-Dienste über die Adresse 239.255.255.250 implementieren. Geräte, die an solchen Ankündigungen interessiert sind, abonnieren diese Multicast-Gruppe und hören Port 1900. Tatsächlich bietet UPnP selbst keinen Erkennungsmechanismus, sondern beruht auf einem Protokoll mit der Bezeichnung SSDP (Simple Service Discovery Protocol), um Hosts im lokalen Netzwerk zu finden.

Sie benötigen lediglich einen UDP-Socket, der an die oben genannte Adresse und den Port gebunden ist, um Nachrichten in Ihrer Home-Multicast-Gruppe zu abonnieren und zu veröffentlichen. Sie müssen eine Implementierung von SSDP verwenden, um Ihren Router zu erkennen. Sobald Sie Ihren Router erkannt haben, können Sie Befehle mit UPnP senden, die um SOAP Envelopes gewickelt sind.

Es gibt viele Implementierungen des UPnP-IGD-Profils in Posix C, die Sie möglicherweise erneut verwenden und an das ESP 8266 portieren (z. B. MiniUPnP, gupnp-igd).

5

Sie einen Blick auf meine Bibliothek haben kann, die ich für das gerade gemacht: https://github.com/ofekp/TinyUPnP

ich ein Beispiel für eine IOT-Gerät haben (LED-Leuchten) innerhalb der Verpackung, ich den Link aufgrund der niedrigen Ruf nicht anhängen .

Sie können sich den Beispielcode ansehen. Alles für ESP8266 gemacht. Sehr einfach zu bedienen, rufen Sie einfach AddPortMapping mit dem Port, den Sie öffnen möchten, wie im Beispiel gezeigt. Sie müssen dies alle 36000 (LEASE_DURATION) Sekunden tun, da UPnP ist Leasing-basierte Protokoll.

Declare:

unsigned long lastUpdateTime = 0; 
TinyUPnP *tinyUPnP = new TinyUPnP(-1); // -1 means blocking, preferably, use a timeout value (ms) 

Setup:

if (tinyUPnP->addPortMapping(WiFi.localIP(), LISTEN_PORT, RULE_PROTOCOL_TCP, LEASE_DURATION, FRIENDLY_NAME)) { 
    lastUpdateTime = millis(); 
} 

Loop:

// update UPnP port mapping rule if needed 
if ((millis() - lastUpdateTime) > (long) (0.8D * (double) (LEASE_DURATION * 1000.0))) { 
    Serial.print("UPnP rule is about to be revoked, renewing lease"); 
    if (tinyUPnP->addPortMapping(WiFi.localIP(), LISTEN_PORT, RULE_PROTOCOL_TCP, LEASE_DURATION, FRIENDLY_NAME)) { 
     lastUpdateTime = millis(); 
    } 
} 

Ich habe es nur mit meinem D-Link-Router.

Für jeden daran interessiert, wie die Bibliothek funktioniert:

  1. Es hat eine M_SEARCH Nachricht an UPnP UDP-Multicast-Adresse sendet. Der Gateway-Router antwortet mit einer Nachricht mit einem HTTP-Header namens Location.
  2. Location ist eine Verknüpfung zu einer XML-Datei, die die IGD-API (Internet Gateway Device) enthält, um die erforderlichen Aufrufe zu erstellen, die die neue Portzuordnung zu Ihrem Gateway-Router hinzufügen.
  3. Einer der Dienste, die in der XML dargestellt wird, ist <serviceType>urn:schemas-upnp-org:service:WANPPPConnection:1</serviceType>, wonach die Bibliothek sucht.
  4. Dieser Dienst enthält ein eventSubURL-Tag, das eine Verbindung zur IGD-API Ihres Routers ist. (Die Basis-URL wird auch in derselben Datei unter dem Tag URLBase angezeigt.)
  5. Mithilfe der Basis-URL und der WANPPPConnection-Verknüpfung können Sie eine HTTP-Abfrage an den Router senden, der die UPnP-Regel hinzufügt.
  6. Als eine Nebenbemerkung enthält der Service, der in der XML dargestellt wird, außerdem ein SCPDURL-Tag, das eine Verknüpfung zu einem anderen XML ist, das für den Dienst verfügbare Befehle und ihre Parameter darstellt. Das Paket überspringt diese Stufe, da ich annahm, dass die Abfrage für viele Router ähnlich sein wird. Dies kann jedoch sehr wohl nicht der Fall sein. Es liegt also an Ihnen, dies zu überprüfen.
  7. Ab diesem Zeitpunkt gibt das Paket den Dienstbefehl mit einer HTTP-Abfrage an den Router aus. Die eigentliche Abfrage kann ganz klar im Code zu sehen, sondern für alle Interessierten:

Headers:

"POST " + <link to service command from XML> + " HTTP/1.1" 
"Content-Type: text/xml; charset=\"utf-8\"" 
"SOAPAction: \"urn:schemas-upnp-org:service:WANPPPConnection:1#AddPortMapping\"" 
"Content-Length: " + body.length() 

Körper:

"<?xml version=\"1.0\"?>\r\n" 
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" 
"<s:Body>\r\n" 
"<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANPPPConnection:1\">\r\n" 
" <NewRemoteHost></NewRemoteHost>\r\n" 
" <NewExternalPort>" + String(rulePort) + "</NewExternalPort>\r\n" 
" <NewProtocol>" + ruleProtocol + "</NewProtocol>\r\n" 
" <NewInternalPort>" + String(rulePort) + "</NewInternalPort>\r\n" 
" <NewInternalClient>" + ipAddressToString(ruleIP) + "</NewInternalClient>\r\n" 
" <NewEnabled>1</NewEnabled>\r\n" 
" <NewPortMappingDescription>" + ruleFriendlyName + "</NewPortMappingDescription>\r\n" 
" <NewLeaseDuration>" + String(ruleLeaseDuration) + "</NewLeaseDuration>\r\n" 
"</u:AddPortMapping>\r\n" 
"</s:Body>\r\n" 
"</s:Envelope>\r\n"; 

Ich hoffe, das hilft.