mbedを使ったUPnPデバイスの作り方
.
mbedを使ったUPnPデバイスの作り方です。
UPnPで何が出来るのか
UPnP(ユニバーサルプラグアンドプレイ)デバイスは、ネットワークに接続するだけで利用できるネットワーク機器です。UPnPデバイスとして動作するmbedは、ネットワーク設定を行わずにコンピュータから検出し、アクセスし、操作することが出来ます。
この画像はWindows7で認識した様子です。
MiMicを使ったUPnPの機能
MiMicのUPnPモジュールは、アドレッシング、ディスカバリ、デスクリプション、プレゼンテーションの機能をサポートしています。 これらの機能から、最も単純なUPnPデバイス UPnPBasicDevice:1を構成することが出来ます。
※現在のバージョンでは、コントロール、イベント機能はありません。
UPnPデバイスを実行してみる
以下のプロジェクトはUPnPBasicDevice:1の実装です。
Import programUPnPBasicDevice
Simplest UPnP basic device example. This program to run UPnP basic device on the mbed.
ファームウェアを書き込んだmbedをネットワークに接続すると、UPnPデバイスとしてOS(Windows)から認識することが出来ます。
新たにUPnPデバイスを作る場合は、これをベースにすることができます。
ソースコード
プログラム構造はHttpServerにUPnP処理を追加した形をしています。パーツとしてはHttpServer機能を提供するUPnPBasicDeviceHttpdクラスと、起動する為の手続きを記述したmain関数の2つに分かれます。
UPnPBasicdevice::main.cpp 全文
/** * @file * Simplest UPnP basic device.<br/> * This program is upnp:BasicDeveice:1 template. * * <p> * After starting program, check "network" by Exproler. * MiMic basic device will be appeared. * </p> */ #include "mbed.h" #include "rtos.h" #include "SDFileSystem.h" #include "mimic.h" #include "utils/PlatformInfo.h" #include "fsdata.h" Net* net; /** * Httpd for UPnPService and presentation. */ class UPnPBasicDeviceHttpd:public MiMic::Httpd { private: ModUPnPDevice modupnp; ModRomFiles modromfs; //ROM file module public: UPnPBasicDeviceHttpd(NetConfig& i_cfg):Httpd(i_cfg.getHttpPort()) { //prepare fs data (presentation.html,icon,image.) this->modromfs.setParam("rom",FSDATA,3); //bind upnp service to module. this->modupnp.setParam(*net); } virtual void onRequest(HttpdConnection& i_connection) { //try to ModRomFS module. for icon,images. if(this->modromfs.execute(i_connection)){ return; } //try to UPnP service. for descriptions. if(this->modupnp.execute(i_connection)){ return; } //Otherwise, Send the redirect response to /rom/index.html i_connection.sendHeader(302, "text/html", "Status: 302:Moved Temporarily\r\n" "Location: /rom/index.html\r\n"); } }; NetConfig cfg; //create network configulation int main() { net=new Net();//Net constructor must be created after started RTOS //Prepare configulation. cfg.setUPnPIcon(64,64,8,"image/png","/rom/icon.png");//set upnp icon address cfg.setUPnPUdn(0xe29f7103,0x4ba2,0x01e0,0); //set application timebase-uuid time and sequence field. cfg.setFriendlyName("UPnPBasicDevice(LPC176x)"); //set friendly name cfg.setUPnPPresentationURL("/rom/index.html"); //set presentationURL cfg.setZeroconf(true);//AutoIP enable UPnPBasicDeviceHttpd httpd(cfg); //create a httpd instance. net->start(cfg); httpd.loop(); //start httpd loop. return 0; }
HttpServerクラス
20-54行はHttpServerの実装です。httpdはメイン関数から起動します。
Httpd部分
class UPnPBasicDeviceHttpd:public MiMic::Httpd { private: ModUPnPDevice modupnp; ModRomFiles modromfs; //ROM file module public: UPnPBasicDeviceHttpd(NetConfig& i_cfg):Httpd(i_cfg.getHttpPort()) { //prepare fs data (presentation.html,icon,image.) this->modromfs.setParam("rom",FSDATA,3); //bind upnp service to module. this->modupnp.setParam(*net); } virtual void onRequest(HttpdConnection& i_connection) { //try to ModRomFS module. for icon,images. if(this->modromfs.execute(i_connection)){ return; } //try to UPnP service. for descriptions. if(this->modupnp.execute(i_connection)){ return; } //Otherwise, Send the redirect response to /rom/index.html i_connection.sendHeader(302, "text/html", "Status: 302:Moved Temporarily\r\n" "Location: /rom/index.html\r\n"); } };
HttpServerには2つのサービスモジュールを実装します。
- ModRomFiles - 構造体に格納したファイルイメージを返却するモジュール。ファイルイメージはfsdat.hに構造体で定義します。プレゼンテーション用のindex.html,HTMLコンテンツを提供します。
- ModUPnPDevice - UPnPのデスクリプション処理を行うモジュール。UPnPから要求されるHttpリクエストを処理します。
main関数
UPnPBasicdevice::main関数
int main() { net=new Net();//Net constructor must be created after started RTOS //Prepare configulation. cfg.setUPnPIcon(64,64,8,"image/png","/rom/icon.png");//set upnp icon address cfg.setUPnPUdn(0xe29f7103,0x4ba2,0x01e0,0); //set application timebase-uuid time and sequence field. cfg.setFriendlyName("UPnPBasicDevice(LPC176x)"); //set friendly name cfg.setUPnPPresentationURL("/rom/index.html"); //set presentationURL cfg.setZeroconf(true);//AutoIP enable UPnPBasicDeviceHttpd httpd(cfg); //create a httpd instance. net->start(cfg); httpd.loop(); //start httpd loop. return 0; }
main関数はネットワークサービスの生成、ネットワークコンフィギュレーションの設定、Httpdの生成、ネットワークの起動の後、httpdのループ処理を実行します。
Tips
httpd.loopを別のタスクで実行する
サンプルコードでは、httpd.loop();を実行後に他の処理を行うことができず、Httpリクエストに反応する以外の動作が出来ません。main関数のスレッドをそのまま利用するときは、 httpd.loop();の変わりに httpd.loopTask();関数を使います。
httpd.loopTask
int main() { net=new Net();//Net constructor must be created after started RTOS //Prepare configulation. cfg.setUPnPIcon(64,64,8,"image/png","/rom/icon.png");//set upnp icon address cfg.setUPnPUdn(0xe29f7103,0x4ba2,0x01e0,0); //set application timebase-uuid time and sequence field. cfg.setFriendlyName("UPnPBasicDevice(LPC176x)"); //set friendly name cfg.setUPnPPresentationURL("/rom/index.html"); //set presentationURL cfg.setZeroconf(true);//AutoIP enable UPnPBasicDeviceHttpd httpd(cfg); //create a httpd instance. net->start(cfg); //httpd.loop(); //start httpd loop. httpd.loopTask(); //start httpd loop with new task for(;;){ Thread::wait(1000); } return 0; }
httpd.loopTask();関数は約300バイトのメモリを消費して別タスクでhttpdの処理を行います。
プレゼンテーションをカスタマイズする
プレゼンテーションページ(UPnPデバイスのアイコンをダブルクリックすると出てくるページ)は好みのものに変更することが出来ます。サンプルでは、fsdata.hにコンテンツファイルのデータを格納した構造体があります。
fsdata.h
#include "mimic.h" struct NyLPC_TRomFileData FSDATA[3]= { { //filename "icon.png", //size 2271, //mimetype "image/png", //file image "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x..." }, { "logo.png", 9040, //mimetype "image/png", //file image "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\..." }, { "index.html", 1122, "text/html", "\x3C\x21\x44\x4F\x43\x54\x59\x50\x45\x20\x68\x74\x6D\x6C\x3E\..." } };
必要な情報は、ファイル名,サイズ,mimetype,ファイルイメージのデータです。ファイルイメージは文字列形式なので、バイナリファイルの場合はテキスト形式に変換してください。
ファイル→構造体の変換プログラムはこちらからダウンロードできます。
File2FileStruct http://sourceforge.jp/projects/mimic/releases/?package_id=13836
Httpdのホストするファイルは容量の許す限り追加することが出来ます。さらに多くのファイルをホストする場合は、mbedファイルシステムやSDカードなどの外部デバイスを利用できます。
機器情報を変更する
アイコンを右クリックしてみることが出来るUPnPの機器情報は、NetConfigの関数で変更することが出来ます。
- NetConfig::setFriendlyName - デバイスの表示名を指定できます。
- NetConfig::setUPnPUdn - デバイスIDを指定できます。IDはTimeBaseUUID(Version1)です。指定できるのはタイムフィールドとシーケンスフィールドです。NodeフィールドはmbedのMACアドレスが使われます。 IDの生成はhttp://www.famkruithof.net/uuid/uuidgenなどを利用してください。
- NetConfig::setUPnPManufactur - 製品製造者の情報やURLを指定できます。
- NetConfig::setUPnPModel - 製品のモデル情報や製品ページの情報を指定できます。
- NetConfig::setUPnPSerialNumber - シリアル番号を指定できます。
- NetConfig::setUPnPPresentationURL - プレゼンテーションページのURLを指定します。サンプルでは、プレゼンテーションページは/rom/index.htmlになっています。
Please log in to post comments.