tmytのらくがき

個人の日記レベルです

Surface Dialを2個接続してSOUND VOLTEXごっこした人へ

Surface Dialを2個以上接続していたとしても、正規のAPIからアクセスするといくつあっても1個にしか見えないのは周知の事実です。じゃぁどうにかして、2個認識できないのかなぁ…ということでやってみました。

TL;DR

  • 通常のAPIからは1個しかみえないが、HIDデバイスなので直接読めば読める
  • VID:045E, PID: 091B, UsagePage: 0001, Usage: 000Eを読めば生データ見える
  • 生データの2バイト目の下位1bitが押し下げフラグ、3バイト目が回転量(signed)、4バイト目が回転方向(00:右、FF:左)

バイス構成

f:id:tmyt:20161127132805p:plain

これを見ると、HID over GATTで5種類のデバイスが見えていて、UsagePage, Usageは次の通り

UsagePage Usage
0001 0080
0001 000E
0001 0072
FF07 0070
FF07 0071

一番上はWinRTでブロックされているUsageなので今回は省略。ほかの4つは特にWinRTでブロックされてない(!!)のでアクセスしてみたところ、返事が返ってきたのは2個目のやつでした。

とりあえずアクセス

public MainPage()
{
    this.InitializeComponent();

    Loaded += async (sender, args) =>
    {
        var d2 = await GetAsync(0x0001, 0x000E);
        d2.InputReportReceived += D2_InputReportReceived;
    };
}

private void D2_InputReportReceived(HidDevice sender, HidInputReportReceivedEventArgs args)
{
    var dump = string.Join(" ", args.Report.Data.ToArray().Select(b => $"{b:X2}"));
    Debug.WriteLine($"D2: {dump}");
}

async Task<HidDevice> GetAsync(ushort up, ushort uid)
{
    var str = HidDevice.GetDeviceSelector(up, uid);//, 0x045E, 0x091B);
    var devices = (await DeviceInformation.FindAllAsync(str)).ToArray();
    return await HidDevice.FromIdAsync(devices[0].Id, FileAccessMode.Read);
}

こんなの書いて、ダイアルを回したり押したりするとこんなダンプがデバッグ出力で得られます。

D2: 01 02 02 00 0A 0B 0C 0D 3A
D2: 01 02 03 00 0A 0B 0C 0D 3A
D2: 01 02 02 00 0A 0B 0C 0D 3A
D2: 01 02 FF FF 0A 0B 0C 0D 3A
D2: 01 02 FF FF 0A 0B 0C 0D 3A
D2: 01 02 FE FF 0A 0B 0C 0D 3A
D2: 01 02 FF FF 0A 0B 0C 0D 3A
D2: 01 02 FD FF 0A 0B 0C 0D 3A
D2: 01 02 FD FF 0A 0B 0C 0D 3A
D2: 01 02 FD FF 0A 0B 0C 0D 3A
D2: 01 02 FC FF 0A 0B 0C 0D 3A
D2: 01 02 FB FF 0A 0B 0C 0D 3A

解析結果

このバイナリの中身をよく見てるとだいたいこんな構造みたい。

struct Report{
  byte One;
  byte Flags;
  sbyte Degree;
  byte Orientation;
  byte[6] Nazo;
}

2バイト目のFlagsとして名前を付けてみたところは、ビットフィールドになっているようでそれぞれ次の意味っぽい。

ビット 意味
1ビット目 押し下げ状態。1で押してる状態
2ビット目 回転中?

3バイト目は符号付の値のようで、右回転で正の値、左回転で負の値になってる感じ。WinRTのデフォルトより元気で1度ごとにレポートがきます。

4バイト目は回転方向で、右回転なら00、左回転ならFFが入っています。

で、のこった6バイトはよくわからん。

まとめ

SOUND VOLTEXごっこできそうですね!