Monday, July 6, 2015

Basic Bluetooth operations in command-line interface (CLI)

First of all, this post talks about Bluetooth management on Linux.

I have Ubuntu 14.04 LTS on my personal laptop. Actually Ubuntu has a pretty good Bluetooth management GUI.

Ubuntu 14.04 LTS: Bluetooth management GUI in Settings
However there might be certain scenarios that we would like to manage Bluetooth devices in CLI. When I work with Bluetooth on my Raspberry Pi, I also need CLI-based Bluetooth tools.

The official Bluetooth protocol stack for Linux is BlueZ (http://www.bluez.org/). It has several simple CLI executives with which you can manage the Bluetooth functionalities on your Linux machine just in CLI. If you open a terminal window and type "blue" and tab (for auto completion), you will probably see a bunch of executives named bluetooth* or bluez-*.

Bluetooth management commands
If you don't find some of these commands, you can install them with

sudo apt-get install bluez-utils

This post will only cover basic Bluetooth management operations in CLI, which include
  1. View local adapters
  2. Pair with other devices
  3. Trust other devices
  4. Browse local services
  5. Check and modify local configurations
These operations are usually required to work with any Bluetooth device in CLI.

I. Environment


Commands and operations presented in this post have been tested on the following platforms.

1. Laptop PC


CPU: Intel® Core™2 Duo CPU T7700 @ 2.40GHz × 2
RAM: 4GB
OS: Ubuntu 14.04 LTS (trusty) 64-bit, Linux 3.13.0-44-generic
Bluetooth adapter: Alps Electric Co., Ltd Bluetooth Controller (ALPS/UGPZ6)

2. Raspberry Pi 1 Model B


RAM: 512MB
OS: Raspbian, Debian 7.8 (wheezy), Linux 3.10-3-rpi
Bluetooth adapter: Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)

The Bluetooth adapter I use on my Raspberry Pi is SoundBot® SB340 Bluetooth 4.0 USB Adapter. It can be found on Amazon at http://www.amazon.com/SoundBot%C2%AE-SB340-Bluetooth-Transmitter-Compatible/dp/B00F25Z0FS/ref=sr_1_1?ie=UTF8&qid=1436200385&sr=8-1&keywords=soundbot+bluetooth+usb. It looks like this:

SoundBot® SB340 Bluetooth 4.0 USB Adapter
However, there should be many different brands of USB Bluetooth adapter using the CSR chip. For example, this one on eBay: http://www.ebay.com/itm/Bluetooth-4-0-USB-2-0-CSR4-0-Dongle-Adapter-for-PC-LAPTOP-WIN-XP-VISTA-7-8-New-/231273407094?pt=LH_DefaultDomain_0&hash=item35d8f82276. I will be surprised if they don't work the same way.

Notice for Cambridge Silicon Radio, Ltd Bluetooth Dongle

If you would like to choose this USB Bluetooth adapter, or another module with the same chip, please be aware that this module has been identified as a very cheap module, and has a significant problem:

ALL modules with this chip have EXACTLY THE SAME BD address!
ALL modules with this chip have EXACTLY THE SAME BD address!
ALL modules with this chip have EXACTLY THE SAME BD address! 

Important things be stressed three times.

This will cause very big problems if you plan to use multiple of these adapters in the same room. However, difficulties can be overcome by modifying the hardware addresses for them. Since that's not related to our topic, I would not prefer to talk about that in this post.

I am not persuading you to buy or not to buy this module or this chip. This is just for your information.

II. Basic operations


This section will cover the basic operations I mentioned at the beginning of this post.

1. View local adapters


A USB Bluetooth adapter should work in HCI mode for BlueZ to recognize and control. As you can use ifconfig to view local network interfaces and use iwconfig to view local wireless network interfaces, you can also use hciconfig to view local HCI devices. For example, this is what I got on my laptop with hciconfig (with my BD address concealed):

$ hciconfig
hci0:    Type: BR/EDR  Bus: USB
    BD Address: 00:1B:FB:xx:xx:xx  ACL MTU: 384:8  SCO MTU: 64:8
    UP RUNNING PSCAN
    RX bytes:21693 acl:645 sco:0 events:353 errors:0
    TX bytes:4653 acl:285 sco:0 commands:53 errors:0


And this is what I got on my Raspberry Pi:

$ hciconfig
hci0:    Type: BR/EDR  Bus: USB
    BD Address: 00:1A:7D:xx:xx:xx  ACL MTU: 310:10  SCO MTU: 64:8
    UP RUNNING PSCAN
    RX bytes:10302 acl:287 sco:0 events:717 errors:0
    TX bytes:19001 acl:645 sco:0 commands:54 errors:0


2. Pair with other devices


Let's say we have two Bluetooth enabled devices. Device 0 is the Linux machine we are working with in CLI (terminal emulator, TTY, SSH, etc.), and device 1 is a device you would like to pair with device 0, e.g. an Android phone, a Bluetooth GPS module, or simply another Bluetooth enabled PC. Then, there are usually two ways you can get them paired with each other.

(a) Make device 0 discoverable and initiate pairing on device 1


This approach is usually easier, because you don't need to do too much on device 0 where we only have CLI access. However, this requires your device 1 to be interactively operable. If your device 1 is an Android phone or another PC, it would be fine. However, if your device 1 is a Bluetooth GPS module, a Bluetooth keyboard, or something else, which is not so smart, it would be impossible, because you cannot initiate pairing on your device 1.

Basically what you are going to do is: make device 0 discoverable, run a simple agent to listen to incoming pairing requests, and initiate pairing on device 1.

To make device 0 discoverable, execute

sudo hciconfig hci0 piscan

Where "hci0" is the device name of the Bluetooth adapter you would like to use, which can be found in a general hciconfig output. "piscan" stands for PSCAN and ISCAN, both of which are required for a Bluetooth adapter to be discoverable by other devices. After that, you will get the following output with hciconfig:

$ hciconfig
hci0:    Type: BR/EDR  Bus: USB
    BD Address: 00:1A:7D:xx:xx:xx  ACL MTU: 310:10  SCO MTU: 64:8
    UP RUNNING PSCAN ISCAN
    RX bytes:10315 acl:287 sco:0 events:719 errors:0
    TX bytes:19008 acl:645 sco:0 commands:56 errors:0


Note that the third line of the output changed from UP RUNNING PSCAN to UP RUNNING PISCAN.

Then you are going to run bluez-simple-agent with root privileges:

$ sudo bluez-simple-agent
Agent registered


It will show "Agent registered" and stay blocked here. Now on your device 1, scan for your device 0 and pair with it. bluez-simple-agent will prompt you when to input the PIN.

(b) Make device 1 discoverable and initiate pairing on device 0


As I mentioned before, if your device 1 is a non-interactive device like a Bluetooth GPS module or a Bluetooth keyboard, you will have to initiate pairing on device 0. You can, of course, do these with an interactive device 1 as well. Therefore, this approach seems more general when talking about Bluetooth pairing in CLI.

We will refer to Bluetooth GPS and Sat Nav on the official Raspberry Pi forum [1], and Bluetooth Keyboard on the Raspberry Pi by Lodewijk Sioen [2], for this approach.

First of all, if your device 1 is an interactive device, like an Android phone, don't forget to turn on discoverable mode.

On your device 0, run

hcitool inq

This will give you a list of nearby discoverable devices, including their BD addresses, like this:

$ hcitool inq
Inquiring ...
    00:0D:B5:xx:xx:xx    clock offset: 0x0763    class: 0x001f00


Or this:

$ hcitool scan
Scanning ...
    00:0D:B5:xx:xx:xx    BT-GPS-xxxxxx


Then you should be able to initiate pairing on your device 0 with

sudo bluez-simple-agent hci0 xx:xx:xx:xx:xx:xx

Replace the BD address with that of your device 1. bluez-simple-agent will start and prompt you what to do next. The next steps may depend on the device type of your device 1. If your device 1 is a Bluetooth keyboard, it will show you a PIN and let you type it on that keyboard. If it is a device with a pre-configured PIN (some audio devices work this way), it will prompt you to enter the PIN on your device 0. For example, with my Bluetooth GPS module, 00:0D:B5:xx:xx:xx, what I got was:

$ sudo bluez-simple-agent hci0 00:0D:B5:xx:xx:xx
RequestPinCode (/org/bluez/2370/hci0/dev_00_0D_B5_xx_xx_xx)
Enter PIN Code:


However, Bluetooth GPS modules don't usually require pairing, and I don't know what its PIN is either. Therefore I will not continue pairing with it :-)

After these steps, you should have your device 0 paired with your device 1.

3. Trust other devices


When another Bluetooth device would like to initiate a Bluetooth connection to your device 0, you will have to have bluez-simple-agent running and manually approve this connection when it prompts you to do so, in order for the connection to be established successfully. Sometimes we hope our device 0 to work unattended and automatically approve some incoming connections. For example, I would like my Raspberry Pi to automatically approve incoming connections from my laptop, but my Raspberry Pi usually works without any keyboard or monitor. That's when we need this "trusting" feature.

Only trusted devices can initiate a Bluetooth connection to your Bluetooth device, i.e. your device 0, without a manual authentication process.

According to Ubuntu Community Help Wiki [3], to trust a device on your device 0, simply execute

sudo bluez-test-device trusted xx:xx:xx:xx:xx:xx yes

To test if a device is trusted, use

sudo bluez-test-device trusted xx:xx:xx:xx:xx:xx

And it will output 0 for untrusted and 1 for trusted.

4. Browse local services


Bluetooth radios work on several different channels simultaneously. A Bluetooth service will listen on a specific channel and respond to requests sent in this channel. To browse local services, execute

sdptool browse local

Root privileges are not required for this browsing command.

What I got on my laptop is

$ sdptool browse local
Browsing FF:FF:FF:00:00:00 ...
Service Name: SIM Access Server
Service RecHandle: 0x10000
Service Class ID List:
  "SIM Access" (0x112d)
  "Generic Telephony" (0x1204)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 8
Profile Descriptor List:
  "SIM Access" (0x112d)
    Version: 0x0101

Service Name: Headset Audio Gateway
Service RecHandle: 0x10001
Service Class ID List:
  "Headset Audio Gateway" (0x1112)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 12
Profile Descriptor List:
  "Headset" (0x1108)
    Version: 0x0102

Service Name: Hands-Free Audio Gateway
Service RecHandle: 0x10002
Service Class ID List:
  "Handsfree Audio Gateway" (0x111f)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 13
Profile Descriptor List:
  "Handsfree" (0x111e)
    Version: 0x0105

Service Name: Hands-Free
Service RecHandle: 0x10003
Service Class ID List:
  "Handsfree" (0x111e)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 7
Profile Descriptor List:
  "Handsfree" (0x111e)
    Version: 0x0105

Service Name: AVRCP TG
Service RecHandle: 0x10004
Service Class ID List:
  "AV Remote Target" (0x110c)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 23
  "AVCTP" (0x0017)
    uint16: 0x103
Profile Descriptor List:
  "AV Remote" (0x110e)
    Version: 0x0104

Service Name: AVRCP CT
Service RecHandle: 0x10005
Service Class ID List:
  "AV Remote" (0x110e)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 23
  "AVCTP" (0x0017)
    uint16: 0x103
Profile Descriptor List:
  "AV Remote" (0x110e)
    Version: 0x0100

Service Name: Audio Source
Service RecHandle: 0x10006
Service Class ID List:
  "Audio Source" (0x110a)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 25
  "AVDTP" (0x0019)
    uint16: 0x102
Profile Descriptor List:
  "Advanced Audio" (0x110d)
    Version: 0x0102

Service Name: Audio Sink
Service RecHandle: 0x10007
Service Class ID List:
  "Audio Sink" (0x110b)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 25
  "AVDTP" (0x0019)
    uint16: 0x102
Profile Descriptor List:
  "Advanced Audio" (0x110d)
    Version: 0x0102


What I got on my Raspberry Pi is

$ sdptool browse local
Browsing FF:FF:FF:00:00:00 ...
Service Name: Headset Audio Gateway
Service RecHandle: 0x10000
Service Class ID List:
  "Headset Audio Gateway" (0x1112)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 12
Profile Descriptor List:
  "Headset" (0x1108)
    Version: 0x0102

Service Name: Hands-Free Audio Gateway
Service RecHandle: 0x10001
Service Class ID List:
  "Handsfree Audio Gateway" (0x111f)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 13
Profile Descriptor List:
  "Handsfree" (0x111e)
    Version: 0x0105

Service Name: AVRCP TG
Service RecHandle: 0x10002
Service Class ID List:
  "AV Remote Target" (0x110c)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 23
  "AVCTP" (0x0017)
    uint16: 0x103
Profile Descriptor List:
  "AV Remote" (0x110e)
    Version: 0x0103

Service Name: AVRCP CT
Service RecHandle: 0x10003
Service Class ID List:
  "AV Remote" (0x110e)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 23
  "AVCTP" (0x0017)
    uint16: 0x103
Profile Descriptor List:
  "AV Remote" (0x110e)
    Version: 0x0100

Service Name: Dial-Up Networking
Service RecHandle: 0x10004
Service Class ID List:
  "Dialup Networking" (0x1103)
  "Generic Networking" (0x1201)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 1
Profile Descriptor List:
  "Dialup Networking" (0x1103)
    Version: 0x0100

Service Name: Serial Port
Service Description: COM Port
Service Provider: BlueZ
Service RecHandle: 0x10006
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 4
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Serial Port" (0x1101)
    Version: 0x0100

Service Name: Serial Port
Service Description: COM Port
Service Provider: BlueZ
Service RecHandle: 0x10007
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 22
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Serial Port" (0x1101)
    Version: 0x0100


Each separated section in the output stands for a Bluetooth service, the succeeding details will reveal its service class ID, the channel it listens on, etc.

5. Check and modify local configurations


There are two places on your Linux machine where you can find Bluetooth related configurations. The first one is /etc/bluetooth, and the second one is /var/lib/bluetooth. The difference is, the first place is for configuration files for your Linux Bluetooth service, namely, BlueZ, and the second place is for configuration files for each of your Bluetooth adapters. Files in the second path are automatically generated, but modifications to them also take effect.

(a) Discoverable device name


In /etc/bluetooth/main.conf, at the beginning of file there's such a section:

# Default adaper name
# %h - substituted for hostname
# %d - substituted for adapter id
Name = %h-%d

# Default device class. Only the major and minor device class bits are
# considered.
Class = 0x000100


This is where you can change your discoverable device name (or the naming rule). It affects the name, that your device (actually, each Bluetooth adapter on your device) appears on other Bluetooth devices when set to discoverable. For example, if the host-name of my laptop is PEPOVAIO and I just keep main.conf unchanged like that, "hci0" on my laptop will appear to be "PEPOVAIO-0" on my Android phone.

However, this is the place where the naming rule is defined. The actual name will be stored in a folder under /var/lib/bluetooth. For example, on my Raspberry Pi I have these things in /var/lib/bluetooth:

$ ls -1 /var/lib/bluetooth
00:00:00:00:00:00
00:1A:7D:xx:xx:xx


I don't really know what the first one (00:00:00:00:00:00) is for. However, the second one is the BD address of my CSR adapter. These are all directories so we can look into them:

$ ls -1 /var/lib/bluetooth/00:1A:7D:xx:xx:xx
classes
config
did
eir
features
lastseen
lastused
linkkeys
manufacturers
names
profiles
sdp
trusts


These files are the actual configuration files that are in effect. For example, in config, you will see something like:

$ cat config
name cycletest-0
pairable yes
class 0x420100


If you changed the naming rule in /etc/bluetooth/main.conf but keep this config file unchanged, nothing will happen even if you restart your device. To make things synchronized, simply remove this config, and it will be re-created using configurations in /etc/bluetooth/main.conf.

Notice for Ubuntu 14.04 LTS' default device name

If you have a built-in Bluetooth adapter on your laptop and had it enabled during Ubuntu 14.04 LTS installation (probably for some other releases, too), it may have named your adapter "ubuntu-0", regardless what you have named your laptop later in your installation process.

This problem is probably caused when that config file was created before you give your laptop a preferred host-name, and stayed unchanged after then. To fix (work around) this, just remove the corresponding config file in the adapter directory, and reboot your machine, or restart the bluetooth service with

sudo service bluetooth restart

This is not a big issue, though, because that name shouldn't be expected to change frequently :-)

(b) Trusted devices


I think you also noticed the file trusts in /var/lib/bluetooth/00:1A:7D:xx:xx:xx. Yes, it contains information of trusted devices. Therefore, to list all trusted devices, simply under that path, use

$ cat trusts
00:1B:FB:xx:xx:xx [all]
00:18:31:xx:xx:xx [all]


Where you can tell that the first one is my laptop, trusted by my Raspberry Pi :-) And the second one is actually my Android phone.

III. References


[1] Bluetooth GPS and Sat Nav. https://www.raspberrypi.org/forums/viewtopic.php?t=25759&p=234809
[2] Bluetooth Keyboard on the Raspberry Pi. http://www.correlatedcontent.com/blog/bluetooth-keyboard-on-the-raspberry-pi/
[3] BluetoothSetup. https://help.ubuntu.com/community/BluetoothSetup

3 comments:

  1. 메리트카지노 메리트카지노 카지노사이트 카지노사이트 カジノ シークレット カジノ シークレット 10bet 10bet dafabet link dafabet link planet win 365 planet win 365 22

    ReplyDelete
  2. CASINO GAMING CASINO RESORT WALESTERN - KTNV
    CASINO GAMING CASINO RESORT WALESTERN. 4-star 익산 출장샵 hotel at Casino Hinckley Village, 제주도 출장안마 8 안양 출장안마 km 서산 출장안마 from Bangor 안동 출장마사지 (DMB)

    ReplyDelete
  3. QOS는 아시다시피 전작에서 바로 이어지는 영화이기 때문에, 전작의 줄거리와 등장인물들을 제대로 기억하고 계시지 않으면 약간의 애로사항 꽃다발을 안겨주는 영화입니다. ● 영화의 반전이나 결말의 비밀 등에 대한 정보가 크랩스 본문에 포함될 경우 반드시 게시물 제목에 '스포일러' 표시를 해주세요. 공포영화로는 그에게 ‘스릴러 퀸’이라는 수식어를 남겼던 ‘장화, 홍련’ 이후 14년 만이다. 007 시리즈 중에서는 가장 많은 제작비인 1억5천만 달러(1천395억여 원)가 투입됐다.

    ReplyDelete