none
USB接続のHIDデバイスに特殊なUSBリクエストを行いたい RRS feed

  • 質問

  • 西脇です。

     

    USB接続のHIDデバイス(Sixaxis)に特殊なUSBリクエストを行うWindows XPで動作するアプリケーションを開発したいのですが、行き詰ってしまいました。
    プラットフォームSDK APIのSetupDiクラスAPIと、Windows標準HIDデバイスドライバへの操作APIを使用して、目的のデバイスをHIDデバイスとしてオープンすることはできたのですが、HIDデバイスとして制限された操作しかできないようでした。

    ※HidD_SetOutputReport等


    以下のような、USBデバイスリクエストを行いたいのです。

    USBプログラミングに関しては全く経験がありません。
    どのグループのAPIを使用するなどなにか取っ掛かりだけでも情報をいただけませんでしょうか。


     

    ○ USB-HIDデータ送信を有効にする

     

    以下のリクエストパケットを送信したいです。

     

    bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE
    bRequest = Clear_Feature
    wValue = 0x03f2
    wIndex = 0
    wLength = 17

     

    データ転送(デバイス→ホスト)する内容は17バイトです。
    中身は見ません。


     

    ○ ペアリングされたBluetooth機器を取得する

     

    以下のリクエストパケットを送信したいです。

     

    bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE
    bRequest = Clear_Feature
    wValue = 0x03f5
    wIndex = 0
    wLength = 8

     

    データ転送(デバイス→ホスト)する内容は8バイトです。
    {0x01, 0x00, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]}

    macはBluetooth機器のアドレスです。


     

    ○ Bluetooth機器とペアリングする

     

    以下のリクエストパケットを送信したいです。

     

    bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
    bRequest = Set_Configuration
    wValue = 0x03f5
    wIndex = 0
    wLength = 8

     

    データ転送(ホスト→デバイス)する内容は8バイトです。
    {0x01, 0x00, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]}

    macはBluetooth機器のアドレスです。


     

    Visual C#フォーラムへの投稿ですが、Visual Studio 2005 Professional Editionに含まれているものであれば、使用言語は問いません。

     

    どうかよろしくお願いします。

    2008年3月6日 1:58

すべての返信

  • 西脇です。

     

    とりあえず、LibUsb-Win32 + .NET USB Library #usblib (SharpUSBLib) を使用して、実装しました。

    LibUsb-Win32のインストールをせずにやる方法がないか、今も調査中です。

     

    Code Snippet

    using System;
    using System.Configuration;
    using System.Globalization;
    using System.Windows.Forms;

    using ICSharpCode.USBlib;

    namespace Sixaxis
    {
        public partial class Sixaxis : Form
        {
            const int SIXAXIS_VENDOR_ID = 0x054c;
            const int SIXAXIS_PRODUCT_ID = 0x0268;

            const int SIXAXIS_USB_MODE = 0x03f2;
            const int SIXAXIS_BT_ADDR = 0x03f5;

            Device device = null;
            byte[] mac = new byte[6];

            public Sixaxis()
            {
                InitializeComponent();
            }

            private void Sixaxis_Load(object sender, EventArgs e)
            {
                GetBluetoothAddress();
                device = GetSixaxisDevice();
                if (device != null)
                {
                    labelManufacturer.Text = device.Manufacturer;
                    labelProduct.Text = device.Product;
                    labelSerialNumber.Text = device.SerialNumber;
                }
            }

            private void Sixaxis_FormClosed(object sender, FormClosedEventArgs e)
            {
                if (device != null)
                {
                    device.Close();
                }
            }

            private void button1_Click(object sender, EventArgs e)
            {
                int bRequestType = 161;
                int bRequest = 1;
                int wValue = SIXAXIS_USB_MODE;
                byte[] pData = new byte[17];

                device.SendControlMessage(bRequestType, bRequest, wValue, pData);
                MessageBox.Show("set USB-mode.", "Successful", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            private void button2_Click(object sender, EventArgs e)
            {
                int bRequestType = 161;
                int bRequest = 1;
                int wValue = SIXAXIS_BT_ADDR;
                byte[] buf = new byte[8];

                device.SendControlMessage(bRequestType, bRequest, wValue, buf);

                object[] args = new object[6];
                args[0] = buf[2];
                args[1] = buf[3];
                args[2] = buf[4];
                args[3] = buf[5];
                args[4] = buf[6];
                args[5] = buf[7];

                string text = String.Format("current bluetooth address: {0:x02}:{1:x02}:{2:x02}:{3:x02}:{4:x02}:{5:x02}", args);
                MessageBox.Show(text, "Successful", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            private void button3_Click(object sender, EventArgs e)
            {
                int bRequestType = 33;
                int bRequest = 9;
                int wValue = SIXAXIS_BT_ADDR;
                byte[] buf = new byte[8];
                buf[0] = 0x01;
                buf[1] = 0x00;
                buf[2] = mac[0];
                buf[3] = mac[1];
                buf[4] = mac[2];
                buf[5] = mac[3];
                buf[6] = mac[4];
                buf[7] = mac[5];

                device.SendControlMessage(bRequestType, bRequest, wValue, buf);
                MessageBox.Show("set bluetooth address.", "Successful", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            private Device GetSixaxisDevice()
            {
                foreach (Bus bus in Bus.Busses)
                {
                    foreach (Descriptor descriptor in bus.Descriptors)
                    {
                        if (descriptor.VendorId == SIXAXIS_VENDOR_ID &&
                            descriptor.ProductId == SIXAXIS_PRODUCT_ID)
                        {
                            return descriptor.OpenDevice();
                        }
                    }
                }

                MessageBox.Show("SIXAXIS not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                button1.Enabled = false;
                button2.Enabled = false;
                button3.Enabled = false;
                return null;
            }

            private void GetBluetoothAddress()
            {
                try
                {
                    char[] separator = { '-', ':' };
                    string[] array = ConfigurationManager.AppSettings["BD_ADDR"].Split(separator);

                    mac[0] = byte.Parse(array[0], NumberStyles.HexNumber);
                    mac[1] = byte.Parse(array[1], NumberStyles.HexNumber);
                    mac[2] = byte.Parse(array[2], NumberStyles.HexNumber);
                    mac[3] = byte.Parse(array[3], NumberStyles.HexNumber);
                    mac[4] = byte.Parse(array[4], NumberStyles.HexNumber);
                    mac[5] = byte.Parse(array[5], NumberStyles.HexNumber);
                }
                catch (Exception)
                {
                    MessageBox.Show("BD_ADDR format error.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    button3.Enabled = false;
                }
            }
        }
    }

    2008年5月16日 4:45