ラズパイ ZERO WH(stretch)のHID化

## 動機
ネットにある情報は２年前の情報でOS(jessie)やカーネルも古く(4.4など)、新しい情報もなかった。
今のOS(stretch)とカーネル(4.19.56)で試した結果無事成功したので、バージョンが・・・で二の足を踏んでいる人の後押しになりたかった。

## 対象
* 新しいOSとカーネルでラズパイをHID化しマウス・キーボードの操作をしたいと目論んでいる人。

## 省いている説明
1. USB OTGでのラズパイのセットアップ
2. gitなど各ツールの細かい使い方

## 検証環境
* ラズパイ
    *  OS: strech

    ``` sh
    pi@pizerowh:dev$ lsb_release -a
    No LSB modules are available.
    Distributor ID: Raspbian
    Description:  Raspbian GNU/Linux 9.9 (stretch)
    Release:  9.9
    Codename: stretch
    ````

    *  Kernel: 4.19.56
    
    ``` sh
    pi@pizerowh:~$ uname -a
    Linux pizerowh 4.19.56+ #1242 Wed Jun 26 17:24:44 BST 
    2019 armv6l GNU/Linux
    ```

## 手順
* 以下のページを参考にセットアップを進める
  * https://qiita.com/hishi/items/8bdfd9d72fa8fe2e7573 for mac
  * https://qiita.com/Liesegang/items/dcdc669f80d1bf721c21 for windows
* 必要に応じてapt update & upgrade
* HID化

 * セットアップ時にセットした下記の設定を削除し、USB経由でのインターネット接続の設定を削除する。  
  
    ```
    // cmdline.txtから以下を削除。
    modules-load=dwc2,g_ether
    // これをしないと、デバイスは作成できても
    // 他の端末につないでも認識されない＆コマンドを送った時にコマンドがハングする。
    ```

  * 再起動
  * https://github.com/aidantwoods/RPi0w-keyboard.git をclone
  * source/home/pi/enableHid.shもしくはhid.shを実行。エラーなく終了すればOK。
  * /dev以下にhidg0が存在することを確認。
  
    ```
    pi@pizerowh:dev$ ls -l hidg0
    crw------- 1 root root 240, 0  6月 28 09:44 hidg0

    ※ カーネルバージョンを4.19.56にしてもデバイスが生えた事を確認。
    ```

 * 他の端末にUSBで接続しUSBデバイスとして認識している事を確認。自分の場合は別のラズパイに接続しlsusbで確認した。lsusbで表示されるのはhid.sh内の下記名称が表示される。

 ``` sh
 echo 0x0104 > idProduct # Multifunction Composite Gadget <- このコメントの文字。
 ```
* 後は、zeroから/dev/hidg0に向けてコマンドを送り、他の端末のテキストエディタやターミナルに文字が表示されればOK。

## マルチファンクション化
* 1USBに複数の機能をもたせるための設定を行うことも可能。
 * 複合機の接続は１本のケーブルだけど、コピーとスキャナなど複数の機能を提供しているとかのイメージ。
* やり方としては、複数のFunctionとReportDescriptorをセットすることで可能。

### 手順
* キーボードもしくはマウスのどちらかの設定をベースに両方のファンクションを合わせる。

```
#!/bin/bash
# Snippet from https://github.com/girst/hardpass-sendHID/blob/master/README.md . In which, the following notice was left:

# this is a stripped down version of https://github.com/ckuethe/usbarmory/wiki/USB-Gadgets - I don't claim any rights

modprobe libcomposite
cd /sys/kernel/config/usb_gadget/
mkdir -p g1
cd g1
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
echo "deadbeef01234567890" > strings/0x409/serialnumber
echo "blabla inc." > strings/0x409/manufacturer
echo "Generic USB mouse and Keyboard" > strings/0x409/product

# For Mouse
N="usb0"
mkdir -p functions/hid.$N
echo 2 > functions/hid.$N/protocol
echo 1 > functions/hid.$N/subclass
echo 8 > functions/hid.$N/report_length
echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x01\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x81\\x25\\x7f\\x75\\x08\\x95\\x02\\x81\\x06\\xc0\\xc0 > functions/hid.$N/report_desc


# For Keyboard
NN="usb1"
mkdir -p functions/hid.$NN
echo 1 > functions/hid.$NN/protocol
echo 1 > functions/hid.$NN/subclass
echo 8 > functions/hid.$NN/report_length
echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 >> functions/hid.$NN/report_desc

C=1
mkdir -p configs/c.$C/strings/0x409
echo "Config $C: ECM network" > configs/c.$C/strings/0x409/configuration
echo 250 > configs/c.$C/MaxPower

ln -s functions/hid.$N configs/c.$C/
ln -s functions/hid.$NN configs/c.$C/

ls /sys/class/udc > UDC
```

* 作成したshellを実行すると以下の設定になる。接続された側のlsusbで確認するとInterface Descriptorが２つ存在している。

```
pi@raspberrypi1:~ $ lsusb
Bus 001 Device 030: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
pi@raspberrypi1:~ $ lsusb -s001:030 -v

Bus 001 Device 030: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x1d6b Linux Foundation
  idProduct          0x0104 Multifunction Composite Gadget
  bcdDevice            1.00
  iManufacturer           1
  iProduct                2
  iSerial                 3
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           73
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          4
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              250mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              5
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.01
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      50
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               4
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      2 Mouse
      iInterface              7
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.01
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      63
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               4
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               4
pi@raspberrypi1:~ $
```

## 参考リンク
* セットアップ後のHID化時のhid.shでハマった時に発見した情報。 
 * https://github.com/aidantwoods/RPi0w-keyboard/issues/1#issuecomment-309244795
* ベースとなるコードはこのリポジトリを元にしています。
 * https://github.com/aidantwoods/RPi0w-keyboard