ZaurusでBluetoothを使う(その1) 最終更新日: 2003/09/18 00:00

目次
IbCard購入
BlueZのインストール
OpenOBEXのコンパイル
/インストール
OBEXテストアプリを
コンパイル
OBEX送信のテスト
OBEX受信のテスト
Macでの送受信
現状と今後の展望
関連リンク

関連ページ
Bluetoothを使う(2)
OBEX送受信活用編
作成パッケージの
ダウンロード

その他
Zaurus関連トップ
掲示板

IbCard購入

IbCard(バルク品)を入手した。
AKIBA PC Hotlineで若松でバルク品が2,980円と載っていたのをみて、会社の帰りに寄って購入。 CFのbluetoothアダプタは普通に買うと一万弱するので、なかなかお得。

これがパッケージ。いかにもバルク。
付属しているCD-Rには、WindowsとPocket PCのドライバが入っているものと思われる(実は中を見ていない)。
左にあるのは、別途購入した中古のUSB Bluetoothアダプタ(ハギワラシスコム製)。

これらをPC〜Zaurus間のお手軽なファイル交換用に使えないかというのが今回の目標。
(Docomo PHSも所有しているが、633S(Bluetooth内蔵機器)ではない。こちらもそのうち入手して試してみたいところ)

買ってから調べてみてわかったのは、これは「Bluetooth 1.0B」準拠のカードらしいということ。 今現在売っているIbCardは、1.1準拠らしい。 だから安かったのか....まあ、そりゃそうだよな。
で、USBアダプタの方は1.1準拠。USBアダプタの説明書を読むと、

「Bluetooth 1.0Bの機器とは互換性はありません」

と書いてある。
....。 まあ、とりあえずやってみることにする。

BlueZのインストール

BlueZは、linuxのオフィシャルなBluetoothプロトコル実装。
本家BlueZのページにはSL-5500用のパッケージが用意されているが、これはkernelが異なるため、 そのままではSL-C7x0などでは使えない。 こちらこちらで対応したものが配布されている。
今回は、最新ソースをビルドしたこちらのパッケージを使わせて頂いた。

bluez-kernel_2.4.18.mh7-1_arm.ipk
bluez-zaurus_2.3.0519-1_arm.ipk
bluepin_0.0.1-1_arm.ipk

をダウンロードしてインストールする。

パッケージをダウンロードしてきたページの説明を参考にして設定を行う。
ついでに/etc/hcid.confも修正しておく。といっても、名称を変更するくらい。 デバイスクラスもそのままだとデスクトップコンピュータ扱いになるので、 Handheld PC/PDA [clam shell](0x110)かPalm sized PC/PDA(0x114)にしておいた方が気分的には良いかもしれない。

# cat /etc/bluetooth/hcid.conf
        :
        :
# Default settings for HCI devices
device {
        # Local device name
        #   %d - device id
        #   %h - host name
        name "%h@BlueZ (%d)";

        # Local device class
        class 0x110;
# cp /etc/modules.conf.add /etc/modules.conf
# depmod -a
# /etc/make_dev.bluez.sh
# /etc/rc.d/init.d/pcmcia restart
# /etc/rc.d/init.d/bluetooth start

bluepinのパッケージには、bluepinqtというQT上でpinが入力できる有り難いツールが付いているが、 今回はとりあえずのテストなので、bluepinの該当行はコメントアウトして単純にpinをechoするようにしておく。

# cat /usr/local/bin/bluepin
#!/bin/sh
#/usr/bin/sudo -u zaurus /usr/local/bin/bluepinqt $1 $2 $3 $4
echo "PIN:xxxx"

設定が完了したらIbCardをスロットに挿入し、認識できているかどうかを確認してみる。

# cardctl ident
Socket 0:
  product info: "WSS", "LSE039"
  manfid: 0x0264, 0x0008
  function: 6 (network)
Socket 1:
  no product info available
# cat /var/lib/pcmcia/stab
Socket 0: LSE039 Bluetooth Compact Flash Card
0       bluetooth       bluecard_cs     0       hci0
Socket 1: empty

hci0というのが、Bluetooth用のデバイス。 大丈夫そうなので、hci0をアクティブにして状態を確認する。

# hciconfig hci0 up
# hciconfig
hci0: Type: PCCARD
      BD Address: xx:xx:xx:xx:xx:xx ACL MTU: 672:10  SCO MTU: 64:0
      UP RUNNING PSCAN ISCAN
      RX bytes:112 acl:0 sco:0 events:12 errors:0
      TX bytes:313 acl:0 sco:0 commands:12 errors:0
# hcitool dev
Devices:
        hci0    xx:xx:xx:xx:xx:xx

xx:xx:xx:xx:xx:xx [Bluetoothアドレス] の部分には、実際には16進数のコードが入る)。

USB BluetoothアダプタをセットアップしたWindows側から、添付のツールを使ってスキャンして確認してみる。

無事認識されているようだ。

Zaurus側からも確認してみる。

# hcitool scan
Scanning ...
        xx:xx:xx:xx:xx:xx       GA-8PE667-01
					

こちらも問題なさそう。

OpenOBEXのコンパイル/インストール

手軽なファイル交換に使えないかというのが今回の目標なので、OBEX(Object Exchange)によるファイル交換を試してみる。 OBEXというのは、赤外線通信などで使われるファイル交換の手順のようだが、これはBluetoothでも使えるようになっているそうだ。

実装としては、OpenOBEXというのがあって、 こちらでSL-Zaurus用のパッケージも公開されているのだが、 これはどうやら赤外線で使うようmakeされているようにみえる(そもそも赤外線通信活用のため、作成されたようだし)。 今回はBluetoothで使えなければ意味がないので、ソースを入手してBluetoothを使えるように自分でコンパイルする。 コンパイルはdev_img-1.3を使い、SDカード上にソースを展開してセルフコンパイルすることにする。

とりあえず、OpenOBEXのホームページからソースファイルを取得する。

http://openobex.sourceforge.net/download.html

ここから、openobex-1.0.0.tar.gzをダウンロードする。

これを展開して、そのままconfigureを実行すると、

# ./configure
checking host system type... arm-unknown-linux-gnu
checking target system type... arm-unknown-linux-gnu
       :
       :
checking for IrDA support... yes
checking for Bluetooth support... no
       :
       :

となってしまい、Bluetooth用のMakefileが作成されない。

これは、Bluetooth用のインクルードファイルがないため。上記のBlueZのパッケージでは 当然そこまでインストールはしてくれないので、自分でBlueZのソースをダウンロードして includeファイルのみを取り出しておく(bluez-libs-2.4.tar.gzにincludeファイルが含まれている)。
といっても、dev_img-1.3はcramfsのため、dev_img-1.3のinclude内には入れることが出来ない。 gccでincludeファイルが読めるようにしておけばconfigure, makeは通るようなので、 とりあえず適当なディレクトリにコピーして、そこをgccで認識するように環境変数で 指定してやることにする。

# cd /mnt/work
# gzip -cd openobex-1.0.0.tar.gz | tar xf -
# gzip -cd bluez-libs-2.4.tar.gz | tar xf -
# cd openobex-1.0.0
# mkdir src/bluetooth
# cp ../bluez-libs-2.4/include/* src/bluetooth/
# export CPPFLAGS=-I/mnt/work/openobex-1.0.0/src/
# ./configure

# make

インストールは素直にmake installするとincludeファイル等もインストールしようとするため、 個別にインストール指定した。
make install-binSCRIPTSでは、openobex-configというスクリプトがインストールされる。 これは後述するopenobex-appsが必要としているようなのでインストールした。
make install-libLTLIBRARIESで、/usr/local/libにOpenOBEXのライブラリファイルがインストールされる。

# make install-binSCRIPTS
# cd src
# make install-libLTLIBRARIES

しかし、前述したページにある ipkgでインストールされるファイルと比べてみると

openobex_1.0.0-1_arm.ipk:
root     root           24 Jun 29 23:53 libopenobex-1.0.so.0
root     root        28888 Jun 29 23:50 libopenobex-1.0.so.0.0.0
root     root        40972 Jun 29 23:49 libopenobex.a
root     root          738 Jun 29 23:51 libopenobex.lai
root     root           24 Jun 29 23:54 libopenobex.so

今回コンパイルしたもの:
root     root           24 Sep 11 01:27 libopenobex-1.0.so.0
root     root        30060 Sep 11 01:27 libopenobex-1.0.so.0.0.0
root     root        43012 Sep 11 01:27 libopenobex.a
root     root          738 Sep 11 01:27 libopenobex.la
root     root           24 Sep 11 01:27 libopenobex.so
という違いが出ている。 なぜかはよくわからないが(というか.la, laiの違いさえわからない....)、 とりあえず気にせず先に進むことにする。

OBEXテストアプリをコンパイル

ライブラリがインストールできたので、次はアプリケーション。 OpenOBEXのページにテスト用のサンプルアプリケーションがあるので、それをコンパイルしてみる。
OpenOBEXの時と同様、configureでbluetoothを認識させるにはBluezのincludeが必要。 それに加えてOpenOBEXのincludeファイルも必要となる。 これらについては、OpenOBEXのコンパイルと同様の方法で解決する。
openobex-configも必要だが、これはOpenOBEXインストール時に入れてあるので大丈夫。

# cd /mnt/work
# gzip -cd openobex-apps-1.0.0.tar.gz | tar xf -
# cd openobex-apps-1.0.0
# mkdir src/bluetooth
# mkdir src/obex
# cp ../bluez-libs-2.4/include/* src/bluetooth/
# cp ../openobex-1.0.0/src/*.h src/obex/
# export CPPFLAGS=-I/mnt/work/openobex-apps-1.0.0/src/
# ./configure
# make

とりあえずインストールはせずに、src内に出来た実行ファイルで試してみることにする。 obex_testというのが対話式のOBEXテストツールで、これが接続テストに使えるようだ。
説明ファイルがないので、ソースをみてオプションやコマンドを調べる。

Bluetooth用に使うには、obex_test -b [アドレス] [チャンネル] でいいようだ。
コマンドは
cクライアントモードで接続
pファイル送信(put)
xファイル送信(push)
gファイル受信(get)
d接続解除
sサーバーモードへ移行(待受状態へ)
q終了
といった感じらしい。pとxの違いがよくわからないが....。
基本的にファイル送受信待受状態になっているのがサーバーで、 そこにクライアントとして接続してファイル送受信することになるようだ。

OBEX送信(Zaurus→Windows)のテスト

まず、Zaurus→Windowsへのファイル送信を試してみる。
相手先のチャンネルを知る必要があるが、これはBlueZのsdptoolで調べられる。

# sdptool search OPUSH
Inquiring ...
Searching for OPUSH on xx:xx:xx:xx:xx:xx ...
Service Name: OBEX Object Push
Service RecHandle: 0x10000
Service Class ID List:
  "Obex Object Push" (0x1105)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel/Port: 1
  "OBEX" (0x0008)
Language Base Atrr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100

OPUSHというのは、サービスの指定でOBEX Object Pushのこと。 この場合、OBEX Object Pushのサービスを提供している端末を検索して表示することになる。
Channel/Portとあるのがチャンネルで、この場合は1となる。

忘れてはいけないのが、ライブラリパスの設定。
obex_testは、当然OpenOBEXのライブラリを使うが、インストールされた /usr/local/libには標準ではライブラリパスが通っていないため、このままではobex_testは起動できない。

# cd /src
# ./obex_test -b xx:xx:xx:xx:xx:xx 1
./obex_test: error while loading shared libraries:
 libopenobex-1.0.so.0: cannot load shared object file:
 No such file or directory

環境変数にパスを追加しておく。

# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

で、起動。

# ./obex_test -b xx:xx:xx:xx:xx:xx 1
Using Bluetooth RFCOMM transport
OBEX Interactive test client/server.
> c
Connect OK!
Version: 0x10. Flags: 0x00
> p
PUT file (local, remote)> /tmp/test.txt test.txt
name=/tmp/test.txt, size=254
Going to send 254 bytes
PUT successful!
> d
Disconnect done!
> q
#

この際、Windows側では受信の際に以下のような確認ダイアログが出た。
(pinの認証はあらかじめ済ませておいた)

この後、受信フォルダをみたら無事ファイルが転送されていた。 めでたしめでたし。

ただし、xについても同様に試してみたが、こちらはうまくいかなかった。

> x
PUSH filename> /tmp/test.txt
name=/tmp/test.txt, size=448
Going to send /tmp/test.txt(test.txt), 448 bytes
Segmentation fault
#

のように、Segmentation faultが起こる。 とりあえず、pでは送信できたので原因は追及していない。

OBEX受信(Windows→Zaurus)のテスト

次にWindows→Zaurusへのファイル転送を試してみる。
これも送信の時と同様に、obex_testで接続してg(et)すればよいように思えるが、これはうまくいかない。

# ./obex_test -b xx:xx:xx:xx:xx:xx 1
Using Bluetooth RFCOMM transport
OBEX Interactive test client/server.
> c
Connect OK!
Version: 0x10. Flags: 0x00
> g
GET File> test.txt
GET failed 0x44!
>

と、このようになる。
考えられるのは、

  • ファイル名の指定がおかしい
  • なんらかのプロトコル非互換がある
  • そもそもWindows側にサーバーモードでのファイル送信処理が実装されていない
だが、3番目の可能性が高いような気がする。 赤外線などでもファイル交換の際の能動的な開始のアクションは送信側が取る場合が殆どなわけだし。

ということで、Zaurus側をサーバーモードにして、Windows側からファイル送信要求をする形で試してみる。
この場合には、Zaurus側がOBEX Object Pushサービスを受け付けるように他機種から見えるようにする必要がある (最初の状態では、他機種からはZaurusは何のサービスも提供していないように見えている)。
これはsdptoolを利用して、そのサービス応答を返すように設定してやれば良い。

# sdpd
# sdptool add --channel=2 OPUSH
OBEX Object Push service registered
#

この状態で、obex_testを起動してサーバーモードに移行する (この場合は、チャンネル指定はこちらのチャンネルを指定する必要があるようだ)

# ./obex_test -b xx:xx:xx:xx:xx:xx 2
Using Bluetooth RFCOMM transport
OBEX Interactive test client/server.
> s

ここまでの状態にしたら、Windows側でファイル送信の指示を出す。
すると、

connect_server()
Server request finished!
server_done() Command (00) has now finished
Made some progress...
Made some progress...
put_server()
put_server() Found name
put_server() Skipped header c3
put_server() Found body
Filename = test2.txt
Wrote /tmp/test2.txt (2064 bytes)
Server request finished!
server_done() Command (02) has now finished
We got a disconnect-request
Server request finished!
Disconnect done!
> q
#

このようになって、ファイル受信が成功した。

Macとの送受信

購入したUSB Bluetoothモジュールのパッケージ等には、Windows 98/Me/2000/XP用と書いてあり、 Macの事については全く触れられていない。
が、そんな事は気にせず、Powerbook G4 400 (MacOS X 10.2)のUSBコネクタに挿してみる。
....あっさり認識。

デバイス検索すると、ちゃんとZaurus側が認識される。

逆も問題なし。

# hcitool scan
Scanning ...
        xx:xx:xx:xx:xx:xx       Tom's PowerBook G4 400

sdptoolでみると、

# sdptool browse
Inquiring ...
Browsing xx:xx:xx:xx:xx:xx ...
Service Name: OBEX Object Push
Service RecHandle: 0x10002
Service Class ID List:
  "Obex Object Push" (0x1105)
Protocol Descriptor List:
  "Error: " (0x00000100)
  "RFCOMM" (0x0003)
    Channel/Port: 10
  "OBEX" (0x0008)
Language Base Atrr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Obex Object Push" (0x1105)
    Version: 0x0100

Service Name: OBEX File Transfer
Service RecHandle: 0x10003
Service Class ID List:
  "Obex File Transfer" (0x1106)
Protocol Descriptor List:
  "Error: " (0x00000100)
  "RFCOMM" (0x0003)
    Channel/Port: 15
  "OBEX" (0x0008)
Language Base Atrr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Obex File Transfer" (0x1106)
    Version: 0x0100

Service Name: Bluetooth-PDA-Sync
Service RecHandle: 0x10004
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel/Port: 3
Language Base Atrr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Serial Port" (0x1101)
    Version: 0x0100

OBEXとシリアル接続をサポートしているようだ。
OBEX Object Pushは、おそらく付属の「Bluetoothファイル交換」で使うのだろう。
obex_testとのファイル交換を試してみる。
(以下、画面キャプチャとログの内容が一致してない部分有)

[Zaurus→Mac]
# ./obex_test -b xx:xx:xx:xx:xx:xx 10
Using Bluetooth RFCOMM transport
OBEX Interactive test client/server.
> c
Connect OK!
Version: 0x10. Flags: 0x00
> p
PUT file (local, remote)> /mnt/card/dev_img-1.3 test.bin
name=/mnt/card/dev_img-1.3, size=16072704
Going to send 16072704 bytes
PUT successful!
> d
Disconnect done!
> q
#

[Mac→Zaurus]
# ./obex_test -b xx:xx:xx:xx:xx:xx 2
Using Bluetooth RFCOMM transport
OBEX Interactive test client/server.
> s

Mac側から「Bluetoothファイル交換」でファイル送信の指示を出す。


connect_server()
Server request finished!
server_done() Command (00) has now finished
Made some progress...
Made some progress...
put_server()
put_server() Found name
put_server() Skipped header c3
put_server() Found body
Filename = test2.txt
Wrote /tmp/test2.txt (2064 bytes)
Server request finished!
server_done() Command (02) has now finished
We got a disconnect-request
Server request finished!
Disconnect done!
> q

問題ない模様。
pinについては、MacOS X側で「Bluetooth設定アシスタント」を使ってあらかじめ登録しておいた。

現状と今後の展望

現状では、今ひとつ動作が不安定で、同じような手順を踏んでいるのに送受信が出来なくなることがある。 再起動をかければ元に戻るのでおそらくZaurus側の問題と思われる。
サスペンドから復帰した際には、カードの抜き差しを行うか cardctl eject / insert して再認識させてやらないといけないのもちょっと面倒。

また、日常利用する際にはobex_testを使うわけにもいかないので、別途送受信用のアプリケーションを作成する必要があるだろう。 ObexFTPという便利そうなソフトもあるのだが、これをコンパイルしようとしたらアセンブル処理でエラーが出てしまい、お手上げ状態中。

このあたり、転送プログラムを含めある程度成果が出たら、OpenOBEXを含めipk化したいと思っている。
ということで(その2)へ続く(多分)。

関連リンク