zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.08k stars 6.19k forks source link

bt: hci: ipm_stm32wb: public identity mac address is not applied #64216

Open lochej opened 8 months ago

lochej commented 8 months ago

Describe the bug When trying the bluetooth examples for STM32WB55RG on two different nucleo_wb55rg boards, I noticed that the MAC address was the same for both:

EDIT: I found this "bug" when trying to setup MAC addresses on 2 nucleo_wb55 boards. I wanted to use the public MAC address either the one generated by STM's or the ones I can get through my company public mac addresses range. Using random addresses is not really an option here because we need MAC address filtering in our applications.

 02:80:E1:00:00:00

To Reproduce

#build a Bluetooth example, peripheral_hr for example:
cd ~/zephyrproject/zephyr/samples/bluetooth/peripheral_hr/
west build -p always -b nucleo_wb55rg && west flash

The 2 boards prints the same MAC address: Board 1:

*** Booting Zephyr OS build zephyr-v3.5.0-233-g9ac852549610 ***                                                                                                                                                                       
[00:00:00.216,000] <inf> bt_hci_core: Identity: 02:80:E1:00:00:00 (public)
[00:00:00.216,000] <inf> bt_hci_core: HCI: version 5.0 (0x09) revision 0x0026, manufacturer 0x0030
[00:00:00.217,000] <inf> bt_hci_core: LMP: version 5.0 (0x09) subver 0x2126
Bluetooth initialized
Advertising successfully started

Board 2:

*** Booting Zephyr OS build zephyr-v3.5.0-233-g9ac852549610 ***                                                                                                                                                                       
[00:00:00.216,000] <inf> bt_hci_core: Identity: 02:80:E1:00:00:00 (public)
[00:00:00.216,000] <inf> bt_hci_core: HCI: version 5.0 (0x09) revision 0x0026, manufacturer 0x0030
[00:00:00.217,000] <inf> bt_hci_core: LMP: version 5.0 (0x09) subver 0x2126
Bluetooth initialized
Advertising successfully started

Possible root of the issue The hci_core->common_init() function issues a HCI reset, which I believe disgards the previous configuration done by ipm_stm32wb->bt_ipm_open()->bt_ipm_ble_init()->bt_imp_set_addr() by resetting the M0 coprocessor. I don't know if all the settings set prior to hci_core->common_init() are affected, but it could be the case.

Possible fix Add BT_QUIRK_NO_RESET to the bt_hci_driver in ipm_stm32wb.c Is there a way to add this quirk using another method that I'm not aware of ?

static const struct bt_hci_driver drv = {
    .name           = "BT IPM",
    .bus            = BT_HCI_DRIVER_BUS_IPM,
    .open           = bt_ipm_open,
#ifdef CONFIG_BT_HCI_HOST
    .close          = bt_ipm_close,
#endif
    .send           = bt_ipm_send,
    .quirks = BT_QUIRK_NO_RESET, //---> Add this driver quirk
};

static int _bt_ipm_init(void)
{
...
}

New output with this change, the MAC address are unique for 2 different boards running the same sample (peripheral_hr).

Board 1:

*** Booting Zephyr OS build zephyr-v3.5.0-233-g9ac852549610 ***
[00:00:00.215,000] <inf> bt_hci_core: Identity: 80:E1:26:1B:A1:E9 (public)
[00:00:00.215,000] <inf> bt_hci_core: HCI: version 5.0 (0x09) revision 0x0026, manufacturer 0x0030
[00:00:00.215,000] <inf> bt_hci_core: LMP: version 5.0 (0x09) subver 0x2126
Bluetooth initialized
Advertising successfully started

Board 2:

*** Booting Zephyr OS build zephyr-v3.5.0-233-g9ac852549610 ***
[00:00:00.215,000] <inf> bt_hci_core: Identity: 80:E1:26:01:AB:7C (public)
[00:00:00.215,000] <inf> bt_hci_core: HCI: version 5.0 (0x09) revision 0x0026, manufacturer 0x0030
[00:00:00.215,000] <inf> bt_hci_core: LMP: version 5.0 (0x09) subver 0x2126
Bluetooth initialized
Advertising successfully started

Expected behavior A config is available to select the public static mac address generated by STMicroElectronics when the IPM hci driver is loaded.

Impact All stm32wb boards have the same MAC address which prevents differentiating them.

Environment (please complete the following information):

lochej commented 8 months ago

Related issue to MAC address setting on the WB55, I've tried setting up my company's public MAC address on the nucleo_wb55rg board without success yet:

Tentative was the following:

I tried modifying my public MAC address using and the settings API in the "samples/bluetooth/peripheral" example with small modifications:

#Disable the PRIVACY config to use the public MAC address instead
CONFIG_BT_PRIVACY=n

Use the CONFIG_BT_SETTING to load "bt/id" key and initialized the bluetooth driver then add the public address setting update function using the settings API:

void setting_load_public_MAC_addr(void)
{
    //Makeen Energy range:
    //28:36:13 (hex)
    //A0:00:00 to AF:FF:FF
    bt_addr_le_t pub_addr;

    pub_addr.type=BT_ADDR_LE_PUBLIC;
    pub_addr.a.val[0]=0xEF;
    pub_addr.a.val[1]=0xBE;
    pub_addr.a.val[2]=0xA0;
    pub_addr.a.val[3]=0x13;
    pub_addr.a.val[4]=0x36;
    pub_addr.a.val[5]=0x28;

    //BT_ADDR_SET_STATIC(&pub_addr.a);

    /* Save the BT address for next reboot */
    settings_save_one("bt/id",&pub_addr,sizeof(pub_addr));
}

static void bt_ready(void)
{
...
    if (IS_ENABLED(CONFIG_SETTINGS)) {
        settings_load();
        setting_load_public_MAC_addr(); //--> make sure the MAC setting is the one we want, should be loaded at next reboot
    }
...
    printk("Advertising successfully started\n");
}

The sample outputs the correctly setup address 28:36:13:A0:BE:EF, so reading from NVS is not an issue.

*** Booting Zephyr OS build zephyr-v3.5.0-233-g9ac852549610 ***
[00:00:00.019,000] <inf> fs_nvs: 2 Sectors of 4096 bytes
[00:00:00.019,000] <inf> fs_nvs: alloc wra: 0, f30
[00:00:00.019,000] <inf> fs_nvs: data wra: 0, 100
[00:00:00.039,000] <inf> bt_hci_core: No ID address. App must call settings_load()
Bluetooth initialized
[00:00:00.040,000] <err> settings: set-value failure. key: bt/irk error(-2)
[00:00:00.042,000] <inf> bt_hci_core: Identity: 28:36:13:A0:BE:EF (public)
[00:00:00.042,000] <inf> bt_hci_core: HCI: version 1.0b (0x00) revision 0xa075, manufacturer 0x0030
[00:00:00.042,000] <inf> bt_hci_core: LMP: version 1.0b (0x00) subver 0x2175
Advertising successfully started
Indicate VND attr 0x8016fd0 (UUID 12345678-1234-5678-1234-56789abcdef1)

But unfortunately, a scan with NRF Connect shows the following MAC:

Zephyr Peripheral Sample Long
02:80:E1:00:00:00

Furthermore, even if I apply the BT_QUIRKS_NO_RESET that fixed loading the public address derived from STM's chip unique ID I still get STM's public address and not my company's one.

Zephyr Peripheral Sample Long
80:E1:26:1B:A1:E9

My guess is that the HCI command to update the loaded identity address is not being sent to the M0 core, therefore not updating the MAC address that shows up in NRF Connect.

I tried to validate my theory and tried the send ACI command used in bt_ipm_set_addr() but in the commit_settings of the subsys/bluetooth/host/settings.c:

static int commit_ble_addr_ipm(void)
{
    bt_addr_t *uid_addr=&bt_dev.id_addr[0].a;
    struct aci_set_ble_addr {
        uint8_t config_offset;
        uint8_t length;
        uint8_t value[6];
    } __packed;
    struct aci_set_ble_addr *param;
    struct net_buf *buf, *rsp;
    int err;

    buf = bt_hci_cmd_create(BT_OP(BT_OGF_VS, 0xFC0C), sizeof(*param));

    if (!buf) {
        return -ENOBUFS;
    }

    param = net_buf_add(buf, sizeof(*param));
    param->config_offset = 0;//HCI_CONFIG_DATA_PUBADDR_OFFSET;
    param->length = 6;
    param->value[0] = uid_addr->val[0];
    param->value[1] = uid_addr->val[1];
    param->value[2] = uid_addr->val[2];
    param->value[3] = uid_addr->val[3];
    param->value[4] = uid_addr->val[4];
    param->value[5] = uid_addr->val[5];

    err = bt_hci_cmd_send_sync(BT_OP(BT_OGF_VS, 0xFC0C), buf, &rsp);
    if (err) {
        return err;
    }
    net_buf_unref(rsp);
    return 0;
}
static int commit_settings(void)
{
    int err;

...
    if (!bt_dev.id_count) {
        err = bt_setup_random_id_addr();
        if (err) {
            LOG_ERR("Unable to setup an identity address");
            return err;
        }
    }

    commit_ble_addr_ipm();

    if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
        bt_finalize_init();
    }
...
    return 0;
}

After flashing the sample the MAC/identity is now correct in NRF connect !

Zephyr Peripheral Sample Long
28:36:13:A0:BE:EF

I don't have a clear idea on the best way to integrate such a procedure in the bluetooth stack since I had to modify both the subsys settings loading and the ipm HCI driver.

But I'm only trying to program my company's public bluetooth addresses in the SOC.

github-actions[bot] commented 6 months ago

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

github-actions[bot] commented 4 months ago

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

github-actions[bot] commented 1 month ago

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

jlh-makeen commented 1 month ago

It's been a while since I posted this issue and I've not worked with wb55 lately.

Has anyone been able to reproduce this issue with latest main ?

erwango commented 1 month ago

No changes were done to solve this issue. It is still valid.