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.
