Re: [Bluez PATCH 01/10] advertising: Detect if extended advertising mgmt commands are supported

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

 



Hi Daniel,

On Wed, Sep 16, 2020 at 4:25 PM Daniel Winkler <danielwinkler@xxxxxxxxxx> wrote:
>
> We need to know if kernel supports the new MGMT interface. To do so, we
> call MGMT_OP_READ_COMMANDS when our manager is created and check if the
> new commands are available. This will then be used to route our requests
> for new advertisements.
>
> The change is tested by manually verifying that the correct MGMT
> commands are used when the feature is and is not available in kernel.
>
> Reviewed-by: Sonny Sasaka <sonnysasaka@xxxxxxxxxxxx>
> ---
>
>  src/advertising.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 54 insertions(+)
>
> diff --git a/src/advertising.c b/src/advertising.c
> index e5f25948d..172a83907 100644
> --- a/src/advertising.c
> +++ b/src/advertising.c
> @@ -57,6 +57,7 @@ struct btd_adv_manager {
>         uint8_t max_ads;
>         uint32_t supported_flags;
>         unsigned int instance_bitmap;
> +       bool extended_add_cmds;
>  };
>
>  #define AD_TYPE_BROADCAST 0
> @@ -1407,6 +1408,51 @@ static void read_adv_features_callback(uint8_t status, uint16_t length,
>                 remove_advertising(manager, 0);
>  }
>
> +static void read_commands_complete(uint8_t status, uint16_t length,
> +                                  const void *param, void *user_data)
> +{
> +       struct btd_adv_manager *manager = user_data;
> +       const struct mgmt_rp_read_commands *rp = param;
> +       uint16_t num_commands, num_events;
> +       size_t expected_len;
> +       int i;
> +
> +       if (status != MGMT_STATUS_SUCCESS) {
> +               error("Failed to read supported commands: %s (0x%02x)",
> +                                               mgmt_errstr(status), status);
> +               return;
> +       }
> +
> +       if (length < sizeof(*rp)) {
> +               error("Wrong size of read commands response");
> +               return;
> +       }
> +
> +       num_commands = btohs(rp->num_commands);
> +       num_events = btohs(rp->num_events);
> +
> +       expected_len = sizeof(*rp) + num_commands * sizeof(uint16_t) +
> +                                               num_events * sizeof(uint16_t);
> +
> +       if (length < expected_len) {
> +               error("Too small reply for supported commands: (%u != %zu)",
> +                                                       length, expected_len);
> +               return;
> +       }
> +
> +       for (i = 0; i < num_commands; i++) {
> +               uint16_t op = get_le16(rp->opcodes + i);
> +
> +               switch (op) {
> +               case MGMT_OP_ADD_EXT_ADV_PARAMS:
> +                       manager->extended_add_cmds = true;
> +                       break;
> +               default:
> +                       break;
> +               }
> +       }
> +}

I wouldn't duplicate the handling of MGMT_OP_READ_COMMANDS, so I would
move this to adapter.c and instead use btd_has_kernel_features in
advertising.c

>  static struct btd_adv_manager *manager_create(struct btd_adapter *adapter,
>                                                 struct mgmt *mgmt)
>  {
> @@ -1426,6 +1472,7 @@ static struct btd_adv_manager *manager_create(struct btd_adapter *adapter,
>         manager->mgmt_index = btd_adapter_get_index(adapter);
>         manager->clients = queue_new();
>         manager->supported_flags = MGMT_ADV_FLAG_LOCAL_NAME;
> +       manager->extended_add_cmds = false;
>
>         if (!g_dbus_register_interface(btd_get_dbus_connection(),
>                                         adapter_get_path(manager->adapter),
> @@ -1442,6 +1489,13 @@ static struct btd_adv_manager *manager_create(struct btd_adapter *adapter,
>                 goto fail;
>         }
>
> +       /* Determine if kernel supports extended advertising add command. We
> +        * don't care if this request fails, as we will fall back to legacy
> +        * add_advertising by default
> +        */
> +       mgmt_send(manager->mgmt, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0,
> +                 NULL, read_commands_complete, manager, NULL);
> +
>         return manager;
>
>  fail:
> --
> 2.28.0.618.gf4bc123cb7-goog
>


-- 
Luiz Augusto von Dentz



[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