Skip to content

Commit

Permalink
fix: HCI only Firmware not supporting ACI_GAP_INIT ACI_GATT_INIT
Browse files Browse the repository at this point in the history
On STM32WB, Cube FW version 1.14.1,
messages ACI_GATT_INIT and ACI_GAP_INIT
are not available on HCI only BLE firmware
(stm32wb5x_BLE_HCILayer_fw.bin)
This imply to move Random Address to host instead of relying on controller

Signed-off-by: Alexandre Bourdiol <[email protected]>
  • Loading branch information
ABOSTM committed Oct 25, 2022
1 parent f8d947b commit 1c8974d
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 211 deletions.
12 changes: 12 additions & 0 deletions src/local/BLELocalDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ int BLELocalDevice::begin()
return 0;
}

uint8_t randomNumber[8];
if (HCI.leRand(randomNumber) != 0) {
end();
return 0;
}

randomNumber[5] |= 0xC0; // Force both MSB bit to b00 in order to define Random Address
if (HCI.leSetRandomAddress((uint8_t*)randomNumber) != 0) {
end();
return 0;
}

uint8_t hciVer;
uint16_t hciRev;
uint8_t lmpVer;
Expand Down
12 changes: 12 additions & 0 deletions src/utility/HCI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#define OCF_LE_CREATE_CONN 0x000d
#define OCF_LE_CANCEL_CONN 0x000e
#define OCF_LE_CONN_UPDATE 0x0013
#define OCF_LE_RAND 0x0018

#define HCI_OE_USER_ENDED_CONNECTION 0x13

Expand Down Expand Up @@ -392,6 +393,17 @@ int HCIClass::leConnUpdate(uint16_t handle, uint16_t minInterval, uint16_t maxIn
return sendCommand(OGF_LE_CTL << 10 | OCF_LE_CONN_UPDATE, sizeof(leConnUpdateData), &leConnUpdateData);
}

int HCIClass::leRand(uint8_t randomNumber[8])
{
int result = sendCommand(OGF_LE_CTL << 10 | OCF_LE_RAND);

if (result == 0) {
memcpy(randomNumber, _cmdResponse, 8);
}

return result;
}

int HCIClass::sendAclPkt(uint16_t handle, uint8_t cid, uint8_t plen, void* data)
{
while (_pendingPkt >= _maxPkt) {
Expand Down
1 change: 1 addition & 0 deletions src/utility/HCI.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class HCIClass {
virtual int leConnUpdate(uint16_t handle, uint16_t minInterval, uint16_t maxInterval,
uint16_t latency, uint16_t supervisionTimeout);
virtual int leCancelConn();
virtual int leRand(uint8_t randomNumber[8]);


virtual int sendAclPkt(uint16_t handle, uint8_t cid, uint8_t plen, void* data);
Expand Down
214 changes: 8 additions & 206 deletions src/utility/HCISharedMemTransport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,12 @@ volatile uint16_t _write_index; /* fifo position when receiving */
/* var of different device steps during init and receiving */
volatile bool phase_bd_addr;
volatile bool phase_tx_power;
volatile bool phase_gatt_init;
volatile bool phase_gap_init;
volatile bool phase_random_addr;
volatile bool phase_get_random_addr;
volatile bool phase_reset;
volatile bool phase_running;
volatile bool is_random_addr_msg;


/** Bluetooth Device Address */
static uint8_t bd_addr_udn[CONFIG_DATA_PUBADDR_LEN];
static uint8_t helper_random_addr[6];

/* Private functions ---------------------------------------------------------*/
/**
Expand Down Expand Up @@ -186,16 +181,10 @@ void evt_received(TL_EvtPacket_t *hcievt)
(hcievt->evtserial.evt.payload[0] == 0x01) &&
(hcievt->evtserial.evt.payload[1] == 0x0C) &&
(hcievt->evtserial.evt.payload[2] == 0xFC)) {
/* First setting must be global address and is_random_addr_msg should be false
* Second setting must be static random address and is_random_addr_msg should be true
/* First setting must be global address
*/
if(!is_random_addr_msg) {
phase_bd_addr = true;
is_random_addr_msg = true;
} else {
phase_random_addr = true;
is_random_addr_msg = false;
}
phase_bd_addr = true;

if (hcievt->evtserial.evt.payload[3] != 0) {
#if defined(PRINT_IPCC_INFO)
printf("Error: wrong BD Addr\r\n");
Expand All @@ -218,50 +207,7 @@ void evt_received(TL_EvtPacket_t *hcievt)
/* rx data is no more useful : not stored in the _rxbuff */
break;
}
/* check the Rx event of complete the previous gatt init 0xFD01 */
if ((hcievt->evtserial.evt.evtcode == TL_BLEEVT_CC_OPCODE) &&
(hcievt->evtserial.evt.payload[0] == 0x01) &&
(hcievt->evtserial.evt.payload[1] == 0x01) &&
(hcievt->evtserial.evt.payload[2] == 0xFD)) {
phase_gatt_init = true;
if (hcievt->evtserial.evt.payload[3] != 0) {
#if defined(PRINT_IPCC_INFO)
printf("Error: wrong Random Addr\r\n");
#endif /*(PRINT_IPCC_INFO)*/
}
/* rx data is no more useful : not stored in the _rxbuff */
break;
}
/* check the Rx event of complete the previous gap init 0xFC8A */
if ((hcievt->evtserial.evt.evtcode == TL_BLEEVT_CC_OPCODE) &&
(hcievt->evtserial.evt.payload[0] == 0x01) &&
(hcievt->evtserial.evt.payload[1] == 0x8A) &&
(hcievt->evtserial.evt.payload[2] == 0xFC)) {
phase_gap_init = true;
if (hcievt->evtserial.evt.payload[3] != 0) {
#if defined(PRINT_IPCC_INFO)
printf("Error: wrong Random Addr\r\n");
#endif /*(PRINT_IPCC_INFO)*/
}
/* rx data is no more useful : not stored in the _rxbuff */
break;
}
/* check the Rx event of complete the previous get random addr opcode 0xFC0D */
if ((hcievt->evtserial.evt.evtcode == TL_BLEEVT_CC_OPCODE) &&
(hcievt->evtserial.evt.payload[0] == 0x01) &&
(hcievt->evtserial.evt.payload[1] == 0x0D) &&
(hcievt->evtserial.evt.payload[2] == 0xFC)) {
if (hcievt->evtserial.evt.payload[3] != 0) {
#if defined(PRINT_IPCC_INFO)
printf("Error: wrong Random Addr\r\n");
#endif /*(PRINT_IPCC_INFO)*/
}

memcpy(helper_random_addr, &hcievt->evtserial.evt.payload[5], 6);
phase_get_random_addr = true;
/* rx data is no more useful : not stored in the _rxbuff */
break;
}
/* check if the reset phase is in progress (opcode is 0x0C03) */
if ((hcievt->evtserial.evt.evtcode == TL_BLEEVT_CC_OPCODE) &&
(hcievt->evtserial.evt.payload[0] == 0x01) &&
Expand Down Expand Up @@ -391,10 +337,10 @@ static bool get_bd_address(uint8_t *bd_addr)

bd_addr[0] = (uint8_t)(udn & 0x000000FF);
bd_addr[1] = (uint8_t)((udn & 0x0000FF00) >> 8);
bd_addr[2] = (uint8_t)((udn & 0x00FF0000) >> 16);
bd_addr[3] = (uint8_t)device_id;
bd_addr[4] = (uint8_t)(company_id & 0x000000FF);
bd_addr[5] = (uint8_t)((company_id & 0x0000FF00) >> 8);
bd_addr[2] = (uint8_t)device_id;
bd_addr[3] = (uint8_t)(company_id & 0x000000FF);
bd_addr[4] = (uint8_t)((company_id & 0x0000FF00) >> 8);
bd_addr[5] = (uint8_t)((company_id & 0x00FF0000) >> 16);

bd_found = true;
} else {
Expand Down Expand Up @@ -448,13 +394,8 @@ HCISharedMemTransportClass::HCISharedMemTransportClass()

phase_bd_addr = false;
phase_tx_power = false;
phase_gatt_init = false;
phase_gap_init = false;
phase_random_addr = false;
phase_get_random_addr = false;
phase_reset = false;
phase_running = false;
is_random_addr_msg = false;
}

HCISharedMemTransportClass::~HCISharedMemTransportClass()
Expand Down Expand Up @@ -517,13 +458,8 @@ void HCISharedMemTransportClass::end()
/* the HCI RESET command ready to be processed again */
phase_bd_addr = false;
phase_tx_power = false;
phase_gatt_init = false;
phase_gap_init = false;
phase_random_addr = false;
phase_get_random_addr = false;
phase_reset = false;
phase_running = false;
is_random_addr_msg = false;
}

void HCISharedMemTransportClass::wait(unsigned long timeout)
Expand Down Expand Up @@ -614,34 +550,11 @@ size_t HCISharedMemTransportClass::write(const uint8_t *data, size_t length)
while (!phase_bd_addr);
/* this sequence is now complete */

/* set the random address */
bt_ipm_set_random_addr();
/* wait for the Rx complete */
while (!phase_random_addr);

/* set the Tx power */
bt_ipm_set_power();
/* wait for the Rx complete */
while (!phase_tx_power);

/* gatt init */
bt_ipm_gatt_init();
/* wait for the Rx complete */
while (!phase_gatt_init);

/* gap init */
bt_ipm_gap_init();
/* wait for the Rx complete */
while (!phase_gap_init);

/* get the random address */
bt_ipm_get_random_addr();
/* wait for the Rx complete */
while (!phase_get_random_addr);

/* Now we can copy the random address and save it in the transport class */
memcpy(_random_addr, helper_random_addr, 6);

/* this sequence is now complete */
phase_running = true;

Expand Down Expand Up @@ -831,43 +744,6 @@ int HCISharedMemTransportClass::bt_ipm_set_addr(void)
return 0; /* Error */
}

int HCISharedMemTransportClass::bt_ipm_set_random_addr(void)
{
/* the specific table for set addr is 8 bytes:
* one byte for config_offset
* one byte for length
* 6 bytes for payload */
uint8_t data[4 + 8];

/*
* Static random Address
* The two upper bits shall be set to 1
* The lowest 32bits is read from the UDN to differentiate between devices
* The RNG may be used to provide a random number on each power on
*/
uint32_t srd_bd_addr[2];

phase_random_addr = false;

srd_bd_addr[1] = 0x0000ED6E;
srd_bd_addr[0] = LL_FLASH_GetUDN( );

data[0] = BT_BUF_CMD;
data[1] = uint8_t(ACI_WRITE_CONFIG_DATA_OPCODE & 0x000000FF); /* OCF */
data[2] = uint8_t((ACI_WRITE_CONFIG_DATA_OPCODE & 0x0000FF00) >> 8); /* OGF */
data[3] = 8; /* length of parameters */
/* fill the ACI_HAL_WRITE_CONFIG_DATA with the addr*/
data[4] = 0x2E; /* the offset */
data[5] = 6; /* is the length of the random address */
memcpy(data + 6, srd_bd_addr, 6);
/* send the ACI_HAL_WRITE_CONFIG_DATA */
if (mbox_write(data[0], 11, &data[1]) != 11) {
/* Error: no data are written */
return 0;
}
/* now wait for the corresponding Rx event */
return 1; /* success */
}

int HCISharedMemTransportClass::bt_ipm_set_power(void)
{
Expand All @@ -894,78 +770,4 @@ int HCISharedMemTransportClass::bt_ipm_set_power(void)
return 1; /* success */
}

int HCISharedMemTransportClass::bt_ipm_gatt_init(void)
{
/* the specific table for gatt init */
uint8_t data[4];

phase_gatt_init = false;

data[0] = BT_BUF_CMD; /* the type */
data[1] = 0x01; /* the OPCODE */
data[2] = 0xFD;
data[3] = 0; /* the length */

/* send the GATT_INIT */
if (mbox_write(data[0], 3, &data[1]) != 3) {
/* Error: no data are written */
return 0;
}
/* now wait for the corresponding Rx event */
return 1; /* success */
}

int HCISharedMemTransportClass::bt_ipm_gap_init(void)
{
/* the specific table for gap init is 3 bytes:
* Role byte, enable_privacy byte, device_name_char_len byte */
uint8_t data[4 + 3];

phase_gap_init = false;

data[0] = BT_BUF_CMD; /* the type */
data[1] = 0x8A; /* the OPCODE */
data[2] = 0xFC;
data[3] = 3; /* the length */
/* fill the GAP_INIT */
data[4] = 0x0F; /* role */
data[5] = 0x00; /* enable_privacy */
data[6] = 0x00; /* device_name_char_len */

/* send the GAP_INIT */
if (mbox_write(data[0], 6, &data[1]) != 6) {
/* Error: no data are written */
return 0;
}
/* now wait for the corresponding Rx event */
return 1; /* success */
}

int HCISharedMemTransportClass::bt_ipm_get_random_addr(void)
{
/* the specific table for set addr is 8 bytes:
* one byte for config_offset
* one byte for length
* 6 bytes for payload */
uint8_t data[4 + 1];

phase_get_random_addr = false;

/* create ACI_READ_CONFIG_DATA_OPCODE */
data[0] = BT_BUF_CMD;
data[1] = uint8_t(ACI_READ_CONFIG_DATA_OPCODE & 0x000000FF); /* OCF */
data[2] = uint8_t((ACI_READ_CONFIG_DATA_OPCODE & 0x0000FF00) >> 8); /* OGF */
data[3] = 1; /* length of parameters */
/* fill the ACI_READ_CONFIG_DATA_OPCODE with the offset*/
data[4] = 0x2E; /* the offset */

/* send the ACI_READ_CONFIG_DATA_OPCODE */
if (mbox_write(data[0], 4, &data[1]) != 4) {
/* Error: no data are written */
return 0;
}
/* now wait for the corresponding Rx event */
return 1; /* success */
}

#endif /* STM32WBxx */
5 changes: 0 additions & 5 deletions src/utility/HCISharedMemTransport.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,8 @@ class HCISharedMemTransportClass : public HCITransportInterface {
void start_ble_rf(void);
void stm32wb_reset(void);
int stm32wb_start_ble(void);
int bt_ipm_ble_init(void);
int bt_ipm_set_addr(void);
int bt_ipm_set_random_addr(void);
int bt_ipm_set_power(void);
int bt_ipm_gatt_init(void);
int bt_ipm_gap_init(void);
int bt_ipm_get_random_addr(void);

uint8_t _random_addr[6];
};
Expand Down

0 comments on commit 1c8974d

Please sign in to comment.