--- wikisrc/guide/bluetooth.mdwn 2015/06/19 19:18:30 1.3 +++ wikisrc/guide/bluetooth.mdwn 2021/04/12 13:15:02 1.4 @@ -1,706 +1,2 @@ -**Contents** - -[[!toc levels=3]] - -# Bluetooth on NetBSD - -## Introduction - -Bluetooth is a digital radio protocol used for short range and low power -communications. NetBSD 4.0 introduced support for the Bluetooth protocol stack, -and some integration of service profiles into the NetBSD device framework. - -The lower layers of the Bluetooth protocol stack pertaining to actual radio -links between devices are handled inside the Bluetooth Controller, which -communicates with the Host computer using the *Host Controller Interface* (HCI) -protocol which can be accessed via a raw packet BTPROTO\_HCI socket interface. - -Most of the Bluetooth protocols or services layer atop the *Link Layer Control -and Adaptation Protocol (L2CAP)*, which can be accessed via a BTPROTO\_L2CAP -socket interface. This provides sequential packet connections to remote devices, -with up to 64k channels. When an L2CAP channel is opened, the protocol or -service that is required is identified by a *Protocol/Service Multiplexer (PSM)* -value. - -Service Discovery in the Bluetooth environment is provided for by the -[[!template id=man name="sdp" section="3"]] library -functions and the -[[!template id=man name="sdpd" section="8"]] daemon, -which keeps a database of locally registered services and makes the information -available to remote devices performing queries. The -[[!template id=man name="sdpquery" section="1"]] -tool can be used to query local and remote service databases. - -Security on Bluetooth links can be enabled by encryption and authentication -options to -[[!template id=man name="btconfig" section="8"]] -which apply to all baseband links that a controller makes, or encryption and -authentication can be enabled for individual RFCOMM and L2CAP links as required. -When authentication is requested, a PIN is presented by each side (generally -entered by the operator, some limited input devices have a fixed PIN). The -controller uses this PIN to generate a Link Key and reports this to the Host -which may be asked to produce it to authenticate subsequent connections. On -NetBSD, the -[[!template id=man name="bthcid" section="8"]] -daemon is responsible for storing link keys and responding to Link Key Requests, -and also provides an interface to allow unprivileged users to specify a PIN with -a PIN client, such as -[[!template id=man name="btpin" section="1"]]. - -## Supported Hardware - -Because Bluetooth controllers normally use the standard HCI protocol as -specified in the *Bluetooth 2.0 Core* documentation to communicate with the -host, the NetBSD Bluetooth stack is compatible with most controllers, only -requiring an interface driver, with the following drivers available in NetBSD -5.0: - - * [[!template id=man name="bcsp" section="4"]] - provides a - [[!template id=man name="tty" section="4"]] line - discipline to send and receive BlueCore Serial Protocol packets over a serial - line as described in the *BlueCore Serial Protocol (BCSP)* specification. - * [[!template id=man name="bt3c" section="4"]] - provides an interface to the 3Com Bluetooth PC Card, model 3CRWB6096-A. - * [[!template id=man name="btbc" section="4"]] - provides support for the AnyCom BlueCard (LSE041, LSE039, LSE139) PCMCIA - devices. - * [[!template id=man name="btuart" section="4"]] - provides a - [[!template id=man name="tty" section="4"]] line - discipline to send and receive Bluetooth packets over a serial line as - described in the *Bluetooth Host Controller Interface [Transport Layer] - specification, Vol 4 part A*. - * [[!template id=man name="sbt" section="4"]] - provides support for Secure Digital IO Bluetooth adapters. - * [[!template id=man name="ubt" section="4"]] - interfaces to all USB Bluetooth controllers conforming to the *HCI USB - Transport Layer* specification. - -If support for the NetBSD Bluetooth stack is enabled in the kernel, -autoconfiguration messages will show up in the -[[!template id=man name="dmesg" section="8"]] -output, for example: - - bt3c0 at pcmcia0 function 0: <3COM, 3CRWB60-A, Bluetooth PC Card> - - ubt0 at uhub1 port 4 configuration 1 interface 0 - ubt0: Cambridge Silicon Radio Bluetooth USB Adapter, rev 2.00/19.58, addr 4 - - ubt1 at uhub1 port 2 configuration 1 interface 0 - ubt1: Broadcom Belkin Bluetooth Device, rev 1.10/0.01, addr 5 - -When support is not already compiled in, it can be added to the kernel -configuration file for any platform that supports USB and/or PCMCIA (see -[[Kernel Tuning|guide/tuning]]), using the following declarations, as required: - - # Bluetooth Controller and Device support - - pseudo-device bcsp # BlueCore Serial Protocol - pseudo-device btuart # Bluetooth HCI UART - - # Bluetooth PCMCIA Controllers - bt3c* at pcmcia? function ? # 3Com 3CRWB6096-A - btbc* at pcmcia? function ? # AnyCom BlueCard LSE041/039/139 - - # Bluetooth SDIO Controllers - sbt* at sdmmc? - - # Bluetooth USB Controllers - ubt* at uhub? port ? - - # Bluetooth Device Hub - bthub* at bcsp? - bthub* at bt3c? - bthub* at btbc? - bthub* at btuart? - bthub* at sbt? - bthub* at ubt? - - # Bluetooth HID support - bthidev* at bthub? - - # Bluetooth Mouse - btms* at bthidev? reportid ? - wsmouse* at btms? mux 0 - - # Bluetooth Keyboard - btkbd* at bthidev? reportid ? - wskbd* at btkbd? console ? mux 1 - - # Bluetooth Audio support - btsco* at bthub? - - -Some older USB Bluetooth dongles based on the Broadcom BCM2033 chip require -firmware to be loaded before they can function, and these devices will be -attached to -[[!template id=man name="ugen" section="4"]]. Use -the `sysutils/bcmfw` package from the NetBSD Package Collection, to load -firmware and enable these. - -## System Configuration - -To fully enable Bluetooth services on NetBSD, the following line should be added -to the `/etc/rc.conf` file. - - bluetooth=YES - -and either reboot, or execute the following command: - - # /etc/rc.d/bluetooth start - -*Note*: Configuration of Bluetooth controllers is done with the -[[!template id=man name="btconfig" section="8"]] -program, and the above argument enables only basic functionality, see the manual -page for other useful options. - -**Important**: -[[!template id=man name="bthcid" section="8"]] -*must* be running in order to make authenticated connections with remote -devices, and authentication may be requested by either device. - -## Human Interface Devices - -Support for *Human Interface Devices (HIDs)*, which operate using the USB HID -protocol over a pair of L2CAP channels is provided by the -[[!template id=man name="bthidev" section="4"]] -driver. Currently, keyboards and mice are catered for, and attach to -[[!template id=man name="wscons" section="4"]] as -normal. - -### Mice - -Bluetooth Mice can be attached to the system with the -[[!template id=man name="btms" section="4"]] driver, -using -[[!template id=man name="btdevctl" section="8"]]. - -First, you must discover the BDADDR of the device. This may be printed on the -box, but the easiest way is to place the device into discoverable mode and -perform a device inquiry with the appropriate controller: - - # btconfig ubt0 inquiry - Device Discovery on ubt0 .... 1 response - 1: bdaddr 00:14:51:c1:b9:2d (unknown) - : name "Mighty Mouse" - : class: [0x002580] Peripheral Mouse - : page scan rep mode 0x01 - : page scan period mode 0x02 - : page scan mode 0x00 - : clock offset 6944 - -For ease of use, you may want to add the address to the `/etc/bluetooth/hosts` -file, so that you can refer to the mouse by alias: - - # echo "00:14:51:c1:b9:2d mouse" >>/etc/bluetooth/hosts - -Now, you can query the mouse, which will likely request authentication before it -accepts connections. The fixed PIN should be listed in the documentation, though -`0000` is often used. Set the PIN first using the -[[!template id=man name="btpin" section="1"]] -program: - - # btpin -d ubt0 -a mouse -p 0000 - # btdevctl -d ubt0 -a mouse -s HID - local bdaddr: 00:08:1b:8d:ba:6d - remote bdaddr: 00:14:51:c1:b9:2d - link mode: auth - device type: bthidev - control psm: 0x0011 - interrupt psm: 0x0013 - Collection page=Generic_Desktop usage=Mouse - Input id=2 size=1 count=1 page=Button usage=Button_1 Variable, logical range 0..1 - Input id=2 size=1 count=1 page=Button usage=Button_2 Variable, logical range 0..1 - Input id=2 size=1 count=1 page=Button usage=Button_3 Variable, logical range 0..1 - Input id=2 size=1 count=1 page=Button usage=Button_4 Variable, logical range 0..1 - Input id=2 size=4 count=1 page=0x0000 usage=0x0000 Const Variable, logical range 0..1 - Collection page=Generic_Desktop usage=Pointer - Input id=2 size=8 count=1 page=Generic_Desktop usage=X Variable Relative, logical range -127..127 - Input id=2 size=8 count=1 page=Generic_Desktop usage=Y Variable Relative, logical range -127..127 - Input id=2 size=8 count=1 page=Consumer usage=AC_Pan Variable Relative, logical range -127..127 - Input id=2 size=8 count=1 page=Generic_Desktop usage=Wheel Variable Relative, logical range -127..127 - End collection - Input id=2 size=8 count=1 page=0x00ff usage=0x00c0 Variable, logical range -127..127 - Feature id=71 size=8 count=1 page=0x0006 usage=0x0020 Variable NoPref Volatile, logical range 0..100 - End collection - -This tells you that the mouse has responded to an SDP query, and the device -capabilities are shown. Note that authentication is enabled by default for -Bluetooth mice. You may now attach to the system: - - # btdevctl -d ubt0 -a mouse -s HID -A - -which should generate some messages on the system console: - - bthidev0 at bthub0 remote-bdaddr 00:14:51:c1:b9:2d link-mode auth - btms0 at bthidev1 reportid 2: 4 buttons, W and Z dirs. - wsmouse1 at btms0 mux 0 - bthidev1: reportid 71 not configured - bthidev1: connected - -and the mouse should work. - -The device capabilities are cached by -[[!template id=man name="btdevctl" section="8"]], -and to reattach the mouse at system startup, place an entry in -`/etc/bluetooth/btdevctl.conf`. The -[[!template id=man name="bthidev" section="4"]] -driver will attempt to connect once, though mice will usually be sleeping and -may require a tap on the shoulder to awaken, in which case they should initiate -the connection to the host computer. - -### Keyboards - -Bluetooth Keyboards can be attached to the system with the -[[!template id=man name="btkbd" section="4"]] -driver, using -[[!template id=man name="btdevctl" section="8"]]. - -First, you must discover the BDADDR of the device. This may be printed on the -box, but the easiest way is to place the device into discoverable mode and -perform a device inquiry with the appropriate controller: - - # btconfig ubt0 inquiry - Device Discovery on ubt0 .... 1 response - 1: bdaddr 00:0a:95:45:a4:a0 (unknown) - : name "Apple Wireless Keyboard" - : class: [0x002540] Peripheral Keyboard - : page scan rep mode 0x01 - : page scan period mode 0x00 - : page scan mode 0x00 - : clock offset 18604 - -For ease of use, you may want to add the address to the `/etc/bluetooth/hosts` -file, so that you can refer to the keyboard by alias: - - # echo "00:0a:95:45:a4:a0 keyboard" >>/etc/bluetooth/hosts - -Now, you can query the keyboard, which will likely request authentication before -it accepts connections. The PIN will need to be entered on the keyboard, and we -can generate a random PIN, using the -[[!template id=man name="btpin" section="1"]] -program. - - # btpin -d ubt0 -a keyboard -r -l 8 - PIN: 18799632 - # btdevctl -d ubt0 -a keyboard -s HID - - < ENTER PIN ON BLUETOOTH KEYBOARD NOW > - - local bdaddr: 00:08:1b:8d:ba:6d - remote bdaddr: 00:0a:95:45:a4:a0 - link mode: encrypt - device type: bthidev - control psm: 0x0011 - interrupt psm: 0x0013 - Collection page=Generic_Desktop usage=Keyboard - Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_LeftControl Variable, logical range 0..1 - Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_LeftShift Variable, logical range 0..1 - Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_LeftAlt Variable, logical range 0..1 - Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_Left_GUI Variable, logical range 0..1 - Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_RightControl Variable, logical range 0..1 - Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_RightShift Variable, logical range 0..1 - Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_RightAlt Variable, logical range 0..1 - Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_Right_GUI Variable, logical range 0..1 - Input id=1 size=8 count=1 page=0x0000 usage=0x0000 Const, logical range 0..1 - Output id=1 size=1 count=1 page=LEDs usage=Num_Lock Variable, logical range 0..1 - Output id=1 size=1 count=1 page=LEDs usage=Caps_Lock Variable, logical range 0..1 - Output id=1 size=1 count=1 page=LEDs usage=Scroll_Lock Variable, logical range 0..1 - Output id=1 size=1 count=1 page=LEDs usage=Compose Variable, logical range 0..1 - Output id=1 size=1 count=1 page=LEDs usage=Kana Variable, logical range 0..1 - Output id=1 size=3 count=1 page=0x0000 usage=0x0000 Const, logical range 0..1 - Input id=1 size=8 count=6 page=Keyboard usage=No_Event, logical range 0..255 - Input id=1 size=1 count=1 page=Consumer usage=Eject Variable Relative, logical range 0..1 - Input id=1 size=1 count=1 page=Consumer usage=Mute Variable Relative, logical range 0..1 - Input id=1 size=1 count=1 page=Consumer usage=Volume_Up Variable, logical range 0..1 - Input id=1 size=1 count=1 page=Consumer usage=Volume_Down Variable, logical range 0..1 - Input id=1 size=1 count=4 page=0x0000 usage=0x0000 Const, logical range 0..1 - End collection - - -This tells you that the keyboard has responded to an SDP query, and the device -capabilities are shown. Note that encryption is enabled by default, since -encrypted connection support is mandatory for Bluetooth keyboards. You may now -attach to the system: - - # btdevctl -d ubt0 -a keyboard -s HID -A - -which should generate some messages on the system console: - - bthidev1 at bthub0 remote-bdaddr 00:0a:95:45:a4:a0 link-mode encrypt - btkbd0 at bthidev0 reportid 1 - wskbd1 at btkbd0 mux 1 - wskbd1: connecting to wsdisplay0 - bthidev1: connected - -and the keyboard should work. - -The device capabilities are cached by -[[!template id=man name="btdevctl" section="8"]], -and to reattach the keyboard at system startup, place an entry in -`/etc/bluetooth/btdevctl.conf`. The -[[!template id=man name="bthidev" section="4"]] -driver will attempt to connect once when attached, but if the keyboard is not -available at that time, you may find that pressing a key will cause it to wake -up and initiate a connection to the last paired host. - -## Personal Area Networking - -Personal Area Networking services over Bluetooth are provided by the -[[!template id=man name="btpand" section="8"]] -daemon which can assume all roles from the PAN profile and connects remote -devices to the system through a -[[!template id=man name="tap" section="4"]] virtual -Ethernet interface. - -### Personal Area Networking User - -The "Personal Area Networking User" role is the client that accesses Network -services on another device. For instance, in order to connect to the Internet -via a smart phone with the NAP profile, make sure that the phone is -discoverable, then: - - # btconfig ubt0 inquiry - Device Discovery from device: ubt0 .... 1 response - 1: bdaddr 00:17:83:30:bd:5e (unknown) - : name "HTC Touch" - : class: [0x5a020c] Smart Phone - - : page scan rep mode 0x01 - : clock offset 9769 - : rssi -42 - - # echo "00:17:83:30:bd:5e phone" >>/etc/bluetooth/hosts - -You will see that the phone should have the `` flag set in the Class -of Device. Checking for the NAP service: - - # sdpquery -a phone search NAP - ServiceRecordHandle: 0x00010000 - ServiceClassIDList: - Network Access Point - ProtocolDescriptorList: - L2CAP (PSM 0x000f) - BNEP (v1.0; IPv4, ARP, IPv6) - LanguageBaseAttributeIDList: - en.UTF-8 base 0x0100 - BluetoothProfileDescriptorList: - Network Access Point, v1.0 - ServiceName: "Network Access Point" - ServiceDescription: "Bluetooth NAP Service" - SecurityDescription: None - NetAccessType: 100Mb Ethernet - MaxNetAccessRate: 100000 - -reveals that the NAP service is available and that it provides IPv4, ARP and IPv6 protocols. - -Most likely, the phone will request authentication before it allows connections -to the NAP service, so before you make the first connection you may need to -provide a PIN, which can be randomly generated. Then start -[[!template id=man name="btpand" section="8"]]: - - # btpin -d ubt0 -a phone -r -l 6 - PIN: 862048 - # btpand -d ubt0 -a phone -s NAP - - < ENTER PIN ON PHONE NOW > - - Searching for NAP service at 00:17:83:30:bd:5e - Found PSM 15 for service NAP - Opening connection to service 0x1116 at 00:17:83:30:bd:5e - Using interface tap0 with addr 00:10:60:e1:50:3d - -Finally, you will need to configure the -[[!template id=man name="tap" section="4"]] -interface, but the phone should have a DHCP server so -[[!template id=man name="dhcpcd" section="8"]] -will do that for you. - - # dhcpcd tap0 - -Now you can surf the World Wide Web, but watch your data usage unless you have a -comprehensive data plan. - -## Serial Connections - -Serial connections over Bluetooth are provided for by the RFCOMM protocol, which -provides up to 30 channels multiplexed over a single L2CAP channel. This -streamed data protocol can be accessed using the BTPROTO\_RFCOMM socket -interface, or via the -[[!template id=man name="rfcomm\_sppd" section="1"]] -program. - -For instance, you can make a serial connection to the *Dial Up Networking (DUN)* -service of a mobile phone in order to connect to the Internet with PPP. First -you should discover the BDADDR of the phone, and add this to your -`/etc/bluetooth/hosts` for ease of use. Place the phone into Discoverable mode, -and perform an inquiry from the appropriate controller: - - # btconfig ubt0 inquiry - Device Discovery from device: ubt0 ..... 1 response - 1: bdaddr 00:16:bc:00:e8:48 (unknown) - : name "Nokia 6103" - : class: [0x520204] Cellular Phone - : page scan rep mode 0x01 - : page scan period mode 0x02 - : page scan mode 0x00 - : clock offset 30269 - - # echo "00:16:bc:00:e8:48 phone" >>/etc/bluetooth/hosts - -Now, you can query the phone to confirm that it supports the DUN profile: - - # sdpquery -d ubt0 -a phone search DUN - ServiceRecordHandle: 0x00010003 - ServiceClassIDList: - Dialup Networking - Generic Networking - ProtocolDescriptorList: - L2CAP - RFCOMM (channel 1) - BrowseGroupList: - Public Browse Root - LanguageBaseAttributeIDList: - en.UTF-8 base 0x0100 - BluetoothProfileDescriptorList: - Dialup Networking, v1.0 - ServiceName: "Dial-up networking" - -Most likely, the phone will request authentication before it allows connections -to the DUN service, so before you make the first connection you may need to -provide a PIN, which can be randomly generated. You can use `rfcomm_sppd` in -stdio mode to check that the connection is working ok, press `^C` to -disconnect and return to the shell, for example: - - # btpin -d ubt0 -a phone -r -l 6 - PIN: 904046 - # rfcomm_sppd -d ubt0 -a phone -s DUN - - < ENTER PIN ON PHONE NOW > - - rfcomm_sppd[24635]: Starting on stdio... - at - OK - ati - Nokia - - OK - ati3 - Nokia 6103 - - OK - at&v - ACTIVE PROFILE: - E1 Q0 V1 X5 &C1 &D2 &S0 &Y0 - +CMEE=0 +CSTA=129 +CBST=0,0,1 +CRLP=61,61,48,6 +CR=0 +CRC=0 +CLIP=0,2 - +CLIR=0,2 +CSNS=0 +CVHU=1 +DS=0,0,2048,32 +DR=0 +ILRR=0 - +CHSN=0,0,0,0 +CHSR=0 +CPBS="SM" - S00:000 S01:000 S02:043 S03:013 S04:010 S05:008 S07:060 S08:002 - S10:100 S12:050 S25:000 - - OK - ^C - rfcomm_sppd[24635]: Completed on stdio - -To have [[!template id=man name="pppd" section="8"]] -connect to the DUN service of your phone automatically when making outbound -connections, add the following line to the `/etc/ppp/options` file in place of -the normal tty declaration: - - pty "rfcomm_sppd -d ubt0 -a phone -s DUN -m encrypt" - -## Audio - -Isochronous (SCO) Audio connections may be created on a baseband radio link -using either the BTPROTO\_SCO socket interface, or the -[[!template id=man name="btsco" section="4"]] audio -device driver. While the specification says that up to three such links can be -made between devices, the current Bluetooth stack can only handle one with any -dignity. - -**Important**: When using SCO Audio with USB Bluetooth controllers, you will -need to enable isochronous data, and calculate the MTU that the device will use, -see [[!template id=man name="ubt" section="4"]] and -[[!template id=man name="btconfig" section="8"]]. - -*Note*: SCO Audio does not work properly with the -[[!template id=man name="bt3c" section="4"]] driver, -use a USB controller for best results. - -*Note*: SCO Audio will not work with -[[!template id=man name="ehci" section="4"]] USB -controllers, since support for Isochronous data over EHCI is missing in NetBSD. - -### SCO Audio Headsets - -Audio connections to Bluetooth Headsets are possible using the -[[!template id=man name="btsco" section="4"]] audio -driver, and the -[[!template id=man name="bthset" section="1"]] -program. First, you need to discover the BDADDR of the headset, and will -probably wish to make an alias in your `/etc/bluetooth/hosts` file for ease of -use. Place the headset into discoverable mode and perform an inquiry with the -appropriate controller: - - # btconfig ubt0 inquiry - Device Discovery from device: ubt0 ..... 1 response - 1: bdaddr 00:07:a4:23:10:83 (unknown) - : name "JABRA 250" - : class: [0x200404] Wearable Headset