[PATCH BlueZ] obex: Publish SDP record for Phonebook Access Client

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

 



This is required for passing below PTS test cases:

1. PBAP/PCE/SGSIT/ATTR/BV-01-C
   Attribute GSIT - Bluetooth Profile Descriptor List, PBAP 1.2
2. PBAP/PCE/SGSIT/OFFS/BV-02-C
   Attribute ID Offset String GSIT - Service Name
3. PBAP/PCE/SGSIT/SERR/BV-01-C
   Service record GSIT - PBAP PCE

Currently the Phonebook Access Client SDP record is not registered,
hence  above test cases are failing.
This commit adds code to register the profile (0x112e).
---
 obexd/client/pbap.c | 157 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 157 insertions(+)

diff --git a/obexd/client/pbap.c b/obexd/client/pbap.c
index 48a2de650..2f234fadf 100644
--- a/obexd/client/pbap.c
+++ b/obexd/client/pbap.c
@@ -121,6 +121,7 @@ static const char *filter_list[] = {
 
 #define PBAP_INTERFACE "org.bluez.obex.PhonebookAccess1"
 #define ERROR_INTERFACE "org.bluez.obex.Error"
+#define PBAP_CLIENT_UUID "0000112e-0000-1000-8000-00805f9b34fb"
 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
 
 struct pbap_data {
@@ -139,6 +140,10 @@ struct pending_request {
 };
 
 static DBusConnection *conn = NULL;
+static DBusConnection *system_conn;
+
+static unsigned int listener_id;
+static char *client_path;
 
 static struct pending_request *pending_request_new(struct pbap_data *pbap,
 							DBusMessage *message)
@@ -1294,6 +1299,151 @@ static void pbap_remove(struct obc_session *session)
 	g_dbus_unregister_interface(conn, path, PBAP_INTERFACE);
 }
 
+static DBusMessage *pbap_release(DBusConnection *conn,
+	DBusMessage *msg, void *data)
+{
+	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static DBusMessage *pbap_new_connection(DBusConnection *conn,
+	DBusMessage *msg, void *data)
+{
+	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static DBusMessage *pbap_request_disconnection(DBusConnection *conn,
+	DBusMessage *msg, void *data)
+{
+	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static DBusMessage *pbap_cancel(DBusConnection *conn,
+	DBusMessage *msg, void *data)
+{
+	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static const GDBusMethodTable profile_methods[] = {
+	{ GDBUS_METHOD("Release",
+			NULL, NULL,
+			pbap_release) },
+	{ GDBUS_METHOD("NewConnection",
+			GDBUS_ARGS({ "device", "o" }, { "fd", "h" },
+			{ "options", "a{sv}" }), NULL,
+			pbap_new_connection) },
+	{ GDBUS_METHOD("RequestDisconnection",
+			GDBUS_ARGS({ "device", "o" }), NULL,
+			pbap_request_disconnection) },
+	{ GDBUS_METHOD("Cancel",
+			NULL, NULL,
+			pbap_cancel) },
+	{ }
+};
+
+static void unregister_profile(void)
+{
+	g_dbus_unregister_interface(system_conn, client_path,
+						"org.bluez.Profile1");
+	g_free(client_path);
+	client_path = NULL;
+}
+
+static void register_profile_reply(DBusPendingCall *call, void *user_data)
+{
+	DBusMessage *reply = dbus_pending_call_steal_reply(call);
+	DBusError derr;
+
+	dbus_error_init(&derr);
+	if (!dbus_set_error_from_message(&derr, reply)) {
+		DBG("Profile %s registered", client_path);
+		goto done;
+	}
+
+	unregister_profile();
+
+	error("bluetooth: RequestProfile error: %s, %s", derr.name,
+								derr.message);
+	dbus_error_free(&derr);
+done:
+	dbus_message_unref(reply);
+}
+
+static int register_profile(void)
+{
+	DBusMessage *msg;
+	DBusMessageIter iter, opt;
+	DBusPendingCall *call;
+	char *uuid = PBAP_CLIENT_UUID;
+	dbus_bool_t auto_connect = FALSE;
+	int ret = 0;
+
+	client_path = g_strconcat("/org/bluez/obex/", uuid, NULL);
+	g_strdelimit(client_path, "-", '_');
+
+	if (!g_dbus_register_interface(system_conn, client_path,
+					"org.bluez.Profile1", profile_methods,
+					NULL, NULL,
+					NULL, NULL)) {
+		error("D-Bus failed to register %s", client_path);
+		g_free(client_path);
+		client_path = NULL;
+		return -1;
+	}
+
+	msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
+						"org.bluez.ProfileManager1",
+						"RegisterProfile");
+
+	dbus_message_iter_init_append(msg, &iter);
+
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+							&client_path);
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
+							&uuid);
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+					DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+					DBUS_TYPE_STRING_AS_STRING
+					DBUS_TYPE_VARIANT_AS_STRING
+					DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+					&opt);
+	g_dbus_dict_append_entry(&opt, "AutoConnect", DBUS_TYPE_BOOLEAN,
+								&auto_connect);
+	dbus_message_iter_close_container(&iter, &opt);
+
+	if (!g_dbus_send_message_with_reply(system_conn, msg, &call, -1)) {
+		ret = -1;
+		unregister_profile();
+		goto failed;
+	}
+
+	dbus_pending_call_set_notify(call, register_profile_reply, NULL,
+									NULL);
+	dbus_pending_call_unref(call);
+
+failed:
+	dbus_message_unref(msg);
+	return ret;
+}
+
+static void name_acquired(DBusConnection *conn, void *user_data)
+{
+	DBG("org.bluez appeared");
+
+	if (register_profile() < 0) {
+		error("bluetooth: Failed to register profile %s",
+			client_path);
+		g_free(client_path);
+		client_path = NULL;
+	}
+}
+
+static void name_released(DBusConnection *conn, void *user_data)
+{
+	DBG("org.bluez disappeared");
+
+	unregister_profile();
+}
+
 static struct obc_driver pbap = {
 	.service = "PBAP",
 	.uuid = PBAP_UUID,
@@ -1314,6 +1464,10 @@ int pbap_init(void)
 	if (!conn)
 		return -EIO;
 
+	system_conn = g_dbus_setup_private(DBUS_BUS_SYSTEM, NULL, NULL);
+	if (system_conn == NULL)
+		return -EIO;
+
 	err = obc_driver_register(&pbap);
 	if (err < 0) {
 		dbus_connection_unref(conn);
@@ -1321,6 +1475,9 @@ int pbap_init(void)
 		return err;
 	}
 
+	listener_id = g_dbus_add_service_watch(system_conn, "org.bluez",
+				name_acquired, name_released, NULL, NULL);
+
 	return 0;
 }
 
-- 
2.43.0





[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