WPFxUPnP その9

次にデバイスクラスの作成を行います。
UPnPバイスはIUPnPDeviceControlインターフェースを実装する必要があります。

using UPnPHostLib;

/// <summary>
/// UPnPライトデバイス
/// </summary>
[ComVisible(true)]
public class DimmableLightDevice : IUPnPDeviceControl
{
    /// <summary>
    /// UPnPライトデバイスディスクリプタパス
    /// </summary>
    readonly string deviceDecXMLPath = @".\web\DimmableLight.xml";

    /// <summary>
    /// SwitchPowerサービス
    /// </summary>
    public SwitchPower SwitchPowerService { get; private set; }

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public DimmableLightDevice()
    {
        SwitchPowerService = new SwitchPower();
    }

    #region IUPnPDeviceControl
    /// <summary>
    /// サービスオブジェクトを取得する
    /// </summary>
    public dynamic GetServiceObject(string bstrUDN, string bstrServiceId)
    {
        if (bstrServiceId == SwitchPowerService.ServiceName)
        {
            return SwitchPowerService;
        }
        return null;
    }

    /// <summary>
    /// UPnPデバイス初期化
    /// </summary>
    public void Initialize(string bstrXMLDesc, string bstrDeviceIdentifier, string bstrInitString)
    {
    }
    #endregion

    #region UPnP
    /// <summary>
    /// デバイスID
    /// </summary>
    private string m_deviceId = string.Empty;

    /// <summary>
    /// UPnPデバイス登録I/F
    /// </summary>
    private IUPnPRegistrar m_registr = null;

    /// <summary>
    /// 登録
    /// </summary>
    public bool Register()
    {
        bool bRet = true;
        try
        {
            Guid id = new Guid("204810B9-73B2-11D4-BF42-00B0D0118B56");

            // IUPnPRegistrarインスタンス取得
            m_registr = (IUPnPRegistrar)(Activator.CreateInstance(Type.GetTypeFromCLSID(id)));

            string descDoc = File.ReadAllText(deviceDecXMLPath);

            m_deviceId = m_registr.RegisterRunningDevice(descDoc,
                                                        this,
                                                        "Dimmable Light Device",
                                                        Directory.GetCurrentDirectory() + @"\web",
                                                        1800);
            if (string.IsNullOrEmpty(m_deviceId))
            {
                throw new ApplicationException("UPnPデバイスの登録に失敗しました。");
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "エラー", MessageBoxButton.OK, MessageBoxImage.Error);
            bRet = false;
        }
        return bRet;
    }

    /// <summary>
    /// 登録解除
    /// </summary>
    public void UnRegister()
    {
        if (!string.IsNullOrEmpty(m_deviceId))
        {
            m_registr.UnregisterDevice(m_deviceId, 1);
            m_deviceId = string.Empty;
        }
        m_registr = null;
    }
    #endregion
}

UPnPのデバイスはIUPnPRegistrar.RegisterRunningDeviceを使って登録します。

登録すると、IUPnPDeviceControlインターフェースのInitializeが呼び出されます。
本来は、このメソッドで、デバイス単位にSwitchPowerサービスのオブジェクトを生成すべきですが、
今回はサボって、デバイスオブジェクト生成と同時に生成しています。

UPnPクライアント(プレゼンテーションのHTMLを利用する場合はブラウザ)からデバイスを利用する際に、GetServiceObjectが呼び出され、
クライアントが必要とするサービスのオブジェクトを返却します。
今回はサボっているので、デバイスオブジェクトが1つなので、それを返却します。
本来はUDNにあったサービスオブジェクトを返却すべきです。

一通り、デバイスとして動作するまでのパーツはそろいました。
次回は、組み合わせて動作(OSに認識)させるまで、行きたいと思います。