Implementation of the method and modification of the dbus method table. --- src/gatt-database.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/src/gatt-database.c b/src/gatt-database.c index 99c95f2d6..7e6b70a80 100644 --- a/src/gatt-database.c +++ b/src/gatt-database.c @@ -3615,6 +3615,93 @@ static DBusMessage *manager_unregister_app(DBusConnection *conn, return dbus_message_new_method_return(msg); } +static DBusMessage *notify_characteristic_changed(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + struct btd_gatt_database *database = user_data; + uint8_t *value = NULL; + int value_len = 0; + DBusMessageIter args; + DBusMessageIter array; + const char *characteristic_path; + const char *client_path; + const char *application_path; + struct svc_match_data match_data; + const char *sender = dbus_message_get_sender(msg); + struct gatt_app *app; + struct external_service *service; + struct external_chrc *chrc; + struct notify notify; + struct device_state *client_state; + struct btd_device *client_device; + + if (!dbus_message_iter_init(msg, &args)) + return btd_error_invalid_args(msg); + + if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) + return btd_error_invalid_args(msg); + dbus_message_iter_get_basic(&args, &application_path); + + dbus_message_iter_next(&args); + if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) + return btd_error_invalid_args(msg); + dbus_message_iter_get_basic(&args, &client_path); + + dbus_message_iter_next(&args); + if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) + return btd_error_invalid_args(msg); + dbus_message_iter_get_basic(&args, &characteristic_path); + + dbus_message_iter_next(&args); + if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) + return btd_error_invalid_args(msg); + + + dbus_message_iter_recurse(&args, &array); + dbus_message_iter_get_fixed_array(&array, &value, &value_len); + + match_data.path = application_path; + match_data.sender = sender; + app = queue_find(database->apps, match_app, &match_data); + if (!app) + return btd_error_does_not_exist(msg); + + + service = queue_find(app->services, match_service_by_chrc, + characteristic_path); + if (!service) + return btd_error_does_not_exist(msg); + + + chrc = queue_find(service->chrcs, match_chrc, characteristic_path); + if (!chrc) + return btd_error_agent_not_available(msg); + + + client_device = btd_adapter_find_device_by_path(database->adapter, + client_path); + if (!client_device) + return btd_error_does_not_exist(msg); + + client_state = find_device_state(database, + device_get_address(client_device), + btd_device_get_bdaddr_type(client_device)); + if (!client_state) + return btd_error_does_not_exist(msg); + + + notify.handle = gatt_db_attribute_get_handle(chrc->attrib); + notify.ccc_handle = gatt_db_attribute_get_handle(chrc->ccc); + notify.database = database; + notify.value = value; + notify.len = value_len; + notify.conf = conf_cb; + + send_notification_to_device(client_state, ¬ify); + DBG("Notification/Indication sent to %s.", client_path); + return dbus_message_new_method_return(msg); +} + static const GDBusMethodTable manager_methods[] = { { GDBUS_ASYNC_METHOD("RegisterApplication", GDBUS_ARGS({ "application", "o" }, @@ -3623,6 +3710,12 @@ static const GDBusMethodTable manager_methods[] = { { GDBUS_ASYNC_METHOD("UnregisterApplication", GDBUS_ARGS({ "application", "o" }), NULL, manager_unregister_app) }, + { GDBUS_ASYNC_METHOD("NotifyCharacteristicChanged", + GDBUS_ARGS({"application", "o" }, + { "device", "o" }, + { "characteristic_path", "o"}, + { "value", "ay"}), + NULL, notify_characteristic_changed) }, { } }; -- 2.17.1