@@ -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[] = {
@@ -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));
@@ -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;
@@ -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,
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@samsung.com> --- lib/mgmt.h | 8 ++++++++ src/adapter.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/device.c | 7 +++++++ src/device.h | 2 ++ 4 files changed, 57 insertions(+)