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:
- 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
.
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.
- Einer der Dienste, die in der XML dargestellt wird, ist
<serviceType>urn:schemas-upnp-org:service:WANPPPConnection:1</serviceType>
, wonach die Bibliothek sucht.
- 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.)
- 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.
- 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.
- 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.