といっても、規格もちゃんと決まっているものなので、実装「それ自身」はちゃんと規格書を読めればそれなりなのですが、それを実装するまでに手間取りました・・・。
いろいろなページから必要な情報だけをピックアップして実装しています。
実装の目的は?
何となくわかると思いますが、ちょっととある目的のために通信プログラムを考えていて、そのための前段階として「ルーターにポートを開けさせる」動作を
ユーザーが簡単にできるようにするために必要だと思ったので実装に踏み切りました。
Universal Plug And Playというのは、本来は「Universalでやりとりするため」の規格ですが、今回の場合は「ルーターの情報を取得する」ことを目的としています。
これの処理用のライブラリもあるような気がしますが、やっぱりライセンスが気になるので自前実装で。
はじめのSSDPによるマルチキャストに苦労
マルチキャストにはUDPによる通信・・・というかパケット送信がいりますが、マルチキャストの発行でいろいろとつまずいていしましました。
マルチキャストを発行するためには通常、
マルチキャストの発行元デバイス(もしくはIP)を通信ソケットに設定する必要がある
という項目が必要です。これを知らなかったので闇雲にテストを繰り返して「マルチキャストが送信されていない」というところに気がつくまでに苦労しました。
それがわかったとしてももう一つの問題
自身のLANポートに設定されているIPを取得する必要がある
ということです。これに関してはマシンによっては複数のIPを持っている可能性がありますので注意してください。
(LANポートが一つしか無くてもLoopbackインターフェイスやら仮想LANやらで認識されているインターフェイスは複数ある可能性がある)
これに関してはIPHelperAPIからGetAdaptersAddresses(WinXP以降)もしくはGetIpAddrTable(Win2000以前)で調べることができます。
XMLのリーダーが必要
UPNPは基本的にXMLでやりとりするので、簡易でもいいのでXMLを処理できる必要があります。
といっても、まさかlibxmlとかその系統に頼ろうとすると、今度はGPLやらBSDやらと面倒なライセンスが絡むのがやっかいです。
私の場合はとりあえずXMLのParserを組んでそれに処理させていますが、それでもちょっと処理が甘い(エラーやら)のが弱点ですね。
ライセンスを気にしないのであればライブラリを使うのもありだと思います。
マルチキャストの情報後はただのhttp通信になる
UPNPに必要な通信アドレスおよびページの取得もhttp通信(xmlファイルの取得)なら、その後の命令発行もhttp通信(の変形)です。
POSTコマンドで必要なXMLの文章を送りつける形をとります。なので、以降はTCPを使ったhttpの通信を理解している必要があります。全部UDPの方が楽なんだけどな・・・。
送信側のXMLの構築は固定なので適当にsprintfあたりで処理すれば問題ないと思います。
Windowsの場合に限り、COMでUPNPを処理できたりする
できたりするんです。汎用で処理する場合はソケットを使って通信部分を実装する必要がありますが、COMで組む場合はインターフェイスに指示を出すだけなのでバグも少なく楽ちんです。
問題はやはり、「Windowsの場合に限り」ですね。これが気になる人はがんばって通信で組んでください。