2017-06-09 21 views
1

ESP8266を使用してルータ上の自動ポート転送にUPNPプロトコルを使用できますか?ESP8266 UPnPポート転送 - IoT

私が帰宅していてもESP8266モジュールにアクセスできる必要があります。 現在、ルータの設定でポート転送を手動で設定しています。

将来的には、私のプロジェクトが商用製品になるためには、自動ポート転送が可能である必要があります。これは平均的なユーザーの障壁となるためです。

インターネット上で、私はESP8266でUPNPについて話していましたが、ポート転送に関してではありませんでした。

ありがとうございます!

答えて

2

なぜそうは見えないのですか? UPnPは複数のプロファイルを実装していますが、興味のあるものはIGD (Internet Gateway Device)という名前で、ほとんどの家庭用ルータはローカルネットワーク上のクライアントアプリケーション(Skype、uTorrentなど)がルータのNAT上のポートをマッピングできるように実装しています。

UPnPは、アドレス239.255.255.250でUPnPサービスを実装するデバイスを検出してアナウンスするために、IP multicast以上で動作します。そのようなアナウンスに興味のあるデバイスは、このマルチキャストグループに加入し、ポート1900でリッスンします。実際には、UPnP自体は検出メカニズムを提供しませんが、ローカルネットワーク上のホストを検出するためにSSDP (Simple Service Discovery Protocol)というプロトコルに依存しています。

ホームマルチキャストグループのメッセージを購読して公開するには、前述のアドレスとポートにバインドされたUDPソケットが必要です。 SSDPの実装を使用してルータを発見する必要があります。ルータを発見すると、SOAP enveloppesをラップしたUPnPを使用してコマンドを送信できます。

Posix CにUPnP IGDプロファイルが実装されています。これを再利用してESP 8266に移植することができます(例:MiniUPnPgupnp-igd)。あなたは、私はちょうどそれのために作られた私のライブラリを見て持つことができます

5

:私はパッケージ内IOTデバイス(LEDライト)のための例を持って https://github.com/ofekp/TinyUPnP

を、私は、低評判へのリンクを添付することはできません。

サンプルコードをご覧ください。すべてESP8266のために作られました。 非常に使いやすく、例のように、開くポートでaddPortMappingを呼び出すだけです。 UPnPはリースベースのプロトコルなので、36000 (LEASE_DURATION)秒ごとにこれを行う必要があります。

宣言:

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

セットアップ:

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

ループ:

// 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(); 
    } 
} 

私は私のD-Linkのルータでそれを確認しました。

ライブラリがどのように機能するかに興味がある人へ:

  1. これは、UPnP、UDPマルチキャストアドレスにM_SEARCHメッセージを送信します。
  2. ゲートウェイルータは、LocationというHTTPヘッダーを含むメッセージで応答します。
  3. Locationは、ゲートウェイルーターに新しいポートマッピングを追加するために必要な呼び出しを作成するために、IGD(Internet Gateway Device)APIを含むXMLファイルへのリンクです。
  4. XMLで示されているサービスの1つは、<serviceType>urn:schemas-upnp-org:service:WANPPPConnection:1</serviceType>であり、これは図書館が探しているサービスです。
  5. このサービスには、ルータのIGD APIへのリンクであるeventSubURLタグが含まれています。 (ベースURLはタグURLBaseの下の同じファイルにも記載されています)
  6. ベースURLとWANPPPConnectionリンクを使用すると、UPnPルールを追加するHTTPクエリをルータに発行できます。
  7. 注釈として、XMLに描かれているサービスには、SCPDURLタグも含まれています。このタグは、サービスで使用可能なコマンドとそのパラメータを示す別のXMLへのリンクです。パッケージはこの段階をスキップしています。これは、多くのルータでクエリが似ていると想定しているためですが、そうではない可能性があります。チェックするのはあなた次第です。
  8. この段階から、パッケージはHTTPクエリを使用してルータにserviceコマンドを発行します。実際のクエリは非常にはっきりコードで見られるが、興味がある人のためにすることができます:

ヘッダ:

"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() 

ボディ:

"<?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"; 

私はこのことができます願っています。