The new Tx Power Selected MGMT event will alert bluetoothd that an advertising instance has been assigned a tx power. This is intended to be used to then update the client of their instance's tx power. Towards this goal, this patch does the following: - When adv manager is created, register a handler for tx selected event - On callback, identify the relevant advertising instance, and call for a property set with the new value. If the client exposes this method, it will be called with the new value selected by the controller. To test, I modified the example-advertisement python script to implement the Set dbus method, and verified that it is called after advertisement registration on a device with extended advertising. Reviewed-by: Sonny Sasaka <sonnysasaka@xxxxxxxxxxxx> --- lib/mgmt.h | 6 ++++++ src/advertising.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/lib/mgmt.h b/lib/mgmt.h index 9874be004..97f8dd9b4 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -1002,6 +1002,12 @@ struct mgmt_ev_controller_resume { uint8_t wake_reason; } __packed; +#define MGMT_EV_ADV_TX_POWER_SELECTED 0x002f +struct mgmt_ev_adv_tx_power_selected { + uint8_t instance; + int8_t tx_power; +} __packed; + static const char *mgmt_op[] = { "<0x0000>", "Read Version", diff --git a/src/advertising.c b/src/advertising.c index 008ce0073..0269c9224 100644 --- a/src/advertising.c +++ b/src/advertising.c @@ -113,6 +113,17 @@ static bool match_client(const void *a, const void *b) return true; } +static bool match_client_by_instance(const void *a, const void *b) +{ + const struct btd_adv_client *client = a; + const uint8_t *instance = b; + + if (client && client->instance == *instance) + return true; + + return false; +} + static void client_free(void *data) { struct btd_adv_client *client = data; @@ -1673,6 +1684,22 @@ static void read_adv_features_callback(uint8_t status, uint16_t length, remove_advertising(manager, 0); } +static void tx_power_selected(uint16_t index, uint16_t length, + const void *param, void *user_data) +{ + const struct mgmt_ev_adv_tx_power_selected *ev = param; + struct btd_adv_client *client; + struct btd_adv_manager *manager = user_data; + dbus_int16_t tx_power = ev->tx_power; + + client = queue_find(manager->clients, match_client_by_instance, + &ev->instance); + + if (client) + g_dbus_proxy_set_property_basic(client->proxy, "TxPower", + DBUS_TYPE_INT16, &tx_power, NULL, NULL, NULL); +} + static void read_commands_complete(uint8_t status, uint16_t length, const void *param, void *user_data) { @@ -1716,6 +1743,11 @@ static void read_commands_complete(uint8_t status, uint16_t length, break; } } + + if (manager->extended_add_cmds) + mgmt_register(manager->mgmt, MGMT_EV_ADV_TX_POWER_SELECTED, + manager->mgmt_index, tx_power_selected, + manager, NULL); } static struct btd_adv_manager *manager_create(struct btd_adapter *adapter, -- 2.28.0.618.gf4bc123cb7-goog