2016年1月26日火曜日

LinuxでUSB webcamのパケットを円満にモニタする方法メモ (tshark)

logicoolのwebcam C500を、Linuxから制御したい.

Linuxのlibusb/libuvc/opencvを利用して制御するのはネットの情報を引用すれば簡単にできるのだが、ライブラリ関数をcallしてスレッドを起動して完成とはできない大人の事情ってのがある.なぜなら、EZ-USBでC500を制御するのが最終目的なので、Linuxでwebcamを制御すると云っても、極論するならば直接的にlinuxのioctl()を叩きまくってベタベタに制御したいのである.

そのためには、USB packetレベルでどんな通信をしてるんだ?という情報を知るのが先である.

そのような事情にて、LinuxにてUSB packetをモニタ&記録したい.やってみたところコマンド一発でOKOKではなかったので、やり方をメモしておこうと思ふ.

使うツールはtsharkである.windowsのアプリのwiresharkのCUI版である.

「USB パケット モニタ」でググると、なぜかwiresharkがたくさんヒットする.wiresharkはLANのパケットだろ!と検索結果に文句を言いつつ、よく読んでみると、
wireshrakはUSBパケットもモニタできる
最初はうそーっと思いましたよ.

【環境】
Kona-Linux 3.0 64bit (ubuntu系です)
CPU atom 1.8GHz

【実行手順】
わたしの場合、既にtsharkはinstall済みだったが、たぶんこのコマンドでinstallしたんだったと思う.
  apt-get install tshark

つぎに、これは不要なのかもしれないのだが、pcapをinstallした.tsharkをinstallした時点でpcapがinstallされていなかった様子なので、たぶん不要なのだろうとは思いつつ、installしちゃった.読者におかれましては、tsharkが動かなかったら一縷の望みを託してpcapをinstallするという手順でもよろしかろうと思う.
    apt-get install libpcap-dev

これでいきなりtsrarkを起動してもUSBパケットをモニタできない.debugfsをマウントしないとUSBをモニタできない.この2つのコマンドには順番に依存関係があるのかもしれないのでダメだったら順番を入れ替えてトライしてちょうだい.
    modprobe usbmon
    mount -t debugfs none /sys/kernel/debug
ここでやっているのは、USBデバイスを、/sys/kernel/debug/usb/usbmon に表示させること.
tsharkは、usbmonにアクセスするようだ.

つぎに、多数在るUSBデバイスのうちwebcamはどれかを調べる.kona-linux3.0では最初からlsusbはinstallされていると思う.
    lsusb
わたしの環境ではlsusbで表示された1行目がwebcamである.このBus=003が重要.(なぜか名称がB500)
 Bus 003 Device 007: ID 046d:0807 Logitech, Inc. Webcam B500
さらに調べる.
  cat /sys/kernel/debug/usb/devices
たくさんの表示が出て画面がスクロールするだろう.その中から、videoという文字を含むUSBデバイスを探すと、わたしの環境では、これだった.
  T:  Bus=03 Lev=01 Prnt=01 Port=06 Cnt=01 Dev#=  7 Spd=480  MxCh= 0
ここでもやはりBus=03が表示された.
webcamは3番であるらしい.

ようやくtsharkの出番である.
   tshark -D
と打つと、こんな表示が出る.
 1. eth0
 2. any
 3. lo (Loopback)
 4. nflog
 5. nfqueue
 6. usbmon1
 7. usbmon2
 8. usbmon3
 9. usbmon4
 10. usbmon5
この中のusbmon3こそが、USBパケットモニタしたいwebcamなのだとわかる.

最後に、このコマンドで、webcamに関係するUSBパケットが表示される.
   tshark -i usbmon3 -V -x

-----
追記: tsharkが表示する内容について
USBパケットはACKだとか様々なパケットが飛び交う.しかしtsharkが表示するのは、基本的にDATAの部分だけであるようだ.基本的にというのはDATA以外にもヘッダ情報が追加されて表示される.HEADDER+DATAを合わせて、URBという構造体を形成しており、tsharkが表示するのはURBだと思って良さそうだ.URBの構造体ソースが見つからなかったので想像であるが、00-3F番地までがURBヘッダで、40番地以降がデータであるらしい.データが無い場合もある.

以下は、ディスクリプタ要求と、ディスクリプタ返信の2例を記す.

#windows版wiresharkで同様のパケットを採取したところ、windowsのURBヘッダは28バイトと短く、格納されているデータが微妙に異なる.またwindows版wiresharkではURB pseudo headerという理に叶ったネーミングになっている. (なお、40番地以降のデータはLinuxでもwindowsでも同じであるのは云うまでもない)

-----
追記:  Linux wireshark 1.12.1 → wireshark 2.0 にupgradeする方法
kona-linuxでwiresharkをinstallするにはこのコマンドでできます.
apt-get install wireshark
ところがこれでinstallされるのは、wireshark 1.12.1 になります.

PCだとwireshark2.0を簡単ポンでinstallできちゃうんですが、Linuxがwireshark1.12.1だと両者で表示結果が微妙に異なるので、Linuxも2.0にしたいなぁと思いました.

Linux版wireshark2.0の導入は次のようにしました.

wireshark 2.0をDLするのはここ.
http://linux.softpedia.com/get/Internet/HTTP-WWW-/Ethereal-1961.shtml

DLファイルを解凍します.
tar jxvf wireshark-2.0.1.tar.bz2

configureを通すのに必要なソフトをinstallする必要がありました.
apt-get install bison flex libgtk-3-dev  libqt4-dev  libpcap-dev

コンパイルします.
cd wireshark-2.0.1
./configure
make
make install
これでwireshark,tsharkが動くはずのですがなぜか/usr/local/bin/wiresharkまたはtsharkが動きません.作業ディレクトリのwiresharkまたはtsharkなら動きます.原因不明.


【ディスクリプタ要求パケット】
Frame 1: 64 bytes on wire (512 bits), 64 bytes captured (512 bits) on interface 0
           中略
USB URB
    URB id: 0xffff880127ffff40
    URB type: URB_SUBMIT ('S')
    URB transfer type: URB_CONTROL (0x02)
    Endpoint: 0x80, Direction: IN
        1... .... = Direction: IN (1)
        .000 0000 = Endpoint value: 0
    Device: 7
    URB bus id: 3
    Device setup request: relevant (0)
    Data: not present ('<')
    URB sec: 1453786215    0x0000000056a70467
    URB usec: 729960    0x000b2368
    URB status: Operation now in progress (-EINPROGRESS) (-115)
    URB length [bytes]: 40
    Data length [bytes]: 0
    Interval: 0
    Start frame: 0
    Copy of Transfer Flags: 0x00000200
    Number of ISO descriptors: 0
URB setup
    bmRequestType: 0x80
        1... .... = Direction: Device-to-host
        .00. .... = Type: Standard (0x00)
        ...0 0000 = Recipient: Device (0x00)
    bRequest: GET DESCRIPTOR (6)
    Descriptor Index: 0x00
    bDescriptorType: 0x01
    Language Id: no language specified (0x0000)
    wLength: 40

0000  40 ff ff 27 01 88 ff ff 53 02 80 07 03 00 00 3c  header
0010  67 04 a7 56 00 00 00 00 68 23 0b 00 8d ff ff ff  header
0020  28 00 00 00 00 00 00 00 80 06 00 01 00 00 28 00  setup
0030  00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00  header

ここでURB setupというのはこれのようです↓



【ディスクリプタ返信パケット】
Frame 2: 82 bytes on wire (656 bits), 82 bytes captured (656 bits) on interface 0
                 中略
USB URB
    URB id: 0xffff880127ffff40
    URB type: URB_COMPLETE ('C')
    URB transfer type: URB_CONTROL (0x02)
    Endpoint: 0x80, Direction: IN
        1... .... = Direction: IN (1)
        .000 0000 = Endpoint value: 0
    Device: 7
    URB bus id: 3
    Device setup request: not relevant ('-')
    Data: present (0)
    URB sec: 1453786215    0x0000000056a70467
    URB usec: 733103    0x0b2faf
    URB status: Success (0)
    URB length [bytes]: 18
    Data length [bytes]: 18
    [Request in: 1]
    [Time from request: 0.003143000 seconds]
    Unused Setup Header
    Interval: 0
    Start frame: 0
    Copy of Transfer Flags: 0x00000200
    Number of ISO descriptors: 0
DEVICE DESCRIPTOR
    bLength: 18
    bDescriptorType: 0x01 (DEVICE)
    bcdUSB: 0x0200
    bDeviceClass: Miscellaneous (0xef)
    bDeviceSubClass: 2
    bDeviceProtocol: 1 (Interface Association Descriptor)
    bMaxPacketSize0: 64
    idVendor: Logitech, Inc. (0x046d)
    idProduct: Webcam B500 (0x0807)
    bcdDevice: 0x0009
    iManufacturer: 0
    iProduct: 0
    iSerialNumber: 2
    bNumConfigurations: 1

0000  40 ff ff 27 01 88 ff ff 43 02 80 07 03 00 2d 00  header
0010  67 04 a7 56 00 00 00 00 af 2f 0b 00 00 00 00 00  header
0020  12 00 00 00 12 00 00 00 00 00 00 00 00 00 00 00  header
0030  00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00  header
0040  12 01 00 02 ef 02 01 40 6d 04 07 08 09 00 00 00  descripter
0050  02 01

↑40番地以降が、返信されたデバイスディスクリプタ.

かしこ


人気ブログランキングへ

3 件のコメント:

  1. コンデジに拡大鏡顕微鏡望遠鏡を繋いでもうまく写せません。
    chdk.wikia.com/wiki/CHDK を入れると違う。
    しかし画素数多めの簡単カメラ(webCAM)などですと結構うまく写ります。

    返信削除
  2. 先人の軌跡
    ttp://homepage2.nifty.com/3D-eyes/3D-eyes/camera/stereo-camera.html

    返信削除
    返信
    1. 単眼で左右の画像を撮るみたいですね.

      削除