Return-Path: From: Arman Uguray To: linux-bluetooth@vger.kernel.org Cc: Arman Uguray Subject: [PATCH BlueZ v3 3/7] core/gatt: Send not/ind for D-Bus characteristics Date: Tue, 3 Mar 2015 20:30:07 -0800 Message-Id: <1425443411-11958-4-git-send-email-armansito@chromium.org> In-Reply-To: <1425443411-11958-1-git-send-email-armansito@chromium.org> References: <1425443411-11958-1-git-send-email-armansito@chromium.org> Sender: linux-bluetooth-owner@vger.kernel.org List-ID: This patch adds support for sending out notification/indication packets for external characteristics whenever a PropertiesChanged signal is received for the "Value" property of an external characteristic that has either the 'notify' or the 'indicate' property. --- src/gatt-database.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/gatt-database.c b/src/gatt-database.c index 2ca9daa..e7f849e 100644 --- a/src/gatt-database.c +++ b/src/gatt-database.c @@ -90,6 +90,7 @@ struct external_service { }; struct external_chrc { + struct external_service *service; GDBusProxy *proxy; uint8_t props; uint8_t ext_props; @@ -299,6 +300,9 @@ static void chrc_free(void *data) queue_destroy(chrc->pending_reads, cancel_pending_read); queue_destroy(chrc->pending_writes, cancel_pending_write); + if (chrc->proxy) + g_dbus_proxy_set_property_watch(chrc->proxy, NULL, NULL); + g_dbus_proxy_unref(chrc->proxy); free(chrc); @@ -997,7 +1001,8 @@ static void service_remove(void *data) service_remove_helper(service); } -static struct external_chrc *chrc_create(GDBusProxy *proxy) +static struct external_chrc *chrc_create(struct external_service *service, + GDBusProxy *proxy) { struct external_chrc *chrc; @@ -1018,6 +1023,7 @@ static struct external_chrc *chrc_create(GDBusProxy *proxy) return NULL; } + chrc->service = service; chrc->proxy = g_dbus_proxy_ref(proxy); return chrc; @@ -1146,7 +1152,7 @@ static void proxy_added_cb(GDBusProxy *proxy, void *user_data) return; } - chrc = chrc_create(proxy); + chrc = chrc_create(service, proxy); if (!chrc) { service->failed = true; return; @@ -1566,6 +1572,41 @@ static uint8_t ccc_write_cb(uint16_t value, void *user_data) return 0; } +static void property_changed_cb(GDBusProxy *proxy, const char *name, + DBusMessageIter *iter, void *user_data) +{ + struct external_chrc *chrc = user_data; + DBusMessageIter array; + uint8_t *value = NULL; + int len = 0; + + if (strcmp(name, "Value")) + return; + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) { + DBG("Malformed \"Value\" property received"); + return; + } + + dbus_message_iter_recurse(iter, &array); + dbus_message_iter_get_fixed_array(&array, &value, &len); + + if (len < 0) { + DBG("Malformed \"Value\" property received"); + return; + } + + /* Truncate the value if it's too large */ + len = MIN(BT_ATT_MAX_VALUE_LEN, len); + value = len ? value : NULL; + + send_notification_to_devices(chrc->service->database, + gatt_db_attribute_get_handle(chrc->attrib), + value, len, + gatt_db_attribute_get_handle(chrc->ccc), + chrc->props & BT_GATT_CHRC_PROP_INDICATE); +} + static bool create_ccc_entry(struct external_service *service, struct external_chrc *chrc) { @@ -1576,6 +1617,12 @@ static bool create_ccc_entry(struct external_service *service, return false; } + if (g_dbus_proxy_set_property_watch(chrc->proxy, property_changed_cb, + chrc) == FALSE) { + error("Failed to set up property watch for characteristic"); + return false; + } + return true; } -- 2.2.0.rc0.207.ga3a616c