[PATCH v2 8/8] sdp: Decouple Device ID profile implementation

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

 



Make DeviceID profile similar to other profiles implementations. Use
btd_profile for handling DeviceID profile while adding/removing
adapters. The nice drawback is that SDP code no longer depends on
main_opts.
---
 Makefile.plugins             |   3 +
 profiles/deviceid/deviceid.c | 187 +++++++++++++++++++++++++++++++++++++++++++
 src/adapter.c                |  26 +++---
 src/adapter.h                |   3 +
 src/sdpd-server.c            |   4 -
 src/sdpd-service.c           |  58 --------------
 src/sdpd.h                   |   2 -
 7 files changed, 204 insertions(+), 79 deletions(-)
 create mode 100644 profiles/deviceid/deviceid.c

diff --git a/Makefile.plugins b/Makefile.plugins
index 7c5f71d..df5d2a1 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -82,6 +82,9 @@ builtin_sources += profiles/scanparam/scan.c
 builtin_modules += deviceinfo
 builtin_sources += profiles/deviceinfo/deviceinfo.c
 
+builtin_modules += deviceid
+builtin_sources += profiles/deviceid/deviceid.c
+
 if EXPERIMENTAL
 builtin_modules += alert
 builtin_sources += profiles/alert/server.c
diff --git a/profiles/deviceid/deviceid.c b/profiles/deviceid/deviceid.c
new file mode 100644
index 0000000..be5df80
--- /dev/null
+++ b/profiles/deviceid/deviceid.c
@@ -0,0 +1,187 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  Intel Corporation
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#include <glib.h>
+
+#include "sdpd.h"
+#include "hcid.h"
+#include "adapter.h"
+#include "profile.h"
+#include "plugin.h"
+#include "log.h"
+
+struct deviceid_adapter {
+	struct btd_adapter *adapter;
+	uint32_t handle;
+};
+
+static GSList *deviceid_adapters = NULL;
+
+static struct deviceid_adapter *find_adapter(struct btd_adapter *adapter)
+{
+	GSList *list;
+
+	for (list = deviceid_adapters; list; list = list->next) {
+		struct deviceid_adapter *da = list->data;
+
+		if (da->adapter == adapter)
+			return da;
+	}
+
+	return NULL;
+}
+
+static sdp_record_t *create_record(uint16_t source, uint16_t vendor,
+					uint16_t product, uint16_t version)
+{
+	const uint16_t spec = 0x0103;
+	const uint8_t primary = 1;
+	sdp_list_t *class_list, *group_list, *profile_list;
+	uuid_t class_uuid, group_uuid;
+	sdp_data_t *sdp_data, *primary_data, *source_data;
+	sdp_data_t *spec_data, *vendor_data, *product_data, *version_data;
+	sdp_profile_desc_t profile;
+	sdp_record_t *record = sdp_record_alloc();
+
+	DBG("%04x:%04x:%04x:%04x", source, vendor, product, version);
+
+	record->handle = sdp_next_handle();
+
+	sdp_data = sdp_data_alloc(SDP_UINT32, &record->handle);
+	sdp_attr_add(record, SDP_ATTR_RECORD_HANDLE, sdp_data);
+
+	sdp_uuid16_create(&class_uuid, PNP_INFO_SVCLASS_ID);
+	class_list = sdp_list_append(0, &class_uuid);
+	sdp_set_service_classes(record, class_list);
+	sdp_list_free(class_list, NULL);
+
+	sdp_uuid16_create(&group_uuid, PUBLIC_BROWSE_GROUP);
+	group_list = sdp_list_append(NULL, &group_uuid);
+	sdp_set_browse_groups(record, group_list);
+	sdp_list_free(group_list, NULL);
+
+	sdp_uuid16_create(&profile.uuid, PNP_INFO_PROFILE_ID);
+	profile.version = spec;
+	profile_list = sdp_list_append(NULL, &profile);
+	sdp_set_profile_descs(record, profile_list);
+	sdp_list_free(profile_list, NULL);
+
+	spec_data = sdp_data_alloc(SDP_UINT16, &spec);
+	sdp_attr_add(record, 0x0200, spec_data);
+
+	vendor_data = sdp_data_alloc(SDP_UINT16, &vendor);
+	sdp_attr_add(record, 0x0201, vendor_data);
+
+	product_data = sdp_data_alloc(SDP_UINT16, &product);
+	sdp_attr_add(record, 0x0202, product_data);
+
+	version_data = sdp_data_alloc(SDP_UINT16, &version);
+	sdp_attr_add(record, 0x0203, version_data);
+
+	primary_data = sdp_data_alloc(SDP_BOOL, &primary);
+	sdp_attr_add(record, 0x0204, primary_data);
+
+	source_data = sdp_data_alloc(SDP_UINT16, &source);
+	sdp_attr_add(record, 0x0205, source_data);
+
+	return record;
+}
+
+static int deviceid_adapter_probe(struct btd_profile *p,
+						struct btd_adapter *adapter)
+{
+	struct deviceid_adapter *dadapter;
+	sdp_record_t *rec;
+	int ret;
+
+	DBG("path %s", adapter_get_path(adapter));
+
+	rec = create_record(main_opts.did_source, main_opts.did_vendor,
+				main_opts.did_product, main_opts.did_version);
+
+	ret = adapter_service_add(adapter, rec);
+	if (ret < 0) {
+		sdp_record_free(rec);
+		return ret;
+	}
+
+	btd_adapter_set_did(adapter, main_opts.did_source, main_opts.did_vendor,
+				main_opts.did_product, main_opts.did_version);
+
+	dadapter = g_new0(struct deviceid_adapter, 1);
+	dadapter->adapter = btd_adapter_ref(adapter);
+	dadapter->handle = rec->handle;
+
+	deviceid_adapters = g_slist_prepend(deviceid_adapters, dadapter);
+
+	return 0;
+}
+
+static void deviceid_adapter_remove(struct btd_profile *p,
+						struct btd_adapter *adapter)
+{
+	struct deviceid_adapter *dadapter;
+
+	DBG("path %s", adapter_get_path(adapter));
+
+	dadapter = find_adapter(adapter);
+	if (!dadapter)
+		return;
+
+	adapter_service_remove(dadapter->adapter, dadapter->handle);
+
+	btd_adapter_unref(dadapter->adapter);
+	g_free(dadapter);
+}
+
+struct btd_profile deviceid_profile = {
+	.name		= "deviceid",
+	.adapter_probe	= deviceid_adapter_probe,
+	.adapter_remove	= deviceid_adapter_remove,
+};
+
+static int deviceid_init(void)
+{
+	if (main_opts.did_source == 0) {
+		info("Device ID information disabled");
+		return -1;
+	}
+
+	return btd_profile_register(&deviceid_profile);
+}
+
+static void deviceid_exit(void)
+{
+	btd_profile_unregister(&deviceid_profile);
+}
+
+BLUETOOTH_PLUGIN_DEFINE(deviceid, VERSION,
+			BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+			deviceid_init, deviceid_exit)
diff --git a/src/adapter.c b/src/adapter.c
index b99bff9..ed4824c 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3929,17 +3929,12 @@ static struct btd_adapter *btd_adapter_new(uint16_t index)
 	adapter->system_name = g_strdup(main_opts.name);
 	adapter->major_class = (main_opts.class & 0x001f00) >> 8;
 	adapter->minor_class = (main_opts.class & 0x0000fc) >> 2;
-	adapter->modalias = bt_modalias(main_opts.did_source,
-						main_opts.did_vendor,
-						main_opts.did_product,
-						main_opts.did_version);
 	adapter->discoverable_timeout = main_opts.discovto;
 	adapter->pairable_timeout = main_opts.pairto;
 
 	DBG("System name: %s", adapter->system_name);
 	DBG("Major class: %u", adapter->major_class);
 	DBG("Minor class: %u", adapter->minor_class);
-	DBG("Modalias: %s", adapter->modalias);
 	DBG("Discoverable timeout: %u seconds", adapter->discoverable_timeout);
 	DBG("Pairable timeout: %u seconds", adapter->pairable_timeout);
 
@@ -5566,14 +5561,23 @@ void adapter_foreach(adapter_cb func, gpointer user_data)
 	g_slist_foreach(adapters, (GFunc) func, user_data);
 }
 
-static int set_did(struct btd_adapter *adapter, uint16_t vendor,
-			uint16_t product, uint16_t version, uint16_t source)
+int btd_adapter_set_did(struct btd_adapter *adapter,
+					uint16_t source, uint16_t vendor,
+					uint16_t product, uint16_t version)
 {
 	struct mgmt_cp_set_device_id cp;
 
 	DBG("hci%u source %x vendor %x product %x version %x",
 			adapter->dev_id, source, vendor, product, version);
 
+	g_free(adapter->modalias);
+	adapter->modalias = bt_modalias(source, vendor, product, version);
+
+	DBG("Modalias: %s", adapter->modalias);
+
+	g_dbus_emit_property_changed(dbus_conn, adapter->path,
+						ADAPTER_INTERFACE, "Modalias");
+
 	memset(&cp, 0, sizeof(cp));
 
 	cp.source = htobs(source);
@@ -5638,14 +5642,6 @@ static int adapter_register(struct btd_adapter *adapter)
 
 	adapter->initialized = TRUE;
 
-	if (main_opts.did_source) {
-		/* DeviceID record is added by sdpd-server before any other
-		 * record is registered. */
-		adapter_service_insert(adapter, sdp_record_find(0x10000));
-		set_did(adapter, main_opts.did_vendor, main_opts.did_product,
-				main_opts.did_version, main_opts.did_source);
-	}
-
 	DBG("Adapter %s registered", adapter->path);
 
 	return 0;
diff --git a/src/adapter.h b/src/adapter.h
index 5d124e7..a6fb340 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -113,6 +113,9 @@ void btd_adapter_unref(struct btd_adapter *adapter);
 
 void btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major,
 							uint8_t minor);
+int btd_adapter_set_did(struct btd_adapter *adapter,
+					uint16_t source, uint16_t vendor,
+					uint16_t product, uint16_t version);
 
 struct btd_adapter_driver {
 	const char *name;
diff --git a/src/sdpd-server.c b/src/sdpd-server.c
index 7b1351f..de5aef1 100644
--- a/src/sdpd-server.c
+++ b/src/sdpd-server.c
@@ -238,10 +238,6 @@ int start_sdp_server(uint16_t mtu, uint32_t flags)
 		return -1;
 	}
 
-	if (main_opts.did_source > 0)
-		register_device_id(main_opts.did_source, main_opts.did_vendor,
-				main_opts.did_product, main_opts.did_version);
-
 	io = g_io_channel_unix_new(l2cap_sock);
 	g_io_channel_set_close_on_unref(io, TRUE);
 
diff --git a/src/sdpd-service.c b/src/sdpd-service.c
index 09f6c0a..2da70b5 100644
--- a/src/sdpd-service.c
+++ b/src/sdpd-service.c
@@ -176,64 +176,6 @@ void register_server_service(void)
 	update_db_timestamp();
 }
 
-void register_device_id(uint16_t source, uint16_t vendor,
-					uint16_t product, uint16_t version)
-{
-	const uint16_t spec = 0x0103;
-	const uint8_t primary = 1;
-	sdp_list_t *class_list, *group_list, *profile_list;
-	uuid_t class_uuid, group_uuid;
-	sdp_data_t *sdp_data, *primary_data, *source_data;
-	sdp_data_t *spec_data, *vendor_data, *product_data, *version_data;
-	sdp_profile_desc_t profile;
-	sdp_record_t *record = sdp_record_alloc();
-
-	DBG("Adding device id record for %04x:%04x:%04x:%04x",
-					source, vendor, product, version);
-
-	record->handle = sdp_next_handle();
-
-	sdp_record_add(BDADDR_ANY, record);
-	sdp_data = sdp_data_alloc(SDP_UINT32, &record->handle);
-	sdp_attr_add(record, SDP_ATTR_RECORD_HANDLE, sdp_data);
-
-	sdp_uuid16_create(&class_uuid, PNP_INFO_SVCLASS_ID);
-	class_list = sdp_list_append(0, &class_uuid);
-	sdp_set_service_classes(record, class_list);
-	sdp_list_free(class_list, NULL);
-
-	sdp_uuid16_create(&group_uuid, PUBLIC_BROWSE_GROUP);
-	group_list = sdp_list_append(NULL, &group_uuid);
-	sdp_set_browse_groups(record, group_list);
-	sdp_list_free(group_list, NULL);
-
-	sdp_uuid16_create(&profile.uuid, PNP_INFO_PROFILE_ID);
-	profile.version = spec;
-	profile_list = sdp_list_append(NULL, &profile);
-	sdp_set_profile_descs(record, profile_list);
-	sdp_list_free(profile_list, NULL);
-
-	spec_data = sdp_data_alloc(SDP_UINT16, &spec);
-	sdp_attr_add(record, 0x0200, spec_data);
-
-	vendor_data = sdp_data_alloc(SDP_UINT16, &vendor);
-	sdp_attr_add(record, 0x0201, vendor_data);
-
-	product_data = sdp_data_alloc(SDP_UINT16, &product);
-	sdp_attr_add(record, 0x0202, product_data);
-
-	version_data = sdp_data_alloc(SDP_UINT16, &version);
-	sdp_attr_add(record, 0x0203, version_data);
-
-	primary_data = sdp_data_alloc(SDP_BOOL, &primary);
-	sdp_attr_add(record, 0x0204, primary_data);
-
-	source_data = sdp_data_alloc(SDP_UINT16, &source);
-	sdp_attr_add(record, 0x0205, source_data);
-
-	update_db_timestamp();
-}
-
 int add_record_to_server(const bdaddr_t *src, sdp_record_t *rec)
 {
 	sdp_data_t *data;
diff --git a/src/sdpd.h b/src/sdpd.h
index 3c6ee01..174a4d7 100644
--- a/src/sdpd.h
+++ b/src/sdpd.h
@@ -54,8 +54,6 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp);
 
 void register_public_browse_group(void);
 void register_server_service(void);
-void register_device_id(uint16_t source, uint16_t vendor,
-					uint16_t product, uint16_t version);
 
 int record_sort(const void *r1, const void *r2);
 void sdp_svcdb_reset(void);
-- 
1.8.4

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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