Porting and configuration of the Bluetooth protocol stack bluez on the ARM platform
Author: Liu Xuhui Raymond reprinted. Please indicate the source
Email: colorant@163.com
Blog: http://blog.csdn.net/colorant/
Home: http://rgbbones.googlepages.com/
Bluez, as the most mature open-source Bluetooth protocol stack, has been widely used in various major Linux releases. In the desktop environment, bluez should not be used too much. The main purpose of this article is to introduce the work required to build and configure the various profiles of bluez on the embedded platform, discuss possible problems and introduce the use and working principles of some tools. Due to my limited ability and test time, some understanding and analysis in this article may not be accurate. Please contact us for correction.
1. Description
1.1 website resources
Bluez Official Website: http://www.bluez.org/here provides the latest source code download, recently server crashed once, some things are gone ....
Bluez wiki: http://wiki.bluez.org/wiki/ provides bluez-related documentation resources such as howto
Related email list:
Most of the https://lists.sourceforge.net/lists/listinfo/bluez-users's questions about how to use and configure bluez are discussed in PC environments ....
Https://lists.sourceforge.net/lists/listinfo/bluez-devel bluez developer activities, where there are any bugs and other doubts, as well as programming interface problems, just sent here.
1.2 Working Environment
I personally feel that the biggest problem with using bluez is the lack of documentation. In addition to the limited information on Wiki, it is difficult to find other useful documents.
Since bluez's code implementation changes rapidly, many documents on the Internet introduce the use of earlier versions. Some other articles are mostly based on mature Linux releases, to discuss the configuration and use of Bluetooth devices, there are few articles on embedded system development, self-compilation, setup and configuration of related environments. In addition, it is difficult to find information related to the specific Bluetooth chip.
I don't plan to write a complete guide here, but I can only do my work on my own board some time ago, summarize the relevant steps and various problems encountered, as well as the various related knowledge during this period. I hope to provide some useful help to my friends who have similar development needs. The following is the working environment based on this article:
Hardware Platform: ARM-based Embedded Board
Bluetooth Chip: CSR bc4 ROM chip without EEPROM
Software environment: Linux 2.6.21, self-made File System
Bluez version: bluez-libs 3.22 bluez-utils 3.22
2 compile
2.1 Kernel
I believe most people are using the 2.6 kernel. To support bluez In the 2.6 kernel, as long as your kernel version is not too old, you don't need to install patches. You can simply configure it, the code in the kernel is relatively stable. Of course, bluez still needs to update the kernel code to support some new features of the Bluetooth protocol stack. Check whether the kernel version you are using contains the corresponding support.
For Kernel configuration, select the following items in Bluetooth Subsystem Support under networking:
L2CAP protocol support
SCO links support
RFCOMM protocol support
RFCOMM tty support
Bnep protocol support
Hidp protocol support
In addition, select the bluetooth device you want to support in the bluetooth device drivers. The chip of the csr I used is built on the board and communicates with the CPU through the serial port. The chip uses bcsp as the communication protocol by default, so I chose:
Hci uart driver
Bcsp protocol support
If you are using a Bluetooth adapter through the USB interface, you need to select
Hci usb driver
2.2 bluez lib/utils
The compilation of bluez Lib is relatively simple, while bluez-utils relies on a lot of libraries, such as dbus ALSA Hal gstreamer openobex XML. /configure output. install or build the required package first.
It is worth noting that:
If you need to enable support for all functional modules, you must. add -- enable-all -- enable-audio -- enable-input -- enable-Network-enable-serial to the/configure parameter, in version 3.22, -- enable-all does not include the compilation of services of related modules such as audio. I wonder whether it is because different solutions such as daemon and service are retained. However, this is at least inconsistent with the description of -- enable-all in configure -- help.
3. Bluetooth hardware initialization and basic service startup
If Ubuntu is used in a PC environment, call/etc/init. d/Bluetooth start to complete this step. The following describes how to manually complete this step in my embedded environment.
3.1 What is hardware initialization
Hardware initialization refers to configuring the Bluetooth chip and placing it in a State that can communicate normally.
For CSR chips, you can set pskey, crystal oscillator frequency, UART baud rate, and other key parameters. If a USB-type adapter is used, because its EEPROM stores the relevant default parameters, this step is likely not required, and I am using a rom version chip without the EEPROM, it took me a while to complete initialization correctly.
I have not studied much about other chips. However, I have limited understanding that Ti chips also need to complete some additional initialization work during hciattach, other chips such as ST may need to download firmware.
3.2 hardware initialization steps
Generally, the initialization and Protocol binding of the Bluetooth chip can be completed through hciattach (by configuring the bluez STARTUP script, you do not need to use hciattach. The standard release version should not use hciattach. how to configure it, no research... 8)
Parameters required by hciattach mainly include tty nodes, device types, and baud rates. For most types of devices, after selecting the correct device type parameter, hciattach calls the specific initialization function in the init_uart function.
Unfortunately, it is necessary to reset the crystal oscillator frequency and baud rate and synchronize the bcsp protocol, this method does not seem to be able to handle the chips I use (it is not ruled out that I have not found the right solution). The final solution is before hciattach, use the bccmd tool in bluez-utils to set these pskeys first.
The specific command is:
Bccmd-T bcsp-D/dev/ttys1 psload-r CSR. SRS
At this time, because the HCI interface has not been started, you can only use the bcsp protocol for communication, and my device is exposed under ttys1, you may be different, -R parameter indicates that after psload completes the pskey batch loading operation, the chip will be warmreset. Otherwise, the modification of these parameters will not work.
The content of CSR. PSR depends on your chip. My details are as follows:
// Pskey_ana_freq
& 01fe = 9c40 // equivalent to a 40 m Crystal Oscillator
// Pskey_uart_baud_rate
& 01be = 0ebf // 921600 baud rate
// Pskey_uart_seq_winsize
& Amp; 0407 = 0006
// Bdaddr
& Amp; 0001 = 1122 3344 5566 7788
...
There is a problem here, you will find that in theory, each pskey can be set in one step through the bccmd-T bcsp psset command, but in my practice, in the process of calling bccmd twice, the last modification to pskey will be reset before the next call, it is estimated from the code that it is related to the synchronization process of the bcsp protocol.
3.2.1 pskey acquisition
There are several ways to obtain the correct and complete pskey parameters:
Download the boot_token package from the CSR website. This is the initialization code used by the CSR's own bchs protocol stack. Find the pskey value you need.
Download the CSR bluesuite tool, which contains a tool called pstool, which can be used to read and write the pskey settings of the CSR casira Development Board or other Bt devices, test and find out the parameters you can use.
Find CSR or module vendor support 8)
However, to allow the chip to communicate with the bluez protocol stack through a serial port, you only need to set pskey_ana_freq and pskey_uart_baud_rate.
3.3 daemon process startup
In earlier versions, there were a lot of daemon in bluez, but in recent versions, many daemon were converted into services, and 3.22 included the following services, other profiles seem to retain the form of daemon.
Bluetoothd-service-serial
Bluetoothd-Service-NETWORK
Bluetoothd-service-Audio
Export thd-service-Input
The startup of these services depends on the startup of hcid and related configuration files.
The main configuration file is located at:/etc/Bluetooth/
In addition, you usually need to start SDP to provide service queries. In addition, bluez also depends on the running of mongodaemon.
Therefore, the entire process of manually starting bluez is as follows: (the kernel code is compiled in the form of modules)
Insmod Bluetooth. Ko
Insmod hci_uart.ko
Insmod L2CAP. Ko
Insmod RFCOMM. Ko
Insmod SCO. Ko
Insmod hidp. Ko
/Etc/rc2.d/s201_start
Bccmd-T bcsp-D/dev/ttys1 psload-r CSR. SRS
Hciattach-s 921600/dev/ttys1 bcsp 921600
Hciconfig hci0 up
Sdpd
Hcid-d
4 paring
4.1 passkey_agent
Before using a bluetooth device, you usually need to bind the device.
Bluez's pairing mechanism seems to have been modified several times, 2. in Version X, pin_helper is used to process the PIN code response. In version 3.22, the pairing mechanism is implemented based on callback and an agent needs to be registered with callback, the PC release usually has some passkey_agent based on various graphics libraries. For embedded systems, this part of the code can be imagined, it should be implemented according to the corresponding API, in order to test, I directly used the passkey-agent in the bluez-utils/daemon directory.
This is a program that can be paired with a preset PIN code under the command line.
To use it, the option section in/etc/Bluetooth/hcid. conf in my file system is similar to the following:
# Hcid options
Options {
# Automatically Initialize New Devices
Autoinit yes;
# Security Manager Mode
# None-Security Manager disabled
# Auto-use local pin for incoming connections
# User-always ask user for a pin
#
Security user;
# Pairing mode
Pairing multi;
# Do the same as "hciconfig hci0 down" When setmode ("off ")
# Is called.
Offmode devdown;
# Default PIN code for incoming connections
Passkey "1234 ";
}
4.2 automatic pairing and request Initiation
The initiation of pairing is mainly from the perspective of the Request initiator.
Usually, you do not need to worry about whether the pairing request is initiated locally or remotely. passkey_agent can be correctly processed.
However, if you set the security manager mode to auto in hcid. conf, bluez uses the string following the passkey as the default PIN code to automatically reply to the remote pairing request. This is a pairing method without passkey_agent.
In this case, bluez can process remote pairing requests, but it will not be able to process locally initiated pairing requests correctly. I did not carefully analyze the causes, maybe the code is specially designed to work in this way. Therefore, if you do not know who will initiate a pairing request first and use the atuo mode, the device may be bound and sometimes cannot be bound.
Generally, if it is a new device found by a local device, the pairing operation should also be initiated locally.
In addition, we can observe that for a remote Non-PC bluetooth device, such as a Bluetooth headset, if it was bound last time, a connection request will be initiated when the headset is started, if the local link key is lost, the binding process is followed. In this case, the pairing request is initiated by the remote device.
5 a2dp
A2dp Bluetooth stereo should be one of the most common profiles of Bluetooth.
2. The a2dp support for bluez in Version X is implemented through btsco, and version 3.22 is supported through javasthd-service-audio.
The support for bluez a2dp profile also depends on ALSA or gstreamer.
5.1 Configuration
When testing a2dp, I used aplay and wrote the address of the Bluetooth headset in the relevant configuration file.
The main configuration files include:
/Etc/asound. conf:
PCM. Bluetooth {
Type Bluetooth
Device 00: 02: 5b: 00: C1: A0
Profile "hifi"
}
/Etc/Bluetooth/audio. conf:
[General]
# Disable = sink
Scorouting = PCM
[Headset]
Disablehfp = true
[A2dp]
Sourcecount = 2
After the configuration, use aplay-D Bluetooth sample.wav for testing.
It is worth noting that using aplay to enable the bluetooth device for playback requires the following two ALSA plug-ins:
/Usr/lib/ALSA-lib/libasound_module_pcm_bluetooth.so
/Usr/lib/ALSA-lib/libasound_module_ctl_rjth.so
These two so files can be found in bluez-utils. Note that they match the libasound version.
5.2 questions
During the test, it is found that if the connected headset is an AV headset service provided by the Bluetooth adapter on the PC, the pairing can be completed, but the connection will fail. The real headset does not have this problem, I wonder if the above method still has defects? The same is true if you try to connect to the PC's AV headset service by running the dig command. Do you need to switch the role of the device before connecting to the PC-simulated AV headset service?
No CTL interface tested
How do I dynamically choose different headphones instead of writing them to the script? (This is probably because you need to program your own ALSA-based API, and aplay cannot directly complete the test)
When playing a large file, the under run error may occur. You need to test whether the setting is not high enough with the baud rate, whether the SBC encoding efficiency is not enough, or the bug in this version.
6 Dun usage
The dun profile runs on RFCOMM and exposes a modem interface through the Bluetooth interface to provide dial-up Internet services.
What we discuss here is not to provide the dial-up Internet service itself, but to use the service provided by external devices for network connection.
6.1 System Configuration
Generally, to use Dun or any other Modem, we use the PPP protocol to dial and establish a network connection.
First, Kernel support is required. You can simply select all PPP-related content under device drivers> network device support.
Secondly, to compile the PPP package at the application layer, my test is based on ppp-2.4.4
Two major PPP configuration files:
/Etc/PPP/peers/GPRS:
/Dev/rfcomm0
115200
Defaultroute
Usepeerdns
Nodetach
Noauth
Local
Debug
Connect "/usr/sbin/chat-v-F/etc/PPP/chat-GPRS"
/Etc/PPP/chat-GPRS:
Timeout 10
Abort 'busy'
Abort 'no ancer'
Abort 'error'
"" 'Atz'
Say 'init.../N'
OK 'at + cgdcont = 1, "ip", "cmwap "'
Abort 'no carrier'
Say 'dialing.../N'
OK 'atd * 99 *** 1 #'
Connect''
The previous configuration file is basically like that, and the next one is based on the actual situation of your SIM card:
OK 'at + cgdcont = 1, "ip", "cmwap "'
OK 'atd * 99 *** 1 #'
Here I set up cmwap for China Mobile.
In addition, to use cmwap, you also need to set the proxy server of your browser: 10.0.0.172 port 9201
6.2 connection steps
First, you need to find the channel on which the Dun service is provided. This can be viewed through sdptool. The query result on my device is on channel 1:
~ #./Sdptool browse 00: 08: C6: 77: A0: 6c
Browsing 00: 08: C6: 77: A0: 6C...
Service name: Dial-upnetworking
Service rechandle: 0x10000
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
Second, if the device node required by RFCOMM does not exist, create it:
Mknod-M 666/dev/rfcomm0 C 216 0
If the device is not bound before, the binding operation is automatically initiated during the process:
Pppd debug dump call GPRS &
After that, you can see a network interface such as ppp0.
~ # Ifconfig
Ppp0 link encap: Point-to-Point Protocol
Inet ADDR: 10.154.76.82 p-t-P: 192.200.1.21 mask: 255.255.255.255
Up pointopoint running noarp multicast MTU: 1500 Metric: 1
RX packets: 4 errors: 0 dropped: 0 overruns: 0 frame: 0
TX packets: 6 errors: 0 dropped: 0 overruns: 0 carrier: 0
Collisions: 0 txqueuelen: 3
RX Bytes: 64 (64.0 B) TX Bytes: 101 (101.0 B)
7 use of various tools related to bluez
During this period of time, we found that many tools related to bluez are still quite useful, mainly in the bluez-utils/tools directory. I am sorry for the fact that, apart from man, it is difficult to find more help documents, and man documents do not provide detailed descriptions of some functions.
There are some options. If you do not know about the Bluetooth protocol stack or have not consulted some documents about the Bluetooth chip, it is difficult to understand what it means, even some options have specific parameter values. If you do not read the source code, you will not know which options are available ....
Limited capabilities. The following is just some of the experiences of using the limited tools I have used. I hope this will be helpful.
7.1 bccmd
Bccmd is a tool used to communicate with the CSR chip bccmd (bluecore Command Protocol. Bccmd is not the standard of the Bluetooth protocol stack, but the exclusive protocol of the CSR chip.
The call format of bccmd is: bccmd [-T <transport>] [-D <device>] <command> [<ARGs>]
The tansport type includes hci usb bcsp H4, and the common estimation is HCI and bcsp. Pay attention to their usage scenarios:
HCI is an abstract standard Bluetooth communication interface. When calling bccmd Based on the HCI protocol, it must be used on the basis that the HCI interface has been established by bluez.
Bcsp (bluecore serial Protocol) is a transport layer protocol developed by CSR. It aims to enhance reliable data transmission without using cts or RTS for traffic control. The concept is relative to H3 and H4 (for detailed analysis, refer to the corresponding section in the miscellaneous chapter below)
The main purpose of bccmd is to read and write pskey. Here we will introduce the format using the command psset:
The psset format is as follows: psset [-R] [-S <stores>] <key> <value>
Others are easy to understand. The key is the specific meaning of the store after the-S parameter. This parameter can be a numeric value or a string.
Query the bccmd-related documents of CSR. The specific meanings are as follows:
0x0000 default
0x0008 psram
0x0001 PSI
0x0002 PSF
0x0004 psrom
0x0003 PSI then PSF
0x0007 PSI, PSF then psrom
0x0009 psram then PSI
0x000b psram, PSI then PSF
0x000f psram, PSI, PSF then psrom
In the CSR Bluetooth chip, pskey may be stored in ROM flash EEPROM Ram and other media. The value here specifies the storage medium and its priority when the psset/get command is used to operate pskey, we usually use the-S 0x0 or-s "default" command. The meaning of 0x0 is the same as that of 0xf.
It is worth noting that which parameter is valid depends on which type of storage media actually exists in the Bluetooth chip. In addition, the write operation commands of read-only media are invalid.
Basically, the modified pskey is located in psram. In addition, the modified pskey will take effect later. You must also use the-R parameter or directly use the warmreset command to reset the Bluetooth chip for warm.
7.2 hciattach
Hciattach is mainly used to initialize a bluetooth device. Its command format is as follows:
Hciattach [-N] [-p] [-B] [-T timeout] [-s initial_speed] <tty> <type | ID> [speed] [flow | noflow] [bdaddr]
The most important parameters are type and speed. type determines the model of the device to be initialized. You can use hciattach-L to list the supported device models.
Not all parameters are applicable to all devices. Some devices ignore some parameter settings. For example, you can view the hciattach code to see that most devices ignore the bdaddr parameter.
The internal working procedure of the hciattach command is: first open the developed tty device, then make some general settings, such as flow, and then set the baud rate to initial_speed, then, call the respective initialization code based on the type, and then reset the baud rate to speed. Therefore, when calling hciattach, set initial_speed and speed according to your actual situation.
For type bcsp, the initialization Code only performs one thing, that is, synchronizing the bcsp protocol. It does not set any pskey for the Bluetooth chip. For detailed procedures and specifications of synchronization operations, refer to the relevant CSR documents: bcsp link establishment Protocol
7.3 others
Which of the following are used, but there is not much research
7.3.1 hcidump
Hcidump is not in the bluez-utils package, but in a separate hcidump package. It is mainly used to analyze and capture HCI data packets. If problems occur during the bluez process, hcidump can often be used to find some clues and causes of errors. There are many parameters. Basically, hcidump-X-V can help you get detailed formatted parsed data packets.
7.3.2 hcitool
Hcitool is used to scan remote devices and display device addresses and names.
Example: hcitool scan, hcitool INQ
7.3.3 sdptool
It is mainly used to browse the SDP Service of remote devices or manage the databases maintained by local sdpd.
The common method is to find the service of the remote device.
For example:
Services provided by devices with sdptool browse 00: 02: 72: B0: 00: 26 browsing addresses 00: 02: 72: B0: 00: 26
Sdptool search 0x1112 00: 02: 72: B0: 00: 26 find the headset audio gateway service on the device whose address is 00: 02: 72: B0: 00: 26.
./Sdptool search 0x1112 00: 02: 72: B0: 00: 26
Class 0x1112
Inquiring...
Searching for 0x1112 on 00: 02: 72: B0: 00: 26...
Service name: headset audio Gateway
Service rechandle: 0x1001d
Service class ID list:
"Headset audio Gateway" (0x1112)
"Generic audio" (0x1203)
...
7.3.4 hciconfig
The format is similar to ifconfig, which is used to set parameters of HCI devices.
For example
Hciconfig hci0 up start hci0 Interface
Hciconfig hci0 iscan enables the inquery scan mode of the Bluetooth Chip located on the hci0 interface (so that the device can be detected by other Bluetooth devices)
8 Miscellaneous
8.1 test with sending-send
Because bluez uses the publish command for inter-process communication, we can use the send-send command to directly send commands for some queries and experiments.
Bluez each daemon or Service supports the volume interface API description text, which can be found in their respective directories, such as audio APIs written in audio/audio-api.txt.
Taking audio as an example, you can refer to the description in the http://wiki.bluez.org/wiki/HOWTO/AudioDevices
8.2 relationship between HCI, H4, USB, and bcsp
I personally understand that HCI and several other protocols are not comparable at the same level.
HCI protocol is just an abstract transport layer or interface that does not consider the actual transmission carrier and the error correction. USB, H3, H4 and so on are the specific transport layer (In addition, SD Transport Layer ). HCI packets must be attached to these specific transport layer protocol packages.
Taking bcsp as an example, four types of HCI data packets each use a bcsp channel. As the payload of these channels is encapsulated in the Protocol package of bcsp, we need to go through the TTY lldsic layer once, the hci_uart module encapsulates the data. Bcsp also supports other custom protocols through other channels. As a specific transport layer protocol, bcsp also supports features such as verification and synchronization.
The H4 mechanism is similar. SD and USB transport seem to be slightly different. For more information, see Bluetooth specification Volume 4.
8.3 bcsp data packet structure
The structure of HCI data packets is defined in the Bluetooth spec. However, a bunch of other protocols such as CSR bcsp and bccmd are added, HCI data packets are payload of bcsp, while bccmd is payload of HCI. During the test, we find that we need to analyze the data that bluez finally sent to the serial port of the Bluetooth chip through the kernel, in particular, if you want to manually construct a string of data, you have to look at a bunch of spec and splice it to complete it.
The best way to learn and analyze a series of commands is to modify the bccmd code and print every string sent to the serial port. In this way, compare the Code with this spec to get twice the result with half the effort.
For example, the following command uses the modified bccmd command. The operation is to read the pskey of the serial port baud rate:
./Bccmd. dbg-T bcsp-D/dev/ttys1 psget-S 0x0 0x01be
CMD: 00 FC 13 C2 00 00 09 00 01 00 03 70 00 00 be 01 01 00 00 00 00
C0 D1 65 01 C8 00 FC 13 C2 00 00 09 00 01 00 03 70 00 00 be 01 01 01 00 00 00 00 69 A6 C0
Here, the HCI data packet is the first line. The specific explanation is as follows:
The first four bytes are HCI head, where
00 FC: This is a manufacturer-defined command.
13: the length of the HCI command is 0X13.
C2: the package content is the only bccmd packet.
Followed by head of bccmd
00 00: This is a getreq command.
09 00: bccmd command 9 word length, and 18 bytes
01 00: seqno, packet sequence mark Package 1
03 70: varid 7003, indicating that this is an operation on pskey
00 00: Status flag
Next is the payload of bccmd.
Be 01: 0x01be index of the baud rate pskey
01 00: The pskey length is 1
00 00: strore is 00
00 00: the value of this pskey. Here is the READ command, so enter 0.
The second row of Data encapsulates the HCI package in the bcsp data packet:
Previous part: C0 D1 65 01 C8:
C0: the delimiter of bcsp data packets.
D1: Type: reliable link data stream with CRC verification
65 01: Channel 5 (HCI cmd), with a length of 0x16
C8: Check of Baotou
Later Part: 69 A6 C0:
69 A6: CRC verification for the entire bcsp package
C0: Separator
Similar Analysis of other commands is available.
If you only want to see the HCI command itself, you can also use hcidump. Here is the dump operated by the above pskey operation through the HCI interface:
<HCI command: vendor (0x3f | 0x0000) Plen 19
Bccmd: Get Req: Len 9 seqno 1 varid 0x7003 status 0
Pskey: Key 0x01be Len 1 Stores 0x0000
Uart_baudrate: Value 0 (0x0000)
8.4 hid/serial/HF/obex
These commonly used profiles have not been tested yet ...... Who bought me a Bluetooth mouse ?!
8.5 total remaining issues
As a whole, automatic identification and Automatic startup of services on the PC have not been carefully studied.