Re: [PATCH v4 12/13] Bluetooth: Implement Set ADV set random address

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Marcel,

On Sun, Jul 15, 2018 at 2:22 AM, Marcel Holtmann <marcel@xxxxxxxxxxxx> wrote:
> Hi Jaganath,
>
>> This basically sets the random address for the instance 0.
>> Random address can be set only if the instance is created which
>> is done in Set ext adv param.
>>
>> This introduces a hci_get_random_address() which returns the
>> own address type and random address (rpa, nrpa or static) based
>> on the instance flags and hdev flags. New function is required
>> since own address type should be known before setting adv params
>> but address can be set only after setting params.
>>
>> < HCI Command: LE Set Advertising Set Random Address (0x08|0x0035) plen 7
>>        Advertising handle: 0x00
>>        Advertising random address: 3C:8E:56:9B:77:84 (OUI 3C-8E-56)
>>> HCI Event: Command Complete (0x0e) plen 4
>>      LE Set Advertising Set Random Address (0x08|0x0035) ncmd 1
>>        Status: Success (0x00)
>>
>> Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@xxxxxxxxx>
>> ---
>> include/net/bluetooth/hci.h |   6 +++
>> net/bluetooth/hci_conn.c    |  23 +++++++++
>> net/bluetooth/hci_event.c   |  24 ++++++++++
>> net/bluetooth/hci_request.c | 111 +++++++++++++++++++++++++++++++++++++++++++-
>> net/bluetooth/hci_request.h |   3 ++
>> 5 files changed, 166 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
>> index 1a68530..40a532a 100644
>> --- a/include/net/bluetooth/hci.h
>> +++ b/include/net/bluetooth/hci.h
>> @@ -1655,6 +1655,12 @@ struct hci_cp_le_remove_adv_set {
>>
>> #define HCI_OP_LE_CLEAR_ADV_SETS      0x203d
>>
>> +#define HCI_OP_LE_SET_ADV_SET_RAND_ADDR      0x2035
>> +struct hci_cp_le_set_adv_set_rand_addr {
>> +     __u8  handle;
>> +     bdaddr_t  bdaddr;
>> +} __packed;
>> +
>> /* ---- HCI Events ---- */
>> #define HCI_EV_INQUIRY_COMPLETE               0x01
>>
>> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
>> index fc27bd8..cf180b24 100644
>> --- a/net/bluetooth/hci_conn.c
>> +++ b/net/bluetooth/hci_conn.c
>> @@ -875,6 +875,14 @@ static void hci_req_directed_advertising(struct hci_request *req,
>>
>>       if (ext_adv_capable(hdev)) {
>>               struct hci_cp_le_set_ext_adv_params cp;
>> +             bdaddr_t random_addr;
>> +
>> +             /* Set require_privacy to false so that the remote device has a
>> +              * chance of identifying us.
>> +              */
>> +             if (hci_get_random_address(hdev, false, conn_use_rpa(conn),
>> +                                        &own_addr_type, &random_addr) < 0)
>> +                     return;
>>
>>               memset(&cp, 0, sizeof(cp));
>>
>> @@ -891,6 +899,21 @@ static void hci_req_directed_advertising(struct hci_request *req,
>>
>>               hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_PARAMS, sizeof(cp), &cp);
>>
>> +             if (own_addr_type == ADDR_LE_DEV_RANDOM &&
>> +                 bacmp(&random_addr, BDADDR_ANY) &&
>> +                 bacmp(&random_addr, &hdev->random_addr)) {
>> +                     struct hci_cp_le_set_adv_set_rand_addr cp;
>> +
>> +                     memset(&cp, 0, sizeof(cp));
>> +
>> +                     cp.handle = 0;
>> +                     bacpy(&cp.bdaddr, &random_addr);
>> +
>> +                     hci_req_add(req,
>> +                                 HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
>> +                                 sizeof(cp), &cp);
>> +             }
>> +
>>               __hci_req_enable_ext_advertising(req);
>>       } else {
>>               struct hci_cp_le_set_adv_param cp;
>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
>> index e703880..dfb2a82 100644
>> --- a/net/bluetooth/hci_event.c
>> +++ b/net/bluetooth/hci_event.c
>> @@ -1061,6 +1061,26 @@ static void hci_cc_le_set_default_phy(struct hci_dev *hdev, struct sk_buff *skb)
>>       hdev->le_tx_def_phys = cp->tx_phys;
>>       hdev->le_rx_def_phys = cp->rx_phys;
>>
>> +        hci_dev_unlock(hdev);
>
> We have some whitespace damage here.
>
>> +}
>> +
>> +static void hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev,
>> +                                              struct sk_buff *skb)
>> +{
>> +        __u8 status = *((__u8 *) skb->data);
>> +        struct hci_cp_le_set_adv_set_rand_addr *cp;
>> +
>> +     if (status)
>> +             return;
>> +
>> +     cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR);
>> +     if (!cp)
>> +             return;
>> +
>> +     hci_dev_lock(hdev);
>> +
>> +     bacpy(&hdev->random_addr, &cp->bdaddr);
>
> Same as with hdev->adv_tx_power, you can not do that. You need to store these per adv instance. I really like to keep the parts that we used for legacy commands different than others.
>

Ok.

>> +
>>       hci_dev_unlock(hdev);
>> }
>>
>> @@ -3272,6 +3292,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
>>               hci_cc_le_set_ext_adv_enable(hdev, skb);
>>               break;
>>
>> +     case HCI_OP_LE_SET_ADV_SET_RAND_ADDR:
>> +             hci_cc_le_set_adv_set_random_addr(hdev, skb);
>> +             break;
>> +
>>       default:
>>               BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode);
>>               break;
>> diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
>> index 7051c5b..6825a65 100644
>> --- a/net/bluetooth/hci_request.c
>> +++ b/net/bluetooth/hci_request.c
>> @@ -1427,6 +1427,87 @@ static void adv_timeout_expire(struct work_struct *work)
>>       hci_dev_unlock(hdev);
>> }
>>
>> +int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
>> +                        bool use_rpa, u8 *own_addr_type, bdaddr_t *rand_addr)
>> +{
>> +     int err;
>> +
>> +     bacpy(rand_addr, BDADDR_ANY);
>> +
>> +     /* If privacy is enabled use a resolvable private address. If
>> +      * current RPA has expired then generate a new one.
>> +      */
>> +     if (use_rpa) {
>> +             *own_addr_type = ADDR_LE_DEV_RANDOM;
>> +
>> +             if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) &&
>> +                 !bacmp(&hdev->random_addr, &hdev->rpa))
>> +                     return 0;
>> +
>> +             err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
>> +             if (err < 0) {
>> +                     BT_ERR("%s failed to generate new RPA", hdev->name);
>> +                     return err;
>> +             }
>> +
>> +             bacpy(rand_addr, &hdev->rpa);
>> +
>> +             return 0;
>> +     }
>> +
>> +     /* In case of required privacy without resolvable private address,
>> +      * use an non-resolvable private address. This is useful for active
>> +      * scanning and non-connectable advertising.
>> +      */
>> +     if (require_privacy) {
>> +             bdaddr_t nrpa;
>> +
>> +             while (true) {
>> +                     /* The non-resolvable private address is generated
>> +                      * from random six bytes with the two most significant
>> +                      * bits cleared.
>> +                      */
>> +                     get_random_bytes(&nrpa, 6);
>> +                     nrpa.b[5] &= 0x3f;
>> +
>> +                     /* The non-resolvable private address shall not be
>> +                      * equal to the public address.
>> +                      */
>> +                     if (bacmp(&hdev->bdaddr, &nrpa))
>> +                             break;
>> +             }
>> +
>> +             *own_addr_type = ADDR_LE_DEV_RANDOM;
>> +             bacpy(rand_addr, &nrpa);
>> +
>> +             return 0;
>> +     }
>> +
>> +     /* If forcing static address is in use or there is no public
>> +      * address use the static address as random address
>> +      *
>> +      * In case BR/EDR has been disabled on a dual-mode controller
>> +      * and a static address has been configured, then use that
>> +      * address instead of the public BR/EDR address.
>> +      */
>> +     if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
>> +         !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
>> +         (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
>> +          bacmp(&hdev->static_addr, BDADDR_ANY))) {
>> +             *own_addr_type = ADDR_LE_DEV_RANDOM;
>> +             bacpy(rand_addr, &hdev->static_addr);
>> +
>> +             return 0;
>> +     }
>> +
>> +     /* Neither privacy nor static address is being used so use a
>> +      * public address.
>> +      */
>> +     *own_addr_type = ADDR_LE_DEV_PUBLIC;
>> +
>> +     return 0;
>> +}
>> +
>
> So I am not convinced that we need all of this. For example we only use this for advertising. So our decision for active scanning is useless.
>

Ok. I will remove it as well as force static address part as i think
its not relevant for adv.

> What I think is best that we actually add rand_addr to the adv instance structure and just calculate what random address we want to use ahead of time and keep it stored in the instance. I mean, we want to rotate the address for each instance independently.
>

So I think we would need separate rpa timer and expire flag also for
each instance.

Thanks,
Jaganath
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux