02 January 2016

(Ubuntu) コマンドラインでのBluetoothシリアル受信

コマンドラインで、Bluetoothシリアルデバイスからのデータ受信を行う一連の設定作業メモ

検証環境

・Ubuntu 14.04 LTS
・Bluetooth - USB アダプタ
・GPS受信機 BT-GPS-37978F(BT-359W)

20160102-bt-serial.jpg

今回は、一方的にシリアル通信でテキストデータを垂れ流してくるBluetooth GPS受信機を使った。bluetooth, bluez-compat, bluez-utils などの主要パッケージが導入されているかは事前に確認しておくこと。

Bluetoothドングルがシステムに認識されているか確認

# sudo hciconfig 
hci0:	Type: BR/EDR  Bus: USB
	BD Address: 00:15:83:0C:BF:EB  ACL MTU: 339:8  SCO MTU: 128:2
	UP RUNNING PSCAN ISCAN 
	RX bytes:419193 acl:10007 sco:0 events:13310 errors:0
	TX bytes:190661 acl:13031 sco:0 commands:148 errors:0

ステータスが「UP」でなければhciconfig hci0 upで起動する

Bluetoothデバイスのスキャン

# sudo hcitool scan
Scanning ...
	00:11:67:8C:04:E6	H163
	C0:38:96:73:15:6E	BRAVIA
		00:0D:B5:37:97:8F	BT-GPS-37978F

今回は、赤で示したBT-GPS-37978Fに接続したい。念たのめpingテストで通信エラーがないか確認

# sudo l2ping -c 4 00:0D:B5:37:97:8F
Ping: 00:0D:B5:37:97:8F from 00:15:83:0C:BF:EB (data size 44) ...
4 bytes from 00:0D:B5:37:97:8F id 0 time 26.96ms
4 bytes from 00:0D:B5:37:97:8F id 1 time 10.72ms
4 bytes from 00:0D:B5:37:97:8F id 2 time 34.78ms
4 bytes from 00:0D:B5:37:97:8F id 3 time 39.97ms
4 sent, 4 received, 	0% loss

接続したいBluetoothデバイスの情報を表示する

# sudo hcitool info 00:0D:B5:37:97:8F
Requesting information ...
	BD Address:  00:0D:B5:37:97:8F
	Device Name: BT-GPS-37978F
	LMP Version: 1.2 (0x2) LMP Subversion: 0x8ce
	Manufacturer: Cambridge Silicon Radio (10)
	Features: 0xff 0xff 0x8f 0xfe 0x9b 0xf9 0x00 0x80
		<3-slot packets> <5-slot packets> <encryption> <slot offset> 
		<timing accuracy> <role switch> <hold mode> <sniff mode> 
		<park state> <RSSI> <channel quality> <SCO link> <HV2 packets> 
		<HV3 packets> <u-law log> <A-law log> <CVSD> <paging scheme> 
		<power control> <transparent SCO> <broadcast encrypt> 
		<EDR ACL 2 Mbps> <EDR ACL 3 Mbps> <enhanced iscan> 
		<interlaced iscan> <interlaced pscan> <inquiry with RSSI> 
		<extended SCO> <EV4 packets> <EV5 packets> <AFH cap. slave> 
		<AFH class. slave> <3-slot EDR ACL> <5-slot EDR ACL> 
		<AFH cap. master> <AFH class. master> <EDR eSCO 2 Mbps> 
		<EDR eSCO 3 Mbps> <3-slot EDR eSCO> <extended features> 

Bluetoothデバイスに接続、ペアリング

検索して自動接続されるのを待つ。コマンドがいつまで経っても終わらない場合は、手動でペアリングを行う。

# sudo hidd --search
Searching ...
	Connecting to device 00:0D:B5:37:97:8F

ペアリングは、そのマシンで最初の1回だけ行えば良い。次からは自動接続される。

# sudo bluez-simple-agent hci0 00:0D:B5:37:97:8F
RequestPinCode (/org/bluez/6001/hci0/dev_00_0D_B5_37_97_8F)
Enter PIN Code: 0000
Release
New device (/org/bluez/6001/hci0/dev_00_0D_B5_37_97_8F)

Bluetoothデバイスのサービス確認

シリアル接続には必須ではないが、Bluetoothデバイスのサービス確認方法。まずは、全てのデバイスのスキャンを掛けてみるが、ここでは表示されない場合もある。

# sudo sdptool browse
Inquiring ...
Browsing C0:38:96:73:15:6E ...
Service RecHandle: 0x10000
Service Class ID List:
  "PnP Information" (0x1200)
 
Browsing 00:11:67:8C:04:E6 ...
Browsing 00:0D:B5:37:97:8F ...

個別にサービスの強制確認をしてみる。ここで「Serial Port」機能があると表示されることを確認。

# sudo sdptool records 00:0D:B5:37:97:8F
Service Name: BT-GPS COM Port
Service RecHandle: 0x10001
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 1
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
 
 〜 以下省略 〜

なお、全てのデバイスの中でシリアルポート機能のあるものを列挙するには

# sudo sdptool search SP 
Inquiring ...
Searching for SP on 00:0D:B5:37:97:8F ...
Service Name: BT-GPS COM Port
Service RecHandle: 0x10001
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 1
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
 
 〜 以下省略 〜

シリアルポート(/dev/***)にバインドする

/dev/rfcommXにバインドして、他のシリアルポートにアクセスするプログラムから使えるようにする。赤で示した「X」は0, 1, 2 ... の任意の数を指定できる。今回は「1」を指定

# sudo rfcomm bind 1 00:0D:B5:37:97:8F

他のアプリケーションでシリアル通信を利用する例

まず、通信速度などの条件を設定して

# sudo stty -F /dev/rfcomm1 38400 cs8

catコマンドで吐き出してみるう。もしくはminicomを用いて送受信しても良い

# sudo cat /dev/rfcomm1
$PSRFTXT,Version:GSW3.2.4_3.1.00.12-SDK003P1.00a 
$PSRFTXT,Version2:F-GPS-03-0702021
$PSRFTXT,WAAS Disable
$PSRFTXT,TOW:  540485
$PSRFTXT,WK:   1877
$PSRFTXT,POS:  -3743821 3680734 3609547
$PSRFTXT,CLK:  93607
$PSRFTXT,CHNL: 12
$PSRFTXT,Baud rate: 38400 
$GPGGA,063915.239,,,,,0,00,,,M,0.0,M,,0000*56
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,063915.239,V,,,,,,,020116,,*2B
$GPGGA,063916.194,,,,,0,00,,,M,0.0,M,,0000*51
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,063916.194,V,,,,,,,020116,,*2C
$GPGGA,063917.191,,,,,0,00,,,M,0.0,M,,0000*55
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,063917.191,V,,,,,,,020116,,*28
$GPGGA,063918.188,,,,,0,00,,,M,0.0,M,,0000*52
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,063918.188,V,,,,,,,020116,,*2F
$GPGGA,063919.191,,,,,0,00,,,M,0.0,M,,0000*5B
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,12,18,58,306,,21,30,246,,10,25,316,,24,84,340,*76
$GPGSV,3,2,12,15,54,057,,20,49,150,,12,29,150,,13,19,074,*72
$GPGSV,3,3,12,14,07,279,,25,06,182,,22,05,315,,05,03,138,*70
$GPRMC,063919.191,V,,,,,,,020116,,*26

20160102-gtkterm.jpg
GtkTermでの受信例

シリアルポート(/dev/***)からのアンバインド

バインド状況を見てみる。確かに channel 1 にバインドされている

# sudo rfcomm -a
rfcomm1: 00:0D:B5:37:97:8F channel 1 clean 

アンバインドする。Bluetoothドングルを取り外す前に、必ずアンバインドする

# sudo rfcomm release 1