Skip to content

Commit

Permalink
drv/bluetooth_stm32_bluenrg: new random address on each reset
Browse files Browse the repository at this point in the history
The BlueNRG-MS chip always uses the same random address. We would like
to use a new random address on each reset to work around BlueZ bugs
like Chrome causing duplicate notifications after a device disconnects.

Issue: pybricks/support#600
  • Loading branch information
dlech committed Oct 20, 2022
1 parent c17c33f commit d92f48f
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 30 deletions.
47 changes: 19 additions & 28 deletions lib/BlueNRG-MS/hci/hci_le.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,29 +250,30 @@ int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup)
return status;
}

int hci_le_rand(uint8_t random_number[8])
void hci_le_rand_begin(void)
{
struct hci_request_and_response rq;
le_rand_rp resp;

memset(&resp, 0, sizeof(resp));
struct hci_request rq;

memset(&rq, 0, sizeof(rq));
rq.opcode = cmd_opcode_pack(OGF_LE_CTL, OCF_LE_RAND);
rq.cparam = NULL;
rq.clen = 0;
rq.rparam = &resp;
rq.rlen = LE_RAND_RP_SIZE;

hci_send_req_recv_rsp(&rq);
hci_send_req(&rq);
}

if (resp.status) {
return resp.status;
}
tBleStatus hci_le_rand_end(uint8_t *random_number)
{
struct hci_response rq;
le_rand_rp resp;

memcpy(random_number, resp.random, 8);
rq.rparam = &resp;
rq.rlen = sizeof(resp);

return 0;
hci_recv_resp(&rq);

memcpy(random_number, resp.random, sizeof(resp.random));

return resp.status;
}

void hci_le_set_scan_response_data_begin(uint8_t length, const uint8_t *data)
Expand Down Expand Up @@ -317,25 +318,15 @@ int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level)
return 0;
}

int hci_le_set_random_address(tBDAddr bdaddr)
void hci_le_set_random_address_begin(tBDAddr bdaddr)
{
struct hci_request_and_response rq;
le_set_random_address_cp set_rand_addr_cp;
uint8_t status;

memset(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp));
memcpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr));
struct hci_request rq;

memset(&rq, 0, sizeof(rq));
rq.opcode = cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_RANDOM_ADDRESS);
rq.cparam = &set_rand_addr_cp;
rq.cparam = bdaddr;
rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE;
rq.rparam = &status;
rq.rlen = 1;

hci_send_req_recv_rsp(&rq);

return status;
hci_send_req(&rq);
}

int hci_read_bd_addr(tBDAddr bdaddr)
Expand Down
6 changes: 4 additions & 2 deletions lib/BlueNRG-MS/includes/hci_le.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,15 @@ void hci_le_set_advertising_data_begin(uint8_t length, const uint8_t *data);
void hci_le_set_scan_response_data_begin(uint8_t length, const uint8_t *data);
#define hci_le_set_scan_response_data_end hci_le_command_end

int hci_le_rand(uint8_t random_number[8]);
void hci_le_rand_begin(void);
tBleStatus hci_le_rand_end(uint8_t *random_number);

int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level);

int hci_acl_data(const uint8_t * data, uint16_t len);

int hci_le_set_random_address(tBDAddr bdaddr);
void hci_le_set_random_address_begin(tBDAddr bdaddr);
#define hci_le_set_random_address_end hci_le_command_end

int hci_read_bd_addr(tBDAddr bdaddr);

Expand Down
19 changes: 19 additions & 0 deletions lib/pbio/drv/bluetooth/bluetooth_stm32_bluenrg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,25 @@ static PT_THREAD(hci_init(struct pt *pt)) {
PT_WAIT_UNTIL(pt, hci_command_complete);
aci_gatt_update_char_value_end();

// The chip always uses the same random address, so we have to generate
// an actually random one to get a new address each time. This must be
// called after aci_gap_init to take effect.

// STM32F0 doesn't have a random number generator, so we use the bluetooth
// chip to get some random bytes.
hci_le_rand_begin();
PT_WAIT_UNTIL(pt, hci_command_complete);
{
uint8_t rand_buf[8];
hci_le_rand_end(rand_buf);

// hard-coding MSB to meet requirements of static random address
rand_buf[5] = 0xF0;
hci_le_set_random_address_begin(rand_buf);
}
PT_WAIT_UNTIL(pt, hci_command_complete);
hci_le_set_random_address_end();

PT_END(pt);
}

Expand Down

0 comments on commit d92f48f

Please sign in to comment.