forked from mirrors/linux
		
	Bluetooth: Update device_connected and device_found events to latest API
This patch updates mgmt_ev_device_connected and mgmt_ev_device found to include an EIR-encoded remote name and class whenever possible. With this addition the mgmt_ev_remote_name event becomes unnecessary and can be removed. Since the connected event doesn't map to hci_conn_complete anymore a HCI_CONN_MGMT_CONNECTED flag is added to track when mgmt has been notified about a connection. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
		
							parent
							
								
									a0c808b373
								
							
						
					
					
						commit
						b644ba3369
					
				
					 4 changed files with 112 additions and 50 deletions
				
			
		| 
						 | 
					@ -409,6 +409,7 @@ enum {
 | 
				
			||||||
	HCI_CONN_MODE_CHANGE_PEND,
 | 
						HCI_CONN_MODE_CHANGE_PEND,
 | 
				
			||||||
	HCI_CONN_SCO_SETUP_PEND,
 | 
						HCI_CONN_SCO_SETUP_PEND,
 | 
				
			||||||
	HCI_CONN_LE_SMP_PEND,
 | 
						HCI_CONN_LE_SMP_PEND,
 | 
				
			||||||
 | 
						HCI_CONN_MGMT_CONNECTED,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void hci_conn_hash_init(struct hci_dev *hdev)
 | 
					static inline void hci_conn_hash_init(struct hci_dev *hdev)
 | 
				
			||||||
| 
						 | 
					@ -933,7 +934,8 @@ int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
 | 
				
			||||||
int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
 | 
					int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
 | 
				
			||||||
								u8 persistent);
 | 
													u8 persistent);
 | 
				
			||||||
int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 | 
					int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 | 
				
			||||||
								u8 addr_type);
 | 
										u8 addr_type, u8 *name, u8 name_len,
 | 
				
			||||||
 | 
										u8 *dev_class);
 | 
				
			||||||
int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
 | 
					int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
 | 
				
			||||||
						u8 link_type, u8 addr_type);
 | 
											u8 link_type, u8 addr_type);
 | 
				
			||||||
int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status);
 | 
					int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status);
 | 
				
			||||||
| 
						 | 
					@ -962,7 +964,8 @@ int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
 | 
				
			||||||
int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 | 
					int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 | 
				
			||||||
					u8 addr_type, u8 *dev_class, s8 rssi,
 | 
										u8 addr_type, u8 *dev_class, s8 rssi,
 | 
				
			||||||
					u8 cfm_name, u8 *eir, u16 eir_len);
 | 
										u8 cfm_name, u8 *eir, u16 eir_len);
 | 
				
			||||||
int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name);
 | 
					int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 | 
				
			||||||
 | 
								u8 addr_type, s8 rssi, u8 *name, u8 name_len);
 | 
				
			||||||
int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status);
 | 
					int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status);
 | 
				
			||||||
int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status);
 | 
					int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status);
 | 
				
			||||||
int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
 | 
					int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -329,6 +329,11 @@ struct mgmt_ev_new_link_key {
 | 
				
			||||||
} __packed;
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MGMT_EV_DEVICE_CONNECTED	0x000A
 | 
					#define MGMT_EV_DEVICE_CONNECTED	0x000A
 | 
				
			||||||
 | 
					struct mgmt_ev_device_connected {
 | 
				
			||||||
 | 
						struct mgmt_addr_info addr;
 | 
				
			||||||
 | 
						__le16 eir_len;
 | 
				
			||||||
 | 
						__u8 eir[0];
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MGMT_EV_DEVICE_DISCONNECTED	0x000B
 | 
					#define MGMT_EV_DEVICE_DISCONNECTED	0x000B
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -371,20 +376,14 @@ struct mgmt_ev_device_found {
 | 
				
			||||||
	__u8 eir[0];
 | 
						__u8 eir[0];
 | 
				
			||||||
} __packed;
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MGMT_EV_REMOTE_NAME		0x0012
 | 
					#define MGMT_EV_DISCOVERING		0x0012
 | 
				
			||||||
struct mgmt_ev_remote_name {
 | 
					 | 
				
			||||||
	bdaddr_t bdaddr;
 | 
					 | 
				
			||||||
	__u8 name[MGMT_MAX_NAME_LENGTH];
 | 
					 | 
				
			||||||
} __packed;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MGMT_EV_DISCOVERING		0x0013
 | 
					#define MGMT_EV_DEVICE_BLOCKED		0x0013
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MGMT_EV_DEVICE_BLOCKED		0x0014
 | 
					 | 
				
			||||||
struct mgmt_ev_device_blocked {
 | 
					struct mgmt_ev_device_blocked {
 | 
				
			||||||
	bdaddr_t bdaddr;
 | 
						bdaddr_t bdaddr;
 | 
				
			||||||
} __packed;
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MGMT_EV_DEVICE_UNBLOCKED	0x0015
 | 
					#define MGMT_EV_DEVICE_UNBLOCKED	0x0014
 | 
				
			||||||
struct mgmt_ev_device_unblocked {
 | 
					struct mgmt_ev_device_unblocked {
 | 
				
			||||||
	bdaddr_t bdaddr;
 | 
						bdaddr_t bdaddr;
 | 
				
			||||||
} __packed;
 | 
					} __packed;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1286,11 +1286,36 @@ static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e
 | 
				
			||||||
	return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
 | 
						return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void hci_resolve_next_name(struct hci_dev *hdev, bdaddr_t *bdaddr)
 | 
					static bool hci_resolve_next_name(struct hci_dev *hdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct discovery_state *discov = &hdev->discovery;
 | 
						struct discovery_state *discov = &hdev->discovery;
 | 
				
			||||||
	struct inquiry_entry *e;
 | 
						struct inquiry_entry *e;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (list_empty(&discov->resolve))
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
 | 
				
			||||||
 | 
						if (hci_resolve_name(hdev, e) == 0) {
 | 
				
			||||||
 | 
							e->name_state = NAME_PENDING;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
 | 
				
			||||||
 | 
										bdaddr_t *bdaddr, u8 *name, u8 name_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct discovery_state *discov = &hdev->discovery;
 | 
				
			||||||
 | 
						struct inquiry_entry *e;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
 | 
				
			||||||
 | 
							mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
 | 
				
			||||||
 | 
										name, name_len, conn->dev_class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (discov->state == DISCOVERY_STOPPED)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (discov->state == DISCOVERY_STOPPING)
 | 
						if (discov->state == DISCOVERY_STOPPING)
 | 
				
			||||||
		goto discov_complete;
 | 
							goto discov_complete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1301,16 +1326,13 @@ static void hci_resolve_next_name(struct hci_dev *hdev, bdaddr_t *bdaddr)
 | 
				
			||||||
	if (e) {
 | 
						if (e) {
 | 
				
			||||||
		e->name_state = NAME_KNOWN;
 | 
							e->name_state = NAME_KNOWN;
 | 
				
			||||||
		list_del(&e->list);
 | 
							list_del(&e->list);
 | 
				
			||||||
 | 
							if (name)
 | 
				
			||||||
 | 
								mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
 | 
				
			||||||
 | 
										e->data.rssi, name, name_len);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (list_empty(&discov->resolve))
 | 
						if (hci_resolve_next_name(hdev))
 | 
				
			||||||
		goto discov_complete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
 | 
					 | 
				
			||||||
	if (hci_resolve_name(hdev, e) == 0) {
 | 
					 | 
				
			||||||
		e->name_state = NAME_PENDING;
 | 
					 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
discov_complete:
 | 
					discov_complete:
 | 
				
			||||||
	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
 | 
						hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
 | 
				
			||||||
| 
						 | 
					@ -1334,10 +1356,11 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hci_dev_lock(hdev);
 | 
						hci_dev_lock(hdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (test_bit(HCI_MGMT, &hdev->dev_flags))
 | 
					 | 
				
			||||||
		hci_resolve_next_name(hdev, &cp->bdaddr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
 | 
						conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (test_bit(HCI_MGMT, &hdev->dev_flags))
 | 
				
			||||||
 | 
							hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!conn)
 | 
						if (!conn)
 | 
				
			||||||
		goto unlock;
 | 
							goto unlock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1643,8 +1666,6 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
 | 
				
			||||||
			conn->state = BT_CONFIG;
 | 
								conn->state = BT_CONFIG;
 | 
				
			||||||
			hci_conn_hold(conn);
 | 
								hci_conn_hold(conn);
 | 
				
			||||||
			conn->disc_timeout = HCI_DISCONN_TIMEOUT;
 | 
								conn->disc_timeout = HCI_DISCONN_TIMEOUT;
 | 
				
			||||||
			mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
 | 
					 | 
				
			||||||
							conn->dst_type);
 | 
					 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			conn->state = BT_CONNECTED;
 | 
								conn->state = BT_CONNECTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1785,7 +1806,8 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
 | 
				
			||||||
	if (ev->status == 0)
 | 
						if (ev->status == 0)
 | 
				
			||||||
		conn->state = BT_CLOSED;
 | 
							conn->state = BT_CLOSED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (conn->type == ACL_LINK || conn->type == LE_LINK) {
 | 
						if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
 | 
				
			||||||
 | 
								(conn->type == ACL_LINK || conn->type == LE_LINK)) {
 | 
				
			||||||
		if (ev->status != 0)
 | 
							if (ev->status != 0)
 | 
				
			||||||
			mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
 | 
								mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
| 
						 | 
					@ -1878,14 +1900,18 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hci_dev_lock(hdev);
 | 
						hci_dev_lock(hdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
 | 
					 | 
				
			||||||
		if (ev->status == 0)
 | 
					 | 
				
			||||||
			mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		hci_resolve_next_name(hdev, &ev->bdaddr);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
 | 
						conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!test_bit(HCI_MGMT, &hdev->dev_flags))
 | 
				
			||||||
 | 
							goto check_auth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ev->status == 0)
 | 
				
			||||||
 | 
							hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
 | 
				
			||||||
 | 
										strnlen(ev->name, HCI_MAX_NAME_LENGTH));
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_auth:
 | 
				
			||||||
	if (!conn)
 | 
						if (!conn)
 | 
				
			||||||
		goto unlock;
 | 
							goto unlock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1994,7 +2020,10 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
 | 
				
			||||||
		bacpy(&cp.bdaddr, &conn->dst);
 | 
							bacpy(&cp.bdaddr, &conn->dst);
 | 
				
			||||||
		cp.pscan_rep_mode = 0x02;
 | 
							cp.pscan_rep_mode = 0x02;
 | 
				
			||||||
		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
 | 
							hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
 | 
				
			||||||
	}
 | 
						} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
 | 
				
			||||||
 | 
							mgmt_device_connected(hdev, &conn->dst, conn->type,
 | 
				
			||||||
 | 
											conn->dst_type, NULL, 0,
 | 
				
			||||||
 | 
											conn->dev_class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!hci_outgoing_auth_needed(hdev, conn)) {
 | 
						if (!hci_outgoing_auth_needed(hdev, conn)) {
 | 
				
			||||||
		conn->state = BT_CONNECTED;
 | 
							conn->state = BT_CONNECTED;
 | 
				
			||||||
| 
						 | 
					@ -2763,7 +2792,10 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
 | 
				
			||||||
		bacpy(&cp.bdaddr, &conn->dst);
 | 
							bacpy(&cp.bdaddr, &conn->dst);
 | 
				
			||||||
		cp.pscan_rep_mode = 0x02;
 | 
							cp.pscan_rep_mode = 0x02;
 | 
				
			||||||
		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
 | 
							hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
 | 
				
			||||||
	}
 | 
						} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
 | 
				
			||||||
 | 
							mgmt_device_connected(hdev, &conn->dst, conn->type,
 | 
				
			||||||
 | 
											conn->dst_type, NULL, 0,
 | 
				
			||||||
 | 
											conn->dev_class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!hci_outgoing_auth_needed(hdev, conn)) {
 | 
						if (!hci_outgoing_auth_needed(hdev, conn)) {
 | 
				
			||||||
		conn->state = BT_CONNECTED;
 | 
							conn->state = BT_CONNECTED;
 | 
				
			||||||
| 
						 | 
					@ -3164,7 +3196,9 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
 | 
				
			||||||
		goto unlock;
 | 
							goto unlock;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mgmt_device_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type);
 | 
						if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
 | 
				
			||||||
 | 
							mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
 | 
				
			||||||
 | 
											conn->dst_type, NULL, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	conn->sec_level = BT_SECURITY_LOW;
 | 
						conn->sec_level = BT_SECURITY_LOW;
 | 
				
			||||||
	conn->handle = __le16_to_cpu(ev->handle);
 | 
						conn->handle = __le16_to_cpu(ev->handle);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1244,7 +1244,6 @@ static int get_connections(struct sock *sk, u16 index)
 | 
				
			||||||
	struct mgmt_rp_get_connections *rp;
 | 
						struct mgmt_rp_get_connections *rp;
 | 
				
			||||||
	struct hci_dev *hdev;
 | 
						struct hci_dev *hdev;
 | 
				
			||||||
	struct hci_conn *c;
 | 
						struct hci_conn *c;
 | 
				
			||||||
	struct list_head *p;
 | 
					 | 
				
			||||||
	size_t rp_len;
 | 
						size_t rp_len;
 | 
				
			||||||
	u16 count;
 | 
						u16 count;
 | 
				
			||||||
	int i, err;
 | 
						int i, err;
 | 
				
			||||||
| 
						 | 
					@ -1259,8 +1258,9 @@ static int get_connections(struct sock *sk, u16 index)
 | 
				
			||||||
	hci_dev_lock(hdev);
 | 
						hci_dev_lock(hdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	count = 0;
 | 
						count = 0;
 | 
				
			||||||
	list_for_each(p, &hdev->conn_hash.list) {
 | 
						list_for_each_entry(c, &hdev->conn_hash.list, list) {
 | 
				
			||||||
		count++;
 | 
							if (test_bit(HCI_CONN_MGMT_CONNECTED, &c->flags))
 | 
				
			||||||
 | 
								count++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rp_len = sizeof(*rp) + (count * sizeof(struct mgmt_addr_info));
 | 
						rp_len = sizeof(*rp) + (count * sizeof(struct mgmt_addr_info));
 | 
				
			||||||
| 
						 | 
					@ -1274,6 +1274,8 @@ static int get_connections(struct sock *sk, u16 index)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	i = 0;
 | 
						i = 0;
 | 
				
			||||||
	list_for_each_entry(c, &hdev->conn_hash.list, list) {
 | 
						list_for_each_entry(c, &hdev->conn_hash.list, list) {
 | 
				
			||||||
 | 
							if (!test_bit(HCI_CONN_MGMT_CONNECTED, &c->flags))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
		bacpy(&rp->addr[i].bdaddr, &c->dst);
 | 
							bacpy(&rp->addr[i].bdaddr, &c->dst);
 | 
				
			||||||
		rp->addr[i].type = link_to_mgmt(c->type, c->dst_type);
 | 
							rp->addr[i].type = link_to_mgmt(c->type, c->dst_type);
 | 
				
			||||||
		if (rp->addr[i].type == MGMT_ADDR_INVALID)
 | 
							if (rp->addr[i].type == MGMT_ADDR_INVALID)
 | 
				
			||||||
| 
						 | 
					@ -2465,15 +2467,28 @@ int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 | 
					int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 | 
				
			||||||
								u8 addr_type)
 | 
										u8 addr_type, u8 *name, u8 name_len,
 | 
				
			||||||
 | 
										u8 *dev_class)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mgmt_addr_info ev;
 | 
						char buf[512];
 | 
				
			||||||
 | 
						struct mgmt_ev_device_connected *ev = (void *) buf;
 | 
				
			||||||
 | 
						u16 eir_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bacpy(&ev.bdaddr, bdaddr);
 | 
						bacpy(&ev->addr.bdaddr, bdaddr);
 | 
				
			||||||
	ev.type = link_to_mgmt(link_type, addr_type);
 | 
						ev->addr.type = link_to_mgmt(link_type, addr_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return mgmt_event(MGMT_EV_DEVICE_CONNECTED, hdev, &ev, sizeof(ev),
 | 
						if (name_len > 0)
 | 
				
			||||||
									NULL);
 | 
							eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE,
 | 
				
			||||||
 | 
													name, name_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0)
 | 
				
			||||||
 | 
							eir_len = eir_append_data(&ev->eir[eir_len], eir_len,
 | 
				
			||||||
 | 
										EIR_CLASS_OF_DEV, dev_class, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						put_unaligned_le16(eir_len, &ev->eir_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return mgmt_event(MGMT_EV_DEVICE_CONNECTED, hdev, buf,
 | 
				
			||||||
 | 
											sizeof(*ev) + eir_len, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void disconnect_rsp(struct pending_cmd *cmd, void *data)
 | 
					static void disconnect_rsp(struct pending_cmd *cmd, void *data)
 | 
				
			||||||
| 
						 | 
					@ -2813,16 +2828,27 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 | 
				
			||||||
	return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL);
 | 
						return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name)
 | 
					int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 | 
				
			||||||
 | 
									u8 addr_type, s8 rssi, u8 *name, u8 name_len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mgmt_ev_remote_name ev;
 | 
						struct mgmt_ev_device_found *ev;
 | 
				
			||||||
 | 
						char buf[sizeof(*ev) + HCI_MAX_NAME_LENGTH + 2];
 | 
				
			||||||
 | 
						u16 eir_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&ev, 0, sizeof(ev));
 | 
						ev = (struct mgmt_ev_device_found *) buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bacpy(&ev.bdaddr, bdaddr);
 | 
						memset(buf, 0, sizeof(buf));
 | 
				
			||||||
	memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return mgmt_event(MGMT_EV_REMOTE_NAME, hdev, &ev, sizeof(ev), NULL);
 | 
						bacpy(&ev->addr.bdaddr, bdaddr);
 | 
				
			||||||
 | 
						ev->addr.type = link_to_mgmt(link_type, addr_type);
 | 
				
			||||||
 | 
						ev->rssi = rssi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name,
 | 
				
			||||||
 | 
													name_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						put_unaligned_le16(eir_len, &ev->eir_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, &ev, sizeof(ev), NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
 | 
					int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue