Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 4 Nov 2007 11:11:01 +0000 (GMT)
From:      Iain Hibbert <plunky@rya-online.net>
To:        freebsd-bluetooth@freebsd.org
Subject:   sdp - SearchService of UUID
Message-ID:  <1194174661.309391.11026.nullmailer@galant.ukfsn.org>

next in thread | raw e-mail | index | archive | help
Hi Max,

I just got a new phone (HTC Touch) with Windows Mobile 6.0 on it (bah!)
and am having trouble sending files with Bluetooth to my computer, though
it manages to send fine to a Nokia 6103 which also sends fine to my
computer, and I can use obexapp to access the FTRN service on the Touch
and send and receive files that way.

The problem seems to be that it sends a SearchServiceAttribute Request
with SDP_UUID_PROTOCOL_OBEX instead of a service class, like so:

> ACL data: handle 45 flags 0x02 dlen 25
    L2CAP(d): cid 0x0044 len 21 [psm 1]
        SDP SSA Req: tid 0x0 len 0x10
          pat uuid-16 0x0008 (OBEX)
          max 4088
          aid(s) 0x0001 (SrvClassIDList) 0x0004 (ProtocolDescList)
          cont 00

and we reply with "no attributes found":

< ACL data: handle 45 flags 0x02 dlen 15
    L2CAP(d): cid 0x004d len 11 [psm 1]
        SDP SSA Rsp: tid 0x0 len 0x6
          count 3
          cont 00

so it gives up. In contrast, the Nokia sends a ServiceSearchRequest for
ObjectPUSH then ServiceAttributeRequest for the handle and all works
fine..

So, I'm looking at the SDP spec and I'm not finding it really clear but it
seems (section 2.7.2) that a ServiceSearch should cover any UUID within
the record (?) not just the service class but I think that sdpd does not
do that, as it only keeps a single UUID per profile..

Since we don't have an actual record in memory because we build the
appropriate parts when requested (?), I've come up with the following
[incomplete*] scheme to extend the profile uuid into a uuid list and made
a provider_match_uuid() function for the ServiceSearch and
ServiceSearchAttribute functions to use.

what do you think, is this the right way to go?

regards,
iain

*
 - only compile tested so far
 - needs further study of specs to see which UUIDs should be in a profile

--- /usr/src/usr.sbin/sdpd/bgd.c	2006-06-19 16:44:56.000000000 +0100
+++ bgd.c	2007-11-04 10:30:24.000000000 +0000
@@ -98,8 +98,13 @@
 	{ 0, NULL } /* end entry */
 };

-profile_t	bgd_profile_descriptor = {
+static uint16_t	bgd_profile_uuids[] = {
 	SDP_SERVICE_CLASS_BROWSE_GROUP_DESCRIPTOR,
+};
+
+profile_t	bgd_profile_descriptor = {
+	bgd_profile_uuids,
+	nelems(bgd_profile_uuids),
 	0,
 	(profile_data_valid_p) NULL,
 	(attr_t const * const) &bgd_profile_attrs
--- /usr/src/usr.sbin/sdpd/dun.c	2006-06-19 16:44:56.000000000 +0100
+++ dun.c	2007-11-04 10:54:04.000000000 +0000
@@ -132,8 +132,16 @@
 	{ 0, NULL } /* end entry */
 };

-profile_t	dun_profile_descriptor = {
+static uint16_t dun_profile_uuids[] = {
 	SDP_SERVICE_CLASS_DIALUP_NETWORKING,
+	SDP_SERVICE_CLASS_GENERIC_NETWORKING,
+	SDP_UUID_PROTOCOL_L2CAP,
+	SDP_UUID_PROTOCOL_RFCOMM,
+	0x0100,
+};
+
+profile_t	dun_profile_descriptor = {
+	dun_profile_uuids,	nelems(dun_profile_uuids),
 	sizeof(sdp_dun_profile_t),
 	common_profile_server_channel_valid,
 	(attr_t const * const) &dun_profile_attrs
--- /usr/src/usr.sbin/sdpd/ftrn.c	2006-06-19 16:44:56.000000000 +0100
+++ ftrn.c	2007-11-04 10:56:08.000000000 +0000
@@ -113,8 +113,15 @@
 	{ 0, NULL } /* end entry */
 };

-profile_t	ftrn_profile_descriptor = {
+static uint16_t ftrn_profile_uuids[] = {
 	SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER,
+	SDP_UUID_PROTOCOL_L2CAP,
+	SDP_UUID_PROTOCOL_RFCOMM,
+	SDP_UUID_PROTOCOL_OBEX,
+};
+
+profile_t	ftrn_profile_descriptor = {
+	ftrn_profile_uuids,	nelems(ftrn_profile_uuids),
 	sizeof(sdp_ftrn_profile_t),
 	common_profile_server_channel_valid,
 	(attr_t const * const) &ftrn_profile_attrs
--- /usr/src/usr.sbin/sdpd/hf.c	2006-08-17 21:13:31.000000000 +0100
+++ hf.c	2007-11-04 10:52:14.000000000 +0000
@@ -148,8 +148,17 @@
 	{ 0, NULL } /* end entry */
 };

-profile_t	hf_profile_descriptor = {
+static uint16_t	hf_profile_uuids[] = {
 	SDP_SERVICE_CLASS_HANDSFREE,
+	SDP_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY,
+	SDP_SERVICE_CLASS_GENERIC_AUDIO,
+	SDP_UUID_PROTOCOL_L2CAP,
+	SDP_UUID_PROTOCOL_RFCOMM,
+	0x0105,
+};
+
+profile_t	hf_profile_descriptor = {
+	hf_profile_uuids,	nelems(hf_profile_uuids),
 	sizeof(sdp_hf_profile_t),
 	hf_profile_data_valid,
 	(attr_t const * const) &hf_profile_attrs
--- /usr/src/usr.sbin/sdpd/hset.c	2006-06-19 16:44:56.000000000 +0100
+++ hset.c	2007-11-04 10:57:24.000000000 +0000
@@ -128,8 +128,16 @@
 	{ 0, NULL } /* end entry */
 };

-profile_t	hset_profile_descriptor = {
+static uint16_t hset_profile_uuids[] = {
 	SDP_SERVICE_CLASS_HEADSET_AUDIO_GATEWAY,
+	SDP_SERVICE_CLASS_GENERIC_AUDIO,
+	SDP_SERVICE_CLASS_HEADSET,
+	SDP_UUID_PROTOCOL_L2CAP,
+	SDP_UUID_PROTOCOL_RFCOMM,
+};
+
+profile_t	hset_profile_descriptor = {
+	hset_profile_uuids,	nelems(hset_profile_uuids),
 	sizeof(sdp_hset_profile_t),
 	hset_profile_data_valid,
 	(attr_t const * const) &hset_profile_attrs
--- /usr/src/usr.sbin/sdpd/irmc.c	2006-06-19 16:44:56.000000000 +0100
+++ irmc.c	2007-11-04 10:31:15.000000000 +0000
@@ -129,8 +129,12 @@
 	{ 0, NULL } /* end entry */
 };

-profile_t	irmc_profile_descriptor = {
+static uint16_t irmc_profile_uuids[] = {
 	SDP_SERVICE_CLASS_IR_MC_SYNC,
+};
+
+profile_t	irmc_profile_descriptor = {
+	irmc_profile_uuids,	nelems(irmc_profile_uuids),
 	sizeof(sdp_irmc_profile_t),
 	obex_profile_data_valid,
 	(attr_t const * const) &irmc_profile_attrs
--- /usr/src/usr.sbin/sdpd/irmc_command.c	2006-06-19 16:44:56.000000000 +0100
+++ irmc_command.c	2007-11-04 10:31:27.000000000 +0000
@@ -113,8 +113,12 @@
 	{ 0, NULL } /* end entry */
 };

-profile_t	irmc_command_profile_descriptor = {
+static uint16_t	irmc_command_profile_uuids[] = {
 	SDP_SERVICE_CLASS_IR_MC_SYNC_COMMAND,
+};
+
+profile_t	irmc_command_profile_descriptor = {
+	irmc_command_profile_uuids,	nelems(irmc_command_profile_uuids),
 	sizeof(sdp_irmc_command_profile_t),
 	common_profile_server_channel_valid,
 	(attr_t const * const) &irmc_command_profile_attrs
--- /usr/src/usr.sbin/sdpd/lan.c	2006-06-19 16:44:56.000000000 +0100
+++ lan.c	2007-11-04 10:31:36.000000000 +0000
@@ -173,8 +173,12 @@
 	{ 0, NULL } /* end entry */
 };

-profile_t	lan_profile_descriptor = {
+static uint16_t lan_profile_uuids[] = {
 	SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP,
+};
+
+profile_t	lan_profile_descriptor = {
+	lan_profile_uuids,	nelems(lan_profile_uuids),
 	sizeof(sdp_lan_profile_t),
 	lan_profile_data_valid,
 	(attr_t const * const) &lan_profile_attrs
--- /usr/src/usr.sbin/sdpd/opush.c	2006-06-19 16:44:56.000000000 +0100
+++ opush.c	2007-11-04 10:58:30.000000000 +0000
@@ -129,8 +129,15 @@
 	{ 0, NULL } /* end entry */
 };

-profile_t	opush_profile_descriptor = {
+static uint16_t opush_profile_uuids[] = {
 	SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH,
+	SDP_UUID_PROTOCOL_L2CAP,
+	SDP_UUID_PROTOCOL_RFCOMM,
+	SDP_UUID_PROTOCOL_OBEX,
+};
+
+profile_t	opush_profile_descriptor = {
+	opush_profile_uuids,	nelems(opush_profile_uuids),
 	sizeof(sdp_opush_profile_t),
 	obex_profile_data_valid,
 	(attr_t const * const) &opush_profile_attrs
--- /usr/src/usr.sbin/sdpd/profile.c	2006-08-19 18:11:04.000000000 +0100
+++ profile.c	2007-11-04 10:20:55.000000000 +0000
@@ -41,6 +41,7 @@
 #include <string.h>
 #include "profile.h"
 #include "provider.h"
+#include "uuid-private.h"

 /*
  * Lookup profile descriptor
@@ -74,7 +75,7 @@
 	int32_t			i;

 	for (i = 0; i < sizeof(profiles)/sizeof(profiles[0]); i++)
-		if (profiles[i]->uuid == uuid)
+		if (profiles[i]->uuid[0] == uuid)
 			return (profiles[i]);

 	return (NULL);
--- /usr/src/usr.sbin/sdpd/profile.h	2006-06-19 16:44:56.000000000 +0100
+++ profile.h	2007-11-04 10:37:28.000000000 +0000
@@ -63,7 +63,8 @@

 struct profile
 {
-	uint16_t		uuid;	/* profile uuid */
+	uint16_t *		uuid;	/* profile uuid list */
+	int			ucount;	/* profile uuid count */
 	uint16_t		dsize;	/* profile data size */
 	profile_data_valid_p	valid;	/* profile data validator */
 	attr_t const * const	attrs;	/* supported attributes */
@@ -88,4 +89,6 @@
 profile_data_valid_t	common_profile_server_channel_valid;
 profile_data_valid_t	obex_profile_data_valid;

+#define nelems(list)	(sizeof(list) / sizeof(list[0]))
+
 #endif /* ndef _PROFILE_H_ */
--- /usr/src/usr.sbin/sdpd/provider.c	2006-06-19 16:44:56.000000000 +0100
+++ provider.c	2007-11-04 10:40:54.000000000 +0000
@@ -36,10 +36,12 @@

 #include <sys/queue.h>
 #include <bluetooth.h>
+#include <sdp.h>
 #include <string.h>
 #include <stdlib.h>
 #include "profile.h"
 #include "provider.h"
+#include "uuid-private.h"

 static TAILQ_HEAD(, provider)	providers = TAILQ_HEAD_INITIALIZER(providers);
 static uint32_t			change_state = 0;
@@ -198,3 +200,28 @@
 {
 	return (change_state);
 }
+
+/*
+ * Match provider by uuid
+ */
+
+int
+provider_match_uuid(provider_p provider, uint128_t *uuid)
+{
+	uint128_t puuid;
+	int i;
+
+	if (memcmp(uuid, &uuid_public_browse_group, sizeof(*uuid)) == 0)
+		return 1;
+
+	for (i = 0 ; i < provider->profile->ucount ; i++) {
+		memcpy(&puuid, &uuid_base, sizeof(puuid));
+		puuid.b[2] = provider->profile->uuid[i] >> 8;
+		puuid.b[3] = provider->profile->uuid[i];
+
+		if (memcmp(uuid, &puuid, sizeof(*uuid)) == 0)
+			return 1;
+	}
+
+	return 0;
+}
--- /usr/src/usr.sbin/sdpd/provider.h	2006-06-19 16:44:56.000000000 +0100
+++ provider.h	2007-11-04 09:40:59.000000000 +0000
@@ -100,6 +100,8 @@
 provider_p	provider_get_first		(void);
 provider_p	provider_get_next		(provider_p provider);
 uint32_t	provider_get_change_state	(void);
+int		provider_match_uuid		(provider_p provider,
+						 uint128_t *uuid);

 int32_t server_prepare_attr_list(provider_p const, uint8_t const *, uint8_t const *,
 		uint8_t *, uint8_t const *);
--- /usr/src/usr.sbin/sdpd/sd.c	2006-06-19 16:44:56.000000000 +0100
+++ sd.c	2007-11-04 10:55:05.000000000 +0000
@@ -208,8 +208,13 @@
 	{ 0, NULL } /* end entry */
 };

-profile_t	sd_profile_descriptor = {
+static uint16_t sd_profile_uuids[] = {
 	SDP_SERVICE_CLASS_SERVICE_DISCOVERY_SERVER,
+	SDP_UUID_PROTOCOL_L2CAP,
+};
+
+profile_t	sd_profile_descriptor = {
+	sd_profile_uuids,	nelems(sd_profile_uuids),
 	0,
 	(profile_data_valid_p) NULL,
 	(attr_t const * const) &sd_profile_attrs
--- /usr/src/usr.sbin/sdpd/sp.c	2006-06-19 16:44:56.000000000 +0100
+++ sp.c	2007-11-04 10:59:04.000000000 +0000
@@ -113,8 +113,14 @@
 	{ 0, NULL } /* end entry */
 };

-profile_t	sp_profile_descriptor = {
+static uint16_t sp_profile_uuids[] = {
 	SDP_SERVICE_CLASS_SERIAL_PORT,
+	SDP_UUID_PROTOCOL_L2CAP,
+	SDP_UUID_PROTOCOL_RFCOMM,
+};
+
+profile_t	sp_profile_descriptor = {
+	sp_profile_uuids,	nelems(sp_profile_uuids),
 	sizeof(sdp_sp_profile_t),
 	common_profile_server_channel_valid,
 	(attr_t const * const) &sp_profile_attrs
--- /usr/src/usr.sbin/sdpd/ssar.c	2006-06-19 16:44:56.000000000 +0100
+++ ssar.c	2007-11-04 09:41:01.000000000 +0000
@@ -60,7 +60,7 @@

 	provider_t	*provider = NULL;
 	int32_t		 type, rsp_limit, ssplen, aidlen, cslen, cs;
-	uint128_t	 uuid, puuid;
+	uint128_t	 uuid;

 	/*
 	 * Minimal Service Search Attribute Request request
@@ -217,12 +217,7 @@
 			if (!provider_match_bdaddr(provider, &srv->req_sa.bt_bdaddr))
 				continue;

-			memcpy(&puuid, &uuid_base, sizeof(puuid));
-			puuid.b[2] = provider->profile->uuid >> 8;
-			puuid.b[3] = provider->profile->uuid;
-
-			if (memcmp(&uuid, &puuid, sizeof(uuid)) != 0 &&
-			    memcmp(&uuid, &uuid_public_browse_group, sizeof(uuid)) != 0)
+			if (!provider_match_uuid(provider, &uuid))
 				continue;

 			cs = server_prepare_attr_list(provider,
--- /usr/src/usr.sbin/sdpd/ssr.c	2006-06-19 16:44:56.000000000 +0100
+++ ssr.c	2007-11-04 09:41:04.000000000 +0000
@@ -63,7 +63,7 @@
 	uint8_t		*ptr = NULL;
 	provider_t	*provider = NULL;
 	int32_t		 type, ssplen, rsp_limit, rcount, cslen, cs;
-	uint128_t	 uuid, puuid;
+	uint128_t	 uuid;

 	/*
 	 * Minimal SDP Service Search Request
@@ -190,15 +190,11 @@
 			if (!provider_match_bdaddr(provider, &srv->req_sa.bt_bdaddr))
 				continue;

-			memcpy(&puuid, &uuid_base, sizeof(puuid));
-			puuid.b[2] = provider->profile->uuid >> 8;
-			puuid.b[3] = provider->profile->uuid;
-
-			if (memcmp(&uuid, &puuid, sizeof(uuid)) == 0 ||
-			    memcmp(&uuid, &uuid_public_browse_group, sizeof(uuid)) == 0) {
-				SDP_PUT32(provider->handle, ptr);
-				rcount ++;
-			}
+			if (!provider_match_uuid(provider, &uuid))
+				continue;
+
+			SDP_PUT32(provider->handle, ptr);
+			rcount ++;
 		}
 	}




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1194174661.309391.11026.nullmailer>