Skip to content

Commit aa09939

Browse files
dlechholtmann
authored andcommitted
Bluetooth: hci_ll: add support for setting public address
This adds support for setting the public address on Texas Instruments Bluetooth chips using a vendor-specific command. This has been tested on a CC2560A chip. The TI wiki also indicates that this command should work on TI WL17xx/WL18xx Bluetooth chips. During review, there was some question as to the correctness of the byte swapping since TI's documentation is not clear on this matter. This can be tested with the btmgmt utility from bluez. The adapter must be powered off to change the address. If the baswap() is omitted, address is reversed. In case there is a issue in the future, here is the output of btmon during the command `btmgmt public-addr 00:11:22:33:44:55`: Bluetooth monitor ver 5.43 = Note: Linux version 4.15.0-rc2-08561-gcb132a1-dirty (armv5tejl) 0.707043 = Note: Bluetooth subsystem version 2.22 0.707091 = New Index: 00:17:E7:BD:1C:8E (Primary,UART,hci0) [hci0] 0.707106 @ MGMT Open: btmgmt (privileged) version 1.14 {0x0002} 0.707124 @ MGMT Open: bluetoothd (privileged) version 1.14 {0x0001} 0.707137 @ MGMT Open: btmon (privileged) version 1.14 {0x0003} 0.707540 @ MGMT Command: Set Public Address (0x0039) plen 6 {0x0002} [hci0] 11.167991 Address: 00:11:22:33:44:55 (CIMSYS Inc) @ MGMT Event: Command Complete (0x0001) plen 7 {0x0002} [hci0] 11.175681 Set Public Address (0x0039) plen 4 Status: Success (0x00) Missing options: 0x00000000 @ MGMT Event: Index Removed (0x0005) plen 0 {0x0003} [hci0] 11.175757 @ MGMT Event: Index Removed (0x0005) plen 0 {0x0002} [hci0] 11.175757 @ MGMT Event: Index Removed (0x0005) plen 0 {0x0001} [hci0] 11.175757 = Open Index: 00:17:E7:BD:1C:8E [hci0] 11.176807 < HCI Command: Vendor (0x3f|0x0006) plen 6 [hci0] 11.176975 00 11 22 33 44 55 .."3DU > HCI Event: Command Complete (0x0e) plen 4 [hci0] 11.188260 Vendor (0x3f|0x0006) ncmd 1 Status: Success (0x00) ... < HCI Command: Read Local Version Info.. (0x04|0x0001) plen 0 [hci0] 11.189859 > HCI Event: Command Complete (0x0e) plen 12 [hci0] 11.190732 Read Local Version Information (0x04|0x0001) ncmd 1 Status: Success (0x00) HCI version: Bluetooth 2.1 (0x04) - Revision 0 (0x0000) LMP version: Bluetooth 2.1 (0x04) - Subversion 6431 (0x191f) Manufacturer: Texas Instruments Inc. (13) < HCI Command: Read BD ADDR (0x04|0x0009) plen 0 [hci0] 11.191027 > HCI Event: Command Complete (0x0e) plen 10 [hci0] 11.192101 Read BD ADDR (0x04|0x0009) ncmd 1 Status: Success (0x00) Address: 00:11:22:33:44:55 (CIMSYS Inc) ... Signed-off-by: David Lechner <david@lechnology.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
1 parent 94386b6 commit aa09939

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

drivers/bluetooth/hci_ll.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include "hci_uart.h"
5858

5959
/* Vendor-specific HCI commands */
60+
#define HCI_VS_WRITE_BD_ADDR 0xfc06
6061
#define HCI_VS_UPDATE_UART_HCI_BAUDRATE 0xff36
6162

6263
/* HCILL commands */
@@ -662,6 +663,24 @@ static int download_firmware(struct ll_device *lldev)
662663
return err;
663664
}
664665

666+
static int ll_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
667+
{
668+
bdaddr_t bdaddr_swapped;
669+
struct sk_buff *skb;
670+
671+
/* HCI_VS_WRITE_BD_ADDR (at least on a CC2560A chip) expects the BD
672+
* address to be MSB first, but bdaddr_t has the convention of being
673+
* LSB first.
674+
*/
675+
baswap(&bdaddr_swapped, bdaddr);
676+
skb = __hci_cmd_sync(hdev, HCI_VS_WRITE_BD_ADDR, sizeof(bdaddr_t),
677+
&bdaddr_swapped, HCI_INIT_TIMEOUT);
678+
if (!IS_ERR(skb))
679+
kfree_skb(skb);
680+
681+
return PTR_ERR_OR_ZERO(skb);
682+
}
683+
665684
static int ll_setup(struct hci_uart *hu)
666685
{
667686
int err, retry = 3;
@@ -674,6 +693,8 @@ static int ll_setup(struct hci_uart *hu)
674693

675694
lldev = serdev_device_get_drvdata(serdev);
676695

696+
hu->hdev->set_bdaddr = ll_set_bdaddr;
697+
677698
serdev_device_set_flow_control(serdev, true);
678699

679700
do {

0 commit comments

Comments
 (0)