Keep connection handle information inside adapter_ops

There's no point to export connection handle details to the core daemon
since it will not be available in the management interface. Instead
track the handles inside hciops (managment interface will do this inside
the kernel).
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 5f3b48b..481f886 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -68,6 +68,11 @@
 	uint8_t svc_hint;
 };
 
+struct acl_connection {
+	bdaddr_t bdaddr;
+	uint16_t handle;
+};
+
 static int max_dev = -1;
 static struct dev_info {
 	int sk;
@@ -103,6 +108,8 @@
 	uint8_t pin_length;
 
 	GSList *uuids;
+
+	GSList *connections;
 } *devs = NULL;
 
 static int ignore_device(struct hci_dev_info *di)
@@ -575,28 +582,22 @@
 static int get_handle(int index, const bdaddr_t *bdaddr, uint16_t *handle)
 {
 	struct dev_info *dev = &devs[index];
-	struct hci_conn_info_req *cr;
+	struct acl_connection *conn;
+	GSList *match;
 	char addr[18];
-	int err;
 
 	ba2str(bdaddr, addr);
 	DBG("hci%d dba %s", index, addr);
 
-	cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
-	bacpy(&cr->bdaddr, bdaddr);
-	cr->type = ACL_LINK;
+	match = g_slist_find_custom(dev->connections, bdaddr,
+							(GCompareFunc) bacmp);
+	if (match == NULL)
+		return -ENOENT;
 
-	if (ioctl(dev->sk, HCIGETCONNINFO, (unsigned long) cr) < 0) {
-		err = -errno;
-		goto fail;
-	}
+	conn = match->data;
+	*handle = conn->handle;
 
-	err = 0;
-	*handle = cr->conn_info->handle;
-
-fail:
-	g_free(cr);
-	return err;
+	return 0;
 }
 
 static int disconnect_addr(int index, bdaddr_t *dba, uint8_t reason)
@@ -1711,8 +1712,18 @@
 	if (evt->link_type != ACL_LINK)
 		return;
 
-	btd_event_conn_complete(&dev->bdaddr, evt->status,
-					btohs(evt->handle), &evt->bdaddr);
+	if (evt->status == 0) {
+		struct acl_connection *conn;
+
+		conn = g_new0(struct acl_connection, 1);
+
+		bacpy(&conn->bdaddr, &evt->bdaddr);
+		conn->handle = evt->handle;
+
+		dev->connections = g_slist_append(dev->connections, conn);
+	}
+
+	btd_event_conn_complete(&dev->bdaddr, evt->status, &evt->bdaddr);
 
 	if (evt->status)
 		return;
@@ -1738,8 +1749,18 @@
 	char filename[PATH_MAX];
 	char local_addr[18], peer_addr[18], *str;
 
-	btd_event_conn_complete(&dev->bdaddr, evt->status,
-					btohs(evt->handle), &evt->peer_bdaddr);
+	if (evt->status == 0) {
+		struct acl_connection *conn;
+
+		conn = g_new0(struct acl_connection, 1);
+
+		bacpy(&conn->bdaddr, &evt->peer_bdaddr);
+		conn->handle = evt->handle;
+
+		dev->connections = g_slist_append(dev->connections, conn);
+	}
+
+	btd_event_conn_complete(&dev->bdaddr, evt->status, &evt->peer_bdaddr);
 
 	if (evt->status)
 		return;
@@ -1758,13 +1779,38 @@
 		free(str);
 }
 
+static int conn_handle_cmp(gconstpointer a, gconstpointer b)
+{
+	const struct acl_connection *conn = a;
+	uint16_t handle = *((uint16_t *) b);
+
+	return (int) conn->handle - (int) handle;
+}
+
 static inline void disconn_complete(int index, void *ptr)
 {
 	struct dev_info *dev = &devs[index];
 	evt_disconn_complete *evt = ptr;
+	struct acl_connection *conn;
+	uint16_t handle;
+	GSList *match;
 
-	btd_event_disconn_complete(&dev->bdaddr, evt->status,
-					btohs(evt->handle), evt->reason);
+	if (evt->status != 0)
+		return;
+
+	handle = btohs(evt->handle);
+	match = g_slist_find_custom(dev->connections, &handle,
+							conn_handle_cmp);
+	if (match == NULL)
+		return;
+
+	conn = match->data;
+
+	dev->connections = g_slist_delete_link(dev->connections, match);
+
+	btd_event_disconn_complete(&dev->bdaddr, &conn->bdaddr);
+
+	g_free(conn);
 }
 
 static inline void auth_complete(int index, void *ptr)
@@ -1857,6 +1903,9 @@
 	g_slist_foreach(dev->uuids, (GFunc) g_free, NULL);
 	g_slist_free(dev->uuids);
 
+	g_slist_foreach(dev->connections, (GFunc) g_free, NULL);
+	g_slist_free(dev->connections);
+
 	init_dev_info(index, -1, dev->registered);
 }
 
@@ -2823,22 +2872,11 @@
 	return  0;
 }
 
-static int hciops_disconnect(int index, uint16_t handle)
+static int hciops_disconnect(int index, bdaddr_t *bdaddr)
 {
-	struct dev_info *dev = &devs[index];
-	disconnect_cp cp;
+	DBG("hci%d", index);
 
-	DBG("hci%d handle %u", index, handle);
-
-	memset(&cp, 0, sizeof(cp));
-	cp.handle = htobs(handle);
-	cp.reason = HCI_OE_USER_ENDED_CONNECTION;
-
-	if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_DISCONNECT,
-						DISCONNECT_CP_SIZE, &cp) < 0)
-		return -errno;
-
-	return 0;
+	return disconnect_addr(index, bdaddr, HCI_OE_USER_ENDED_CONNECTION);
 }
 
 static int hciops_remove_bonding(int index, bdaddr_t *bdaddr)
@@ -2868,12 +2906,18 @@
 	return 0;
 }
 
-static int hciops_request_authentication(int index, uint16_t handle)
+static int hciops_request_authentication(int index, bdaddr_t *bdaddr)
 {
 	struct dev_info *dev = &devs[index];
 	auth_requested_cp cp;
+	uint16_t handle;
+	int err;
 
-	DBG("hci%d handle %u", index, handle);
+	DBG("hci%d", index);
+
+	err = get_handle(index, bdaddr, &handle);
+	if (err < 0)
+		return err;
 
 	memset(&cp, 0, sizeof(cp));
 	cp.handle = htobs(handle);
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index c082586..cf3b15a 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
@@ -1117,9 +1117,13 @@
 	return 0;
 }
 
-static int mgmt_disconnect(int index, uint16_t handle)
+static int mgmt_disconnect(int index, bdaddr_t *bdaddr)
 {
-	DBG("index %d handle %u", index, handle);
+	char addr[18];
+
+	ba2str(bdaddr, addr);
+	DBG("index %d %s", index, addr);
+
 	return -ENOSYS;
 }
 
@@ -1147,9 +1151,13 @@
 	return 0;
 }
 
-static int mgmt_request_authentication(int index, uint16_t handle)
+static int mgmt_request_authentication(int index, bdaddr_t *bdaddr)
 {
-	DBG("index %d handle %u", index, handle);
+	char addr[18];
+
+	ba2str(bdaddr, addr);
+	DBG("index %d %s", index, addr);
+
 	return -ENOSYS;
 }
 
diff --git a/src/adapter.c b/src/adapter.c
index 3f12884..e61a7d8 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -947,21 +947,6 @@
 	return device;
 }
 
-struct btd_device *adapter_find_connection(struct btd_adapter *adapter,
-						uint16_t handle)
-{
-	GSList *l;
-
-	for (l = adapter->connections; l; l = l->next) {
-		struct btd_device *device = l->data;
-
-		if (device_has_connection(device, handle))
-			return device;
-	}
-
-	return NULL;
-}
-
 static void adapter_update_devices(struct btd_adapter *adapter)
 {
 	char **devices;
@@ -2246,7 +2231,7 @@
 		ba2str(&ci->bdaddr, address);
 		device = adapter_get_device(connection, adapter, address);
 		if (device)
-			adapter_add_connection(adapter, device, ci->handle);
+			adapter_add_connection(adapter, device);
 	}
 
 	g_slist_foreach(conns, (GFunc) g_free, NULL);
@@ -2513,7 +2498,7 @@
 
 	while (adapter->connections) {
 		struct btd_device *device = adapter->connections->data;
-		adapter_remove_connection(adapter, device, 0);
+		adapter_remove_connection(adapter, device);
 	}
 
 	if (adapter->scan_mode == (SCAN_PAGE | SCAN_INQUIRY)) {
@@ -3191,29 +3176,29 @@
 }
 
 void adapter_add_connection(struct btd_adapter *adapter,
-				struct btd_device *device, uint16_t handle)
+						struct btd_device *device)
 {
 	if (g_slist_find(adapter->connections, device)) {
-		error("Unable to add connection %d", handle);
+		error("Device is already marked as connected");
 		return;
 	}
 
-	device_add_connection(device, connection, handle);
+	device_add_connection(device, connection);
 
 	adapter->connections = g_slist_append(adapter->connections, device);
 }
 
 void adapter_remove_connection(struct btd_adapter *adapter,
-				struct btd_device *device, uint16_t handle)
+						struct btd_device *device)
 {
 	bdaddr_t bdaddr;
 
 	if (!g_slist_find(adapter->connections, device)) {
-		error("No matching connection for handle %u", handle);
+		error("No matching connection for device");
 		return;
 	}
 
-	device_remove_connection(device, connection, handle);
+	device_remove_connection(device, connection);
 
 	adapter->connections = g_slist_remove(adapter->connections, device);
 
@@ -3594,9 +3579,9 @@
 						timeout, clock, accuracy);
 }
 
-int btd_adapter_disconnect_device(struct btd_adapter *adapter, uint16_t handle)
+int btd_adapter_disconnect_device(struct btd_adapter *adapter, bdaddr_t *bdaddr)
 {
-	return adapter_ops->disconnect(adapter->dev_id, handle);
+	return adapter_ops->disconnect(adapter->dev_id, bdaddr);
 }
 
 int btd_adapter_remove_bonding(struct btd_adapter *adapter, bdaddr_t *bdaddr)
@@ -3605,9 +3590,9 @@
 }
 
 int btd_adapter_request_authentication(struct btd_adapter *adapter,
-							uint16_t handle)
+							bdaddr_t *bdaddr)
 {
-	return adapter_ops->request_authentication(adapter->dev_id, handle);
+	return adapter_ops->request_authentication(adapter->dev_id, bdaddr);
 }
 
 int btd_adapter_pincode_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
diff --git a/src/adapter.h b/src/adapter.h
index 8396569..27553b7 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -115,8 +115,6 @@
 
 struct btd_device *adapter_find_device(struct btd_adapter *adapter, const char *dest);
 
-struct btd_device *adapter_find_connection(struct btd_adapter *adapter, uint16_t handle);
-
 void adapter_remove_device(DBusConnection *conn, struct btd_adapter *adapter,
 						struct btd_device *device,
 						gboolean remove_storage);
@@ -156,9 +154,9 @@
 
 struct agent *adapter_get_agent(struct btd_adapter *adapter);
 void adapter_add_connection(struct btd_adapter *adapter,
-				struct btd_device *device, uint16_t handle);
+						struct btd_device *device);
 void adapter_remove_connection(struct btd_adapter *adapter,
-				struct btd_device *device, uint16_t handle);
+						struct btd_device *device);
 gboolean adapter_has_discov_sessions(struct btd_adapter *adapter);
 void adapter_suspend_discovery(struct btd_adapter *adapter);
 void adapter_resume_discovery(struct btd_adapter *adapter);
@@ -221,9 +219,9 @@
 	int (*get_conn_list) (int index, GSList **conns);
 	int (*read_local_version) (int index, struct hci_version *ver);
 	int (*read_local_features) (int index, uint8_t *features);
-	int (*disconnect) (int index, uint16_t handle);
+	int (*disconnect) (int index, bdaddr_t *bdaddr);
 	int (*remove_bonding) (int index, bdaddr_t *bdaddr);
-	int (*request_authentication) (int index, uint16_t handle);
+	int (*request_authentication) (int index, bdaddr_t *bdaddr);
 	int (*pincode_reply) (int index, bdaddr_t *bdaddr, const char *pin);
 	int (*confirm_reply) (int index, bdaddr_t *bdaddr, gboolean success);
 	int (*passkey_reply) (int index, bdaddr_t *bdaddr, uint32_t passkey);
@@ -266,12 +264,12 @@
 int btd_adapter_unblock_address(struct btd_adapter *adapter, bdaddr_t *bdaddr);
 
 int btd_adapter_disconnect_device(struct btd_adapter *adapter,
-							uint16_t handle);
+							bdaddr_t *bdaddr);
 
 int btd_adapter_remove_bonding(struct btd_adapter *adapter, bdaddr_t *bdaddr);
 
 int btd_adapter_request_authentication(struct btd_adapter *adapter,
-							uint16_t handle);
+							bdaddr_t *bdaddr);
 
 int btd_adapter_pincode_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 							const char *pin);
diff --git a/src/device.c b/src/device.c
index b7b9a98..bf42b4b 100644
--- a/src/device.c
+++ b/src/device.c
@@ -134,7 +134,7 @@
 	uint8_t		cap;
 	uint8_t		auth;
 
-	uint16_t	handle;			/* Connection handle */
+	gboolean	connected;
 
 	/* Whether were creating a security mode 3 connection */
 	gboolean	secmode3;
@@ -328,9 +328,8 @@
 	dict_append_entry(&dict, "Blocked", DBUS_TYPE_BOOLEAN, &boolean);
 
 	/* Connected */
-	boolean = (device->handle != 0);
 	dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN,
-				&boolean);
+							&device->connected);
 
 	/* UUIDs */
 	str = g_new0(char *, g_slist_length(device->uuids) + 1);
@@ -435,7 +434,7 @@
 
 	device->disconn_timer = 0;
 
-	btd_adapter_disconnect_device(device->adapter, device->handle);
+	btd_adapter_disconnect_device(device->adapter, &device->bdaddr);
 
 	return FALSE;
 }
@@ -448,7 +447,7 @@
 	if (device->blocked)
 		return 0;
 
-	if (device->handle)
+	if (device->connected)
 		do_disconnect(device);
 
 	g_slist_foreach(device->drivers, (GFunc) driver_remove, device);
@@ -783,7 +782,7 @@
 {
 	struct btd_device *device = user_data;
 
-	if (!device->handle)
+	if (!device->connected)
 		return btd_error_not_connected(msg);
 
 	device_request_disconnect(device, msg);
@@ -810,7 +809,7 @@
 
 gboolean device_is_connected(struct btd_device *device)
 {
-	return (device->handle != 0);
+	return device->connected;
 }
 
 static void device_set_connected(struct btd_device *device,
@@ -832,34 +831,30 @@
 	}
 }
 
-void device_add_connection(struct btd_device *device, DBusConnection *conn,
-				uint16_t handle)
+void device_add_connection(struct btd_device *device, DBusConnection *conn)
 {
-	if (device->handle) {
+	if (device->connected) {
 		char addr[18];
 		ba2str(&device->bdaddr, addr);
-		error("%s: Unable to add connection %u, %u already exist",
-			addr, handle, device->handle);
+		error("Device %s is already connected", addr);
 		return;
 	}
 
-	device->handle = handle;
+	device->connected = TRUE;
 
 	device_set_connected(device, conn, TRUE);
 }
 
-void device_remove_connection(struct btd_device *device, DBusConnection *conn,
-				uint16_t handle)
+void device_remove_connection(struct btd_device *device, DBusConnection *conn)
 {
-	if (handle && device->handle != handle) {
+	if (!device->connected) {
 		char addr[18];
 		ba2str(&device->bdaddr, addr);
-		error("%s: connection handle mismatch %u != %u",
-						addr, handle, device->handle);
+		error("Device %s isn't connected", addr);
 		return;
 	}
 
-	device->handle = 0;
+	device->connected = FALSE;
 
 	if (device->disconn_timer > 0) {
 		g_source_remove(device->disconn_timer);
@@ -876,11 +871,6 @@
 	device_set_connected(device, conn, FALSE);
 }
 
-gboolean device_has_connection(struct btd_device *device, uint16_t handle)
-{
-	return (handle == device->handle);
-}
-
 guint device_add_disconnect_watch(struct btd_device *device,
 				disconnect_watch watch, void *user_data,
 				GDestroyNotify destroy)
@@ -1064,7 +1054,7 @@
 		browse_request_cancel(device->browse);
 	}
 
-	if (device->handle)
+	if (device->connected)
 		do_disconnect(device);
 
 	if (remove_stored)
@@ -2016,7 +2006,8 @@
 		goto failed;
 	}
 
-	if (btd_adapter_request_authentication(device->adapter, handle) < 0)
+	if (btd_adapter_request_authentication(device->adapter,
+							&device->bdaddr) < 0)
 		goto failed;
 
 	return;
diff --git a/src/device.h b/src/device.h
index 5dea953..f1bdd39 100644
--- a/src/device.h
+++ b/src/device.h
@@ -98,11 +98,8 @@
 void device_set_renewed_key(struct btd_device *device, gboolean renewed);
 gboolean device_set_debug_key(struct btd_device *device, uint8_t *key);
 gboolean device_get_debug_key(struct btd_device *device, uint8_t *key);
-void device_add_connection(struct btd_device *device, DBusConnection *conn,
-				uint16_t handle);
-void device_remove_connection(struct btd_device *device, DBusConnection *conn,
-				uint16_t handle);
-gboolean device_has_connection(struct btd_device *device, uint16_t handle);
+void device_add_connection(struct btd_device *device, DBusConnection *conn);
+void device_remove_connection(struct btd_device *device, DBusConnection *conn);
 void device_request_disconnect(struct btd_device *device, DBusMessage *msg);
 
 typedef void (*disconnect_watch) (struct btd_device *device, gboolean removal,
diff --git a/src/event.c b/src/event.c
index 00b9ad7..11f153e 100644
--- a/src/event.c
+++ b/src/event.c
@@ -785,8 +785,7 @@
 	return 0;
 }
 
-void btd_event_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle,
-				bdaddr_t *peer)
+void btd_event_conn_complete(bdaddr_t *local, uint8_t status, bdaddr_t *peer)
 {
 	struct btd_adapter *adapter;
 	struct btd_device *device;
@@ -809,33 +808,18 @@
 
 	update_lastused(local, peer);
 
-	adapter_add_connection(adapter, device, handle);
+	adapter_add_connection(adapter, device);
 }
 
-void btd_event_disconn_complete(bdaddr_t *local, uint8_t status,
-				uint16_t handle, uint8_t reason)
+void btd_event_disconn_complete(bdaddr_t *local, bdaddr_t *peer)
 {
 	struct btd_adapter *adapter;
 	struct btd_device *device;
 
-	if (status) {
-		error("Disconnection failed: 0x%02x", status);
+	if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
 		return;
-	}
 
-	adapter = manager_find_adapter(local);
-	if (!adapter) {
-		error("No matching adapter found");
-		return;
-	}
-
-	device = adapter_find_connection(adapter, handle);
-	if (!device) {
-		DBG("No matching connection found for handle %u", handle);
-		return;
-	}
-
-	adapter_remove_connection(adapter, device, handle);
+	adapter_remove_connection(adapter, device);
 }
 
 /* Section reserved to device HCI callbacks */
diff --git a/src/event.h b/src/event.h
index 941902a..ab51018 100644
--- a/src/event.h
+++ b/src/event.h
@@ -29,8 +29,8 @@
 void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer, gboolean legacy);
 void btd_event_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class);
 void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char *name);
-void btd_event_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, bdaddr_t *peer);
-void btd_event_disconn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, uint8_t reason);
+void btd_event_conn_complete(bdaddr_t *local, uint8_t status, bdaddr_t *peer);
+void btd_event_disconn_complete(bdaddr_t *local, bdaddr_t *peer);
 void btd_event_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t status);
 void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t status);
 void btd_event_setscan_enable_complete(bdaddr_t *local);