* [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(¬ification->ch, &cmd->char_id, sizeof(notification->ch));
+ memcpy(¬ification->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, ¬ification->ch, sizeof(ev->char_id));
+ memcpy(&ev->srvc_id, ¬ification->service, sizeof(ev->srvc_id));
+ bdaddr2android(¬ification->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(¬if.ch, &cmd->char_id, sizeof(notif.ch));
+ memcpy(¬if.service, &cmd->srvc_id, sizeof(notif.service));
+ notif.dev = dev;
+
+ notification = queue_find(client->notifications,
+ match_notification, ¬if);
+ 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.