This change will subscribe the MGMT LE PHY Update Complete event. This event will come whenever the particular PHYs changed either autonomously or as a response of set PHY property. Upon receiving the event, it will notify the user by emitting "Phy" property changed event. Reviewed-by: Anupam Roy <anupam.r@xxxxxxxxxxx> --- lib/mgmt.h | 8 ++++++++ src/adapter.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/device.c | 7 +++++++ src/device.h | 2 ++ 4 files changed, 57 insertions(+) diff --git a/lib/mgmt.h b/lib/mgmt.h index 0a6349321..4d2acb778 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -1014,6 +1014,13 @@ struct mgmt_ev_controller_resume { uint8_t wake_reason; } __packed; +#define MGMT_EV_LE_PHY_UPDATE_COMPLETE 0x002f +struct mgmt_ev_le_phy_update_complete { + struct mgmt_addr_info addr; + uint8_t status; + uint32_t phys; +} __packed; + static const char *mgmt_op[] = { "<0x0000>", "Read Version", @@ -1152,6 +1159,7 @@ static const char *mgmt_ev[] = { "Advertisement Monitor Removed", "Controller Suspend", "Controller Resume", + "LE PHY Update Complete", /* 0x002f */ }; static const char *mgmt_status[] = { diff --git a/src/adapter.c b/src/adapter.c index 5de92a570..f616879fd 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -9740,6 +9740,41 @@ static void phy_configuration_changed_callback(uint16_t index, ADAPTER_INTERFACE, "PhyConfiguration"); } +static void le_phy_update_complete_callback(uint16_t index, + uint16_t length, const void *param, + void *user_data) +{ + const struct mgmt_ev_le_phy_update_complete *ev = param; + struct btd_adapter *adapter = user_data; + struct btd_device *device; + char addr[18]; + + if (length < sizeof(*ev)) { + btd_error(adapter->dev_id, "Too small le phy update complete event"); + return; + } + + if (ev->status != MGMT_STATUS_SUCCESS) { + btd_error(adapter->dev_id, "Failed to set le phy: %s (0x%02x)", + mgmt_errstr(ev->status), ev->status); + return; + } + + ba2str(&ev->addr.bdaddr, addr); + + DBG("hci%u device %s PHYs updated %u", index, addr, ev->phys); + + device = btd_adapter_get_device(adapter, &ev->addr.bdaddr, + ev->addr.type); + if (!device) { + btd_error(adapter->dev_id, + "Unable to get device object for %s", addr); + return; + } + + device_le_phy_updated(device, ev->phys); +} + static void read_info_complete(uint8_t status, uint16_t length, const void *param, void *user_data) { @@ -9980,6 +10015,11 @@ static void read_info_complete(uint8_t status, uint16_t length, phy_configuration_changed_callback, adapter, NULL); + mgmt_register(adapter->mgmt, MGMT_EV_LE_PHY_UPDATE_COMPLETE, + adapter->dev_id, + le_phy_update_complete_callback, + adapter, NULL); + set_dev_class(adapter); set_name(adapter, btd_adapter_get_name(adapter)); diff --git a/src/device.c b/src/device.c index 6f74989c7..4b11772b8 100644 --- a/src/device.c +++ b/src/device.c @@ -5684,6 +5684,13 @@ done: } } +void device_le_phy_updated(struct btd_device *dev, uint32_t phy) +{ + dev->pending_phys = false; + + device_set_phy(dev, phy); +} + int device_connect_le(struct btd_device *dev) { struct btd_adapter *adapter = dev->adapter; diff --git a/src/device.h b/src/device.h index 4ae9abe0d..b3b32b231 100644 --- a/src/device.h +++ b/src/device.h @@ -154,6 +154,8 @@ int device_unblock(struct btd_device *device, gboolean silent, void btd_device_set_pnpid(struct btd_device *device, uint16_t source, uint16_t vendor, uint16_t product, uint16_t version); +void device_le_phy_updated(struct btd_device *dev, uint32_t phy); + int device_connect_le(struct btd_device *dev); typedef void (*device_svc_cb_t) (struct btd_device *dev, int err, -- 2.17.1