How to enable Bluetooth serial profile (SPP) in headless Raspberry Pi Zero W.

Raspberry Pi running without connecting display(monitor), keyboard/mouse (USB) and accessing it through SSH or serial console is called headless configuration. We have blog post https://c2plabs.com/blog/2019/04/23/enable-serial-console-on-raspberry-pi-zero-w/ which explains how to enable serial console( UART console) on Raspberry Pi. When Linux OS booting is complete you can login to shell to give commands. During initial boot configure Wifi on Raspberry Pi, Wifi configuration on Raspberry Pi allows the device to connect using SSH from host computer. How to enable wireless network( WiFi) on Raspberry Pi is explained in https://c2plabs.com/blog/2019/04/25/wifi-configuration-on-raspberry-pi-zero-w/.

Operating systems like Linux, Android, Windows comes with Bluetooth daemon/ Bluetooth Service which is launched during booting. In the case of devices connected with monitor and running with GUI like GTK etc, it is easy to enable and connect to near by device with multiple clicks. But in the case of headless devices we have to depends on different commands which needs to be run on command line. This blog we will discuss how to connect near by Bluetooth device on headless Raspberry Pi.

We are using Raspberry Pi zero W booting with Raspberry OS from SD Card. Bluetooth initialization can be observed from Linux kernel log (dmesg command can be used to get the log) Log is as shown below.

[   17.687116] Bluetooth: HCI device and connection manager initialized
[   17.687145] Bluetooth: HCI socket layer initialized
[   17.687160] Bluetooth: L2CAP socket layer initialized
[   17.687212] Bluetooth: SCO socket layer initialized
[   17.716882] Bluetooth: HCI UART driver ver 2.3
[   17.716900] Bluetooth: HCI UART protocol H4 registered
[   17.716906] Bluetooth: HCI UART protocol Three-wire (H5) registered
[   17.721337] Bluetooth: HCI UART protocol Broadcom registered
[   18.110587] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
[   18.110610] brcmfmac: power management disabled
[   18.305415] random: crng init done
[   18.305437] random: 7 urandom warning(s) missed due to ratelimiting
[   18.930110] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[   18.930125] Bluetooth: BNEP filters: protocol multicast
[   18.930157] Bluetooth: BNEP socket layer initialized
[   19.600828] Bluetooth: RFCOMM TTY layer initialized
[   19.600869] Bluetooth: RFCOMM socket layer initialized
[   19.600913] Bluetooth: RFCOMM ver 1.11
[   19.835529] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
[   27.956223] fuse init (API version 7.26)

Above log indicates that all the bluetooth protocls like HCI, L2CAP and RFCOMM are initialized from Kernel Bluetooth stack. Linux user-space comes with tools/utilities to work with Bluetooth devices, hciconfig is similar to ifconfig to list the Bluetooth devices. This command gives BD (Bluetooth Device) address B8:27:EB:84:04:07, status of the device UP RUNNING. The output of the hciconfig is shown below on my RPI device.

pi@raspberrypi:~$ hciconfig 
hci0:	Type: Primary  Bus: UART
	BD Address: B8:27:EB:84:04:07  ACL MTU: 1021:8  SCO MTU: 64:1
	UP RUNNING 
	RX bytes:794 acl:0 sco:0 events:53 errors:0
	TX bytes:3491 acl:0 sco:0 commands:53 errors:0

hcitool is another command used to scan the near by devices, control the local device. This command has multiple command options. hcitool scan is used to scan nearby Bluetooth devices. The output of scan is shown below.

pi@raspberrypi:~$ hcitool scan 
Scanning ...
	08:25:25:D3:AF:F3	my phone
	E0:57:37:D3:00:5E	X_Smart_Box_001

hcitool scan shows the nearby devices with BD address and its name. After getting the details of the nearby devices you can get more details using info option, The output of hcitool with info option is shown below.

pi@raspberrypi:~$ sudo hcitool info 08:25:25:DC:AB:F3
Requesting information ...
	BD Address:  08:25:25:D3:AF:F3
	Device Name: my phone
	LMP Version:  (0x9) LMP Subversion: 0x2be
	Manufacturer: Qualcomm (29)
	Features page 0: 0xff 0xfe 0x8f 0xfe 0xd8 0x3f 0x5b 0x87
		<3-slot packets> <5-slot packets> <encryption> <slot offset> 
		<timing accuracy> <role switch> <hold mode> <sniff mode> 
		<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> <AFH cap. slave> <AFH class. slave> 
		<LE support> <3-slot EDR ACL> <5-slot EDR ACL> 
		<sniff subrating> <pause encryption> <AFH cap. master> 
		<AFH class. master> <EDR eSCO 2 Mbps> <extended inquiry> 
		<LE and BR/EDR> <simple pairing> <encapsulated PDU> 
		<non-flush flag> <LSTO> <inquiry TX power> <EPC> 
		<extended features> 
	Features page 1: 0x0f 0x00 0x00 0x00 0x00 0x00 0x00 0x00
	Features page 2: 0x55 0x03 0x00 0x00 0x00 0x00 0x00 0x00

Linux Bluetooth Stack:

Bluetooth stack in Linux kernel has multiple layers as shown in the below fig. Bluetooth controllers are connected to host using USB/UART interface. These Bluetooth devices use HCI (host controller Interface) protocol to communicate with HOST. Above HCI there is L2CAP layer and RFCOMM protocol layer. These layers are corresponding to network (IP) and Transport(TCP) layers of OSI or TCP/IP protocol stack. Linux kernel provides socket interface for user space application to directly interact with L2CAP and RFCOMM layers ex: BTPROTO_L2CAP, BTPROTO_RFCOMM etc.

Many applications called BT profiles are developed based on the protocols mentioned above.One of the popular profile is btspp which is serial port (UART) protocol over bluetooth. This is used when Raspberry Pi needs to interact with robots built based on HC-05 based bluetooth devices.

Linux OS Bluetooth Stack

How to configure Bluetooth Serial Port:

Service discovery protocol (SDP) is an application layer protocol based on L2CAP SOCKET for discovering different services offered by near by Bluetooth device. Linux Bluetooth stack comes with different commands along with hcitool, hciconfig etc .. sdptool is one such command used to get the different services offered by near by Bluetooth devices.

We are searching service from nearby device with device address 08:25:25:DC:AB:F3 for service with UUID 0x1101. This is the UUID for serial port profile or btspp, output of sdptool search command is as shown below.

pi@raspberrypi:~$ sdptool search  --bdaddr 08:25:25:DC:AB:F3 0x1101
Class 0x1101
Searching for 0x1101 on 08:25:25:DC:AB:F3 ...
pi@raspberrypi:~$ 
pi@raspberrypi:~$ sdptool search  --bdaddr 08:25:25:DC:AB:F3 0x1101
Class 0x1101
Searching for 0x1101 on 08:25:25:DC:AB:F3 ...
pi@raspberrypi:~$ sdptool search  --bdaddr E0:37:17:D7:00:5E 0x1101
Class 0x1101
Searching for 0x1101 on E0:37:17:D7:00:5E ...
Service Name: btspp
Service RecHandle: 0x10008
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 3
Profile Descriptor List:
  "Serial Port" (0x1101)
    Version: 0x0102

Create a rfcomm.conf file in /etc/bluetooth/ director as shown blow. This file is used by rfcomm command to parse while connecting remote device.

rfcomm0 {
        #  Bind the device at startup
       bind no;

         # Remote device Bluetooth address

       device E0:37:17:D7:00:5E;

       # RFCOMM channel this info we can get from sdptool browse

       channel 3;

       # Description of the connection

       comment “Bluetooth Serial port”;

}

After creating above file, use rfcomm bind command to bind the device to BD address and channel. This command take Bluetooth device address BD address and channel as argument. After executing this command device node /dev/rfcomm0 device is created by udev.

pi@raspberrypi:~$ sudo rfcomm bind 0 E0:37:17:D7:00:5E 3

pi@raspberrypi:~$ ls -la /dev/rfcomm0
crw-rw—- 1 root dialout 216, 0 Oct 4 08:24 /dev/rfcomm0

This device is used with minicom/Kermit kind of serial terminal to communicate with remote device.

Leave a Reply

Your email address will not be published. Required fields are marked *