Re: [RFC] android/gatt: Refactor client connection handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Two issues which are now fixed:

On 04/18/2014 04:09 PM, Jakub Tyszkowski wrote:
@@ -861,45 +861,37 @@ static gboolean disconnected_cb(GIOChannel *io, GIOCondition cond,
  	int sock, err = 0;
  	socklen_t len;

-	queue_remove(conn_list, dev);
-
  	sock = g_io_channel_unix_get_fd(io);
  	len = sizeof(err);
  	if (!getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len))
  		DBG("%s (%d)", strerror(err), err);

+	device_disconnect_clients(dev);
  	connection_cleanup(dev);
Connection cleanup unrefs attrib, triggering notification cleanup, which still needs client's connection map to remove itself from notification queue, thus the proper order is:
   	connection_cleanup(dev);
  +	device_disconnect_clients(dev);

@@ -1099,96 +1061,204 @@ static struct gatt_device *create_device(bdaddr_t *addr)

  	bacpy(&dev->bdaddr, addr);

-	dev->clients = queue_new();
  	dev->services = queue_new();
-
-	if (!dev->clients || !dev->services) {
+	if (!dev->services) {
  		error("gatt: Failed to allocate memory for client");
+
  		destroy_device(dev);
  		return NULL;
  	}

+	if (!queue_push_head(gatt_devices, dev)) {
+		error("gatt: Cannot push device to queue");
+
+		return NULL;
+	}
+
  	return dev;
  }

-static void handle_client_connect(const void *buf, uint16_t len)
+static struct connection_record *create_conn_record(struct gatt_device *device,
+						struct gatt_client *client)
  {
-	const struct hal_cmd_gatt_client_connect *cmd = buf;
-	struct gatt_device *dev = NULL;
-	void *l;
-	bdaddr_t addr;
+	struct connection_record *new_conn;
+	struct connection_record *last;
+
+	/* Check if already connected */
+	new_conn = new0(struct connection_record, 1);
+	if (!new_conn)
+		return NULL;
+
+	new_conn->client = client;
+	new_conn->device = device;
+
+	/* Make connection id unique to connection record
+	 * (client, device) pair.
+	 */
+	last = queue_peek_head(client_connections);
+	if (last)
+		new_conn->id = last->id + 1;
+	else
+		new_conn->id = 1;
+
+	if (!queue_push_head(client_connections, new_conn)) {
+		error("gatt: Cannot push client on the client queue!?");
+
+		free(new_conn);
+		return NULL;
+	}
+
+	new_conn->device->client_count++;
+
+	return new_conn;
+}
+
+static void trigger_disconnection(struct connection_record *conn)
+{
+	if (conn->device->state == DEVICE_STATE_DISCONNECTED)
+		return;
+
+	if (queue_remove(client_connections, conn)) {
+		send_client_disconnect_notify(conn, GATT_SUCCESS);
+		conn->device->client_count--;
+	}
+
+	if (conn->device->client_count <= 0) {
+		connection_cleanup(conn->device);
+		device_set_state(conn->device, DEVICE_STATE_DISCONNECTED);
+	}
+
+	free(conn);
+}
+
+static void client_disconnect_devices(struct gatt_client *client)
+{
+	struct connection_record *conn;
+
+	/* find every connection for client record and trigger disconnect */
+	while ((conn = queue_find(client_connections,
It should obviously be:
while ((conn = queue_remove_if(client_connections,
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux