All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service
@ 2014-03-28 10:49 Marcin Kraglak
  2014-03-28 10:49 ` [PATCHv4 2/7] android/gatt: Add get_included_data struct and callback Marcin Kraglak
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-03-28 10:49 UTC (permalink / raw)
  To: linux-bluetooth

It will look for included service in range passed in command.
It call gatt_find_included(), but without result callback now,
as it is initial version.
---
 android/gatt.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/android/gatt.c b/android/gatt.c
index 92e16d4..cf0ad61 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -949,13 +949,67 @@ reply:
 			HAL_OP_GATT_CLIENT_SEARCH_SERVICE, status);
 }
 
+static bool match_service_by_uuid(const void *data, const void *user_data)
+{
+	const struct service *service = data;
+	const bt_uuid_t *uuid = user_data;
+	bt_uuid_t service_uuid;
+
+	if (bt_string_to_uuid(&service_uuid, service->primary.uuid) < 0)
+		return false;
+
+	return !bt_uuid_cmp(uuid, &service_uuid);
+}
+
+static struct service *find_service_by_uuid(struct gatt_device *device,
+								bt_uuid_t *uuid)
+{
+	return queue_find(device->services, match_service_by_uuid, uuid);
+}
+
 static void handle_client_get_included_service(const void *buf, uint16_t len)
 {
+	const struct hal_cmd_gatt_client_get_included_service *cmd = buf;
+	struct gatt_device *device;
+	struct service *service;
+	uint8_t status;
+
 	DBG("");
 
+	device = find_device_by_conn_id(cmd->conn_id);
+	if (!device) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	if (queue_isempty(device->services)) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	if (!cmd->number) {
+		service = queue_peek_head(device->services);
+	} else {
+		bt_uuid_t uuid;
+
+		android2uuid(cmd->srvc_id->uuid, &uuid);
+		service = find_service_by_uuid(device, &uuid);
+	}
+
+	if (!service) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	gatt_find_included(device->attrib, service->primary.range.start,
+					service->primary.range.end, NULL, NULL);
+
+	status = HAL_STATUS_SUCCESS;
+
+failed:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
 					HAL_OP_GATT_CLIENT_GET_INCLUDED_SERVICE,
-					HAL_STATUS_FAILED);
+					status);
 }
 
 static void send_client_char_notify(const struct characteristic *ch,
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv4 2/7] android/gatt: Add get_included_data struct and callback
  2014-03-28 10:49 [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service Marcin Kraglak
@ 2014-03-28 10:49 ` Marcin Kraglak
  2014-03-28 10:49 ` [PATCHv4 3/7] android/gatt: Add implementation of get_included_cb Marcin Kraglak
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-03-28 10:49 UTC (permalink / raw)
  To: linux-bluetooth

Create user data passed to callback get_included_cb.
It will handle included services and pass it to notification.
---
 android/gatt.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/android/gatt.c b/android/gatt.c
index cf0ad61..ac753b7 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -967,9 +967,23 @@ static struct service *find_service_by_uuid(struct gatt_device *device,
 	return queue_find(device->services, match_service_by_uuid, uuid);
 }
 
+struct get_included_data {
+	struct service *service;
+	struct gatt_device *device;
+};
+
+static void get_included_cb(uint8_t status, GSList *included, void *user_data)
+{
+	struct get_included_data *data = user_data;
+
+	/* TODO pass included services to notification */
+	free(data);
+}
+
 static void handle_client_get_included_service(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_gatt_client_get_included_service *cmd = buf;
+	struct get_included_data *data;
 	struct gatt_device *device;
 	struct service *service;
 	uint8_t status;
@@ -1001,8 +1015,19 @@ static void handle_client_get_included_service(const void *buf, uint16_t len)
 		goto failed;
 	}
 
+	data = new0(struct get_included_data, 1);
+	if (!data) {
+		error("gatt: failed to allocate memory for included_data");
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	data->service = service;
+	data->device = device;
+
 	gatt_find_included(device->attrib, service->primary.range.start,
-					service->primary.range.end, NULL, NULL);
+				service->primary.range.end, get_included_cb,
+				data);
 
 	status = HAL_STATUS_SUCCESS;
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv4 3/7] android/gatt: Add implementation of get_included_cb
  2014-03-28 10:49 [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service Marcin Kraglak
  2014-03-28 10:49 ` [PATCHv4 2/7] android/gatt: Add get_included_data struct and callback Marcin Kraglak
@ 2014-03-28 10:49 ` Marcin Kraglak
  2014-03-28 10:49 ` [PATCHv4 4/7] android/gatt: Add initial implementation of register_for_notification Marcin Kraglak
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-03-28 10:49 UTC (permalink / raw)
  To: linux-bluetooth

It will pass found services to upper layer with notification.
Caching included services should be done later.
---
 android/gatt.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/android/gatt.c b/android/gatt.c
index ac753b7..d6a0a2a 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -974,10 +974,52 @@ struct get_included_data {
 
 static void get_included_cb(uint8_t status, GSList *included, void *user_data)
 {
+	struct hal_ev_gatt_client_get_inc_service ev;
 	struct get_included_data *data = user_data;
+	struct gatt_device *device = data->device;
+	struct service *service = data->service;
+	bt_uuid_t uuid;
+
+	DBG("");
 
-	/* TODO pass included services to notification */
 	free(data);
+
+	if (status) {
+		error("gatt: no included services found");
+		return;
+	}
+
+	bt_string_to_uuid(&uuid, service->primary.uuid);
+
+	/* TODO store included services in device->services list */
+	for (; included; included = included->next) {
+		struct gatt_included *included_service = included->data;
+		bt_uuid_t included_uuid;
+
+		ev.conn_id = device->conn_id;
+		ev.status = HAL_STATUS_SUCCESS;
+
+		ev.srvc_id.inst_id = 0;
+		uuid2android(&uuid, ev.srvc_id.uuid);
+
+		ev.incl_srvc_id.inst_id = 0;
+		bt_string_to_uuid(&included_uuid, included_service->uuid);
+		uuid2android(&included_uuid, ev.incl_srvc_id.uuid);
+
+		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT ,
+					HAL_EV_GATT_CLIENT_GET_INC_SERVICE,
+					sizeof(ev), &ev);
+	}
+
+	/* Android expects notification with error status in the end */
+	ev.conn_id = device->conn_id;
+	ev.status = HAL_STATUS_FAILED;
+	ev.srvc_id.inst_id = 0;
+	uuid2android(&uuid, ev.srvc_id.uuid);
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT ,
+					HAL_EV_GATT_CLIENT_GET_INC_SERVICE,
+					sizeof(ev), &ev);
 }
 
 static void handle_client_get_included_service(const void *buf, uint16_t len)
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv4 4/7] android/gatt: Add initial implementation of register_for_notification
  2014-03-28 10:49 [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service Marcin Kraglak
  2014-03-28 10:49 ` [PATCHv4 2/7] android/gatt: Add get_included_data struct and callback Marcin Kraglak
  2014-03-28 10:49 ` [PATCHv4 3/7] android/gatt: Add implementation of get_included_cb Marcin Kraglak
@ 2014-03-28 10:49 ` Marcin Kraglak
  2014-03-28 10:49 ` [PATCHv4 5/7] android/gatt: Add send_register_for_notif_ev function Marcin Kraglak
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-03-28 10:49 UTC (permalink / raw)
  To: linux-bluetooth

It will register notification and indication handler for given parameters.
Proper callback should be send with status of registration.
---
 android/gatt.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 190 insertions(+), 2 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index d6a0a2a..d7ea745 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -51,6 +51,7 @@
 struct gatt_client {
 	int32_t id;
 	uint8_t uuid[16];
+	struct queue *notifications;
 };
 
 struct element_id {
@@ -70,6 +71,16 @@ struct service {
 	struct queue *chars;
 };
 
+struct notification_data {
+	struct hal_gatt_srvc_id service;
+	struct hal_gatt_gatt_id ch;
+	struct gatt_client *client;
+	struct gatt_device *dev;
+	guint notif_id;
+	guint ind_id;
+	int ref;
+};
+
 struct gatt_device {
 	bdaddr_t bdaddr;
 	uint8_t bdaddr_type;
@@ -204,6 +215,56 @@ static bool match_char_by_higher_inst_id(const void *data,
 	return inst_id < ch->id.instance;
 }
 
+static bool match_char_by_instance(const void *data, const void *user_data)
+{
+	const struct characteristic *ch = data;
+	uint8_t inst_id = PTR_TO_INT(user_data);
+
+	return inst_id == ch->id.instance;
+}
+
+static bool match_notification(const void *a, const void *b)
+{
+	const struct notification_data *a1 = a;
+	const struct notification_data *b1 = b;
+
+	if (bacmp(&a1->dev->bdaddr, &b1->dev->bdaddr))
+		return false;
+
+	if (memcmp(&a1->ch, &b1->ch, sizeof(a1->ch)))
+		return false;
+
+	if (memcmp(&a1->service, &b1->service, sizeof(a1->service)))
+		return false;
+
+	return true;
+}
+
+static void destroy_notification(void *data)
+{
+	struct notification_data *notification = data;
+
+	if (--notification->ref)
+		return;
+
+	queue_remove_if(notification->client->notifications, match_notification,
+								notification);
+	free(notification);
+}
+
+static void unregister_notification(void *data)
+{
+	struct notification_data *notification = data;
+
+	if (notification->notif_id)
+		g_attrib_unregister(notification->dev->attrib,
+							notification->notif_id);
+
+	if (notification->ind_id)
+		g_attrib_unregister(notification->dev->attrib,
+							notification->ind_id);
+}
+
 static void destroy_device(void *data)
 {
 	struct gatt_device *dev = data;
@@ -216,6 +277,27 @@ static void destroy_device(void *data)
 	free(dev);
 }
 
+static void destroy_gatt_client(void *data)
+{
+	struct gatt_client *client = data;
+
+	/* First we want to get all notifications and unregister them.
+	 * We don't pass unregister_notification to queue_destroy,
+	 * because destroy notification performs operations on queue
+	 * too. So remove all elements and then destroy queue.
+	 */
+	while (queue_peek_head(client->notifications)) {
+		struct notification_data *notification;
+
+		notification = queue_pop_head(client->notifications);
+		unregister_notification(notification);
+	}
+
+	queue_destroy(client->notifications, free);
+
+	free(client);
+}
+
 static void handle_client_register(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_gatt_client_register *cmd = buf;
@@ -247,6 +329,14 @@ static void handle_client_register(const void *buf, uint16_t len)
 
 	memcpy(client->uuid, cmd->uuid, sizeof(client->uuid));
 
+	client->notifications = queue_new();
+	if (!client->notifications) {
+		error("gatt: couldn't allocate notifications queue");
+		destroy_gatt_client(client);
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
 	client->id = client_cnt++;
 
 	queue_push_head(gatt_clients, client);
@@ -281,7 +371,7 @@ static void handle_client_unregister(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	free(cl);
+	destroy_gatt_client(cl);
 	status = HAL_STATUS_SUCCESS;
 
 failed:
@@ -1311,11 +1401,109 @@ static void handle_client_execute_write(const void *buf, uint16_t len)
 static void handle_client_register_for_notification(const void *buf,
 								uint16_t len)
 {
+	const struct hal_cmd_gatt_client_register_for_notification *cmd = buf;
+	struct notification_data *notification;
+	char uuid[MAX_LEN_UUID_STR];
+	struct gatt_client *client;
+	struct characteristic *c;
+	struct element_id match_id;
+	struct gatt_device *dev;
+	struct service *service;
+	uint8_t status;
+	bdaddr_t addr;
+
 	DBG("");
 
+	client = find_client_by_id(cmd->client_if);
+	if (!client) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	android2bdaddr((bdaddr_t *)&cmd->bdaddr, &addr);
+
+	dev = queue_find(conn_list, match_dev_by_bdaddr, &addr);
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	hal_srvc_id_to_element_id(&cmd->srvc_id, &match_id);
+	service = queue_find(dev->services, match_srvc_by_element_id,
+								&match_id);
+	bt_uuid_to_string(&match_id.uuid, uuid, MAX_LEN_UUID_STR);
+	if (!service) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	c = queue_find(service->chars, match_char_by_instance,
+					INT_TO_PTR(cmd->char_id.inst_id));
+	if (!c) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	notification = new0(struct notification_data, 1);
+	if (!notification) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	memcpy(&notification->ch, &cmd->char_id, sizeof(notification->ch));
+	memcpy(&notification->service, &cmd->srvc_id,
+						sizeof(notification->service));
+	notification->dev = dev;
+	notification->client = client;
+
+	if (queue_find(client->notifications, match_notification,
+								notification)) {
+		free(notification);
+		status = HAL_STATUS_SUCCESS;
+		goto failed;
+	}
+
+	notification->notif_id = g_attrib_register(dev->attrib,
+							ATT_OP_HANDLE_NOTIFY,
+							c->ch.value_handle,
+							NULL, notification,
+							destroy_notification);
+	if (!notification->notif_id) {
+		free(notification);
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	notification->ind_id = g_attrib_register(dev->attrib, ATT_OP_HANDLE_IND,
+							c->ch.value_handle,
+							NULL, notification,
+							destroy_notification);
+	if (!notification->ind_id) {
+		g_attrib_unregister(dev->attrib, notification->notif_id);
+		free(notification);
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	/* Because same data - notification - is shared by two handlers, we
+	 * introduce ref counter to be sure that data can be freed with no risk.
+	 * Counter is decremented in destroy_notification.
+	 */
+	notification->ref = 2;
+
+	if (!queue_push_tail(client->notifications, notification)) {
+		unregister_notification(notification);
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	status = HAL_STATUS_SUCCESS;
+
+failed:
+	/* TODO: send callback with notification enabled/disabled */
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
 				HAL_OP_GATT_CLIENT_REGISTER_FOR_NOTIFICATION,
-				HAL_STATUS_FAILED);
+				status);
 }
 
 static void handle_client_deregister_for_notification(const void *buf,
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv4 5/7] android/gatt: Add send_register_for_notif_ev function
  2014-03-28 10:49 [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service Marcin Kraglak
                   ` (2 preceding siblings ...)
  2014-03-28 10:49 ` [PATCHv4 4/7] android/gatt: Add initial implementation of register_for_notification Marcin Kraglak
@ 2014-03-28 10:49 ` Marcin Kraglak
  2014-03-28 10:49 ` [PATCHv4 6/7] android/gatt: Add handler for ATT_OP_HANDLE_NOTIFY and ATT_OP_HANDLE_IND Marcin Kraglak
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-03-28 10:49 UTC (permalink / raw)
  To: linux-bluetooth

It will be called with register/deregister will be called.
It will send status, service id and characteristic id.
---
 android/gatt.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/android/gatt.c b/android/gatt.c
index d7ea745..e87237a 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -1398,6 +1398,23 @@ static void handle_client_execute_write(const void *buf, uint16_t len)
 			HAL_OP_GATT_CLIENT_EXECUTE_WRITE, HAL_STATUS_FAILED);
 }
 
+static void send_register_for_notification_ev(int32_t id, int32_t registered,
+					int32_t status,
+					const struct hal_gatt_srvc_id *srvc,
+					const struct hal_gatt_gatt_id *ch)
+{
+	struct hal_ev_gatt_client_reg_for_notif ev;
+
+	ev.conn_id = id;
+	ev.status = status;
+	ev.registered = registered;
+	memcpy(&ev.srvc_id, srvc, sizeof(ev.srvc_id));
+	memcpy(&ev.char_id, ch, sizeof(ev.char_id));
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT,
+			HAL_EV_GATT_CLIENT_REGISTER_FOR_NOTIF, sizeof(ev), &ev);
+}
+
 static void handle_client_register_for_notification(const void *buf,
 								uint16_t len)
 {
@@ -1409,6 +1426,7 @@ static void handle_client_register_for_notification(const void *buf,
 	struct element_id match_id;
 	struct gatt_device *dev;
 	struct service *service;
+	int32_t conn_id = 0;
 	uint8_t status;
 	bdaddr_t addr;
 
@@ -1428,6 +1446,8 @@ static void handle_client_register_for_notification(const void *buf,
 		goto failed;
 	}
 
+	conn_id = dev->conn_id;
+
 	hal_srvc_id_to_element_id(&cmd->srvc_id, &match_id);
 	service = queue_find(dev->services, match_srvc_by_element_id,
 								&match_id);
@@ -1500,7 +1520,8 @@ static void handle_client_register_for_notification(const void *buf,
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	/* TODO: send callback with notification enabled/disabled */
+	send_register_for_notification_ev(conn_id, 1, status, &cmd->srvc_id,
+								&cmd->char_id);
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
 				HAL_OP_GATT_CLIENT_REGISTER_FOR_NOTIFICATION,
 				status);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv4 6/7] android/gatt: Add handler for ATT_OP_HANDLE_NOTIFY and ATT_OP_HANDLE_IND
  2014-03-28 10:49 [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service Marcin Kraglak
                   ` (3 preceding siblings ...)
  2014-03-28 10:49 ` [PATCHv4 5/7] android/gatt: Add send_register_for_notif_ev function Marcin Kraglak
@ 2014-03-28 10:49 ` Marcin Kraglak
  2014-03-28 10:49 ` [PATCHv4 7/7] android/gatt: Add deregister_for_notification implementation Marcin Kraglak
  2014-03-28 12:28 ` [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service Szymon Janc
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-03-28 10:49 UTC (permalink / raw)
  To: linux-bluetooth

Invoke callback notify_cb with received data. We set flag is_notify
properly to inform Android what type of notification has been received.
---
 android/gatt.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index e87237a..75c555c 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -1398,6 +1398,31 @@ static void handle_client_execute_write(const void *buf, uint16_t len)
 			HAL_OP_GATT_CLIENT_EXECUTE_WRITE, HAL_STATUS_FAILED);
 }
 
+static void handle_notification(const uint8_t *pdu, uint16_t len,
+							gpointer user_data)
+{
+	uint8_t buf[IPC_MTU];
+	struct hal_ev_gatt_client_notify *ev = (void *) buf;
+	struct notification_data *notification = user_data;
+	uint8_t data_offset = sizeof(uint8_t) + sizeof(uint16_t);
+
+	if (len < data_offset)
+		return;
+
+	memcpy(&ev->char_id, &notification->ch, sizeof(ev->char_id));
+	memcpy(&ev->srvc_id, &notification->service, sizeof(ev->srvc_id));
+	bdaddr2android(&notification->dev->bdaddr, &ev->bda);
+	ev->conn_id = notification->dev->conn_id;
+	ev->is_notify = pdu[0] == ATT_OP_HANDLE_NOTIFY;
+
+	/* We have to cut opcode and handle from data */
+	ev->len = len - data_offset;
+	memcpy(ev->value, pdu + data_offset, len - data_offset);
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, HAL_EV_GATT_CLIENT_NOTIFY,
+						sizeof(*ev) + ev->len, ev);
+}
+
 static void send_register_for_notification_ev(int32_t id, int32_t registered,
 					int32_t status,
 					const struct hal_gatt_srvc_id *srvc,
@@ -1486,7 +1511,8 @@ static void handle_client_register_for_notification(const void *buf,
 	notification->notif_id = g_attrib_register(dev->attrib,
 							ATT_OP_HANDLE_NOTIFY,
 							c->ch.value_handle,
-							NULL, notification,
+							handle_notification,
+							notification,
 							destroy_notification);
 	if (!notification->notif_id) {
 		free(notification);
@@ -1496,7 +1522,8 @@ static void handle_client_register_for_notification(const void *buf,
 
 	notification->ind_id = g_attrib_register(dev->attrib, ATT_OP_HANDLE_IND,
 							c->ch.value_handle,
-							NULL, notification,
+							handle_notification,
+							notification,
 							destroy_notification);
 	if (!notification->ind_id) {
 		g_attrib_unregister(dev->attrib, notification->notif_id);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv4 7/7] android/gatt: Add deregister_for_notification implementation
  2014-03-28 10:49 [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service Marcin Kraglak
                   ` (4 preceding siblings ...)
  2014-03-28 10:49 ` [PATCHv4 6/7] android/gatt: Add handler for ATT_OP_HANDLE_NOTIFY and ATT_OP_HANDLE_IND Marcin Kraglak
@ 2014-03-28 10:49 ` Marcin Kraglak
  2014-03-28 12:28 ` [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service Szymon Janc
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-03-28 10:49 UTC (permalink / raw)
  To: linux-bluetooth

This will unregister handlers for notification and indications
and remove notification_data from client's list.
---
 android/gatt.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/android/gatt.c b/android/gatt.c
index 75c555c..e361506 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -1557,11 +1557,53 @@ failed:
 static void handle_client_deregister_for_notification(const void *buf,
 								uint16_t len)
 {
+	const struct hal_cmd_gatt_client_deregister_for_notification *cmd = buf;
+	struct notification_data *notification, notif;
+	struct gatt_client *client;
+	struct gatt_device *dev;
+	int32_t conn_id = 0;
+	uint8_t status;
+	bdaddr_t addr;
+
 	DBG("");
 
+	client = find_client_by_id(cmd->client_if);
+	if (!client) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	android2bdaddr(&cmd->bdaddr, &addr);
+
+	dev = find_device(&addr);
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	conn_id = dev->conn_id;
+	memcpy(&notif.ch, &cmd->char_id, sizeof(notif.ch));
+	memcpy(&notif.service, &cmd->srvc_id, sizeof(notif.service));
+	notif.dev = dev;
+
+	notification = queue_find(client->notifications,
+						match_notification, &notif);
+	if (!notification) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	unregister_notification(notification);
+
+	status = HAL_STATUS_SUCCESS;
+
+failed:
+	send_register_for_notification_ev(conn_id, 0, status, &cmd->srvc_id,
+								&cmd->char_id);
+
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
 				HAL_OP_GATT_CLIENT_DEREGISTER_FOR_NOTIFICATION,
-				HAL_STATUS_FAILED);
+				status);
 }
 
 static void handle_client_read_remote_rssi(const void *buf, uint16_t len)
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service
  2014-03-28 10:49 [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service Marcin Kraglak
                   ` (5 preceding siblings ...)
  2014-03-28 10:49 ` [PATCHv4 7/7] android/gatt: Add deregister_for_notification implementation Marcin Kraglak
@ 2014-03-28 12:28 ` Szymon Janc
  6 siblings, 0 replies; 8+ messages in thread
From: Szymon Janc @ 2014-03-28 12:28 UTC (permalink / raw)
  To: Marcin Kraglak; +Cc: linux-bluetooth

Hi Marcin,

On Friday 28 of March 2014 11:49:16 Marcin Kraglak wrote:
> It will look for included service in range passed in command.
> It call gatt_find_included(), but without result callback now,
> as it is initial version.
> ---
>  android/gatt.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 55 insertions(+), 1 deletion(-)
> 
> diff --git a/android/gatt.c b/android/gatt.c
> index 92e16d4..cf0ad61 100644
> --- a/android/gatt.c
> +++ b/android/gatt.c
> @@ -949,13 +949,67 @@ reply:
>  			HAL_OP_GATT_CLIENT_SEARCH_SERVICE, status);
>  }
>  
> +static bool match_service_by_uuid(const void *data, const void *user_data)
> +{
> +	const struct service *service = data;
> +	const bt_uuid_t *uuid = user_data;
> +	bt_uuid_t service_uuid;
> +
> +	if (bt_string_to_uuid(&service_uuid, service->primary.uuid) < 0)
> +		return false;
> +
> +	return !bt_uuid_cmp(uuid, &service_uuid);
> +}
> +
> +static struct service *find_service_by_uuid(struct gatt_device *device,
> +								bt_uuid_t *uuid)
> +{
> +	return queue_find(device->services, match_service_by_uuid, uuid);
> +}
> +
>  static void handle_client_get_included_service(const void *buf, uint16_t len)
>  {
> +	const struct hal_cmd_gatt_client_get_included_service *cmd = buf;
> +	struct gatt_device *device;
> +	struct service *service;
> +	uint8_t status;
> +
>  	DBG("");
>  
> +	device = find_device_by_conn_id(cmd->conn_id);
> +	if (!device) {
> +		status = HAL_STATUS_FAILED;
> +		goto failed;
> +	}
> +
> +	if (queue_isempty(device->services)) {
> +		status = HAL_STATUS_FAILED;
> +		goto failed;
> +	}
> +
> +	if (!cmd->number) {
> +		service = queue_peek_head(device->services);
> +	} else {
> +		bt_uuid_t uuid;
> +
> +		android2uuid(cmd->srvc_id->uuid, &uuid);
> +		service = find_service_by_uuid(device, &uuid);
> +	}
> +
> +	if (!service) {
> +		status = HAL_STATUS_FAILED;
> +		goto failed;
> +	}
> +
> +	gatt_find_included(device->attrib, service->primary.range.start,
> +					service->primary.range.end, NULL, NULL);
> +
> +	status = HAL_STATUS_SUCCESS;
> +
> +failed:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
>  					HAL_OP_GATT_CLIENT_GET_INCLUDED_SERVICE,
> -					HAL_STATUS_FAILED);
> +					status);
>  }
>  
>  static void send_client_char_notify(const struct characteristic *ch,
> 

All patches applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-03-28 12:28 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-28 10:49 [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service Marcin Kraglak
2014-03-28 10:49 ` [PATCHv4 2/7] android/gatt: Add get_included_data struct and callback Marcin Kraglak
2014-03-28 10:49 ` [PATCHv4 3/7] android/gatt: Add implementation of get_included_cb Marcin Kraglak
2014-03-28 10:49 ` [PATCHv4 4/7] android/gatt: Add initial implementation of register_for_notification Marcin Kraglak
2014-03-28 10:49 ` [PATCHv4 5/7] android/gatt: Add send_register_for_notif_ev function Marcin Kraglak
2014-03-28 10:49 ` [PATCHv4 6/7] android/gatt: Add handler for ATT_OP_HANDLE_NOTIFY and ATT_OP_HANDLE_IND Marcin Kraglak
2014-03-28 10:49 ` [PATCHv4 7/7] android/gatt: Add deregister_for_notification implementation Marcin Kraglak
2014-03-28 12:28 ` [PATCHv4 1/7] android/gatt: Add initial implementation of get_included_service Szymon Janc

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.