Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Feb 2019 09:20:10 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r344144 - stable/12/usr.sbin/bluetooth/sdpd
Message-ID:  <201902150920.x1F9KA9V086673@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Fri Feb 15 09:20:10 2019
New Revision: 344144
URL: https://svnweb.freebsd.org/changeset/base/344144

Log:
  MFC r343905:
  Improve Bluetooth device discovery support for Android and Microsoft devices.
  
  Tested using the virtual_bt_speaker(8) tool from the virtual_oss(8)
  project at github.com.
  
  PR:			210089
  Sponsored by:		Mellanox Technologies

Modified:
  stable/12/usr.sbin/bluetooth/sdpd/ssar.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/usr.sbin/bluetooth/sdpd/ssar.c
==============================================================================
--- stable/12/usr.sbin/bluetooth/sdpd/ssar.c	Fri Feb 15 04:15:43 2019	(r344143)
+++ stable/12/usr.sbin/bluetooth/sdpd/ssar.c	Fri Feb 15 09:20:10 2019	(r344144)
@@ -47,6 +47,131 @@ int32_t server_prepare_attr_list(provider_p const prov
 		uint8_t *rsp, uint8_t const * const rsp_end);
 
 /*
+ * Scan an attribute for matching UUID.
+ */
+static int
+server_search_uuid_sub(uint8_t *buf, uint8_t const * const eob, const uint128_t *uuid)
+{
+        int128_t duuid;
+        uint32_t value;
+        uint8_t type;
+
+        while (buf < eob) {
+
+                SDP_GET8(type, buf);
+
+                switch (type) {
+                case SDP_DATA_UUID16:
+                        if (buf + 2 > eob)
+                                continue;
+                        SDP_GET16(value, buf);
+
+                        memcpy(&duuid, &uuid_base, sizeof(duuid));
+                        duuid.b[2] = value >> 8 & 0xff;
+                        duuid.b[3] = value & 0xff;
+
+                        if (memcmp(&duuid, uuid, sizeof(duuid)) == 0)
+                                return (0);
+                        break;
+                case SDP_DATA_UUID32:
+                        if (buf + 4 > eob)
+                                continue;
+                        SDP_GET32(value, buf);
+                        memcpy(&duuid, &uuid_base, sizeof(duuid));
+                        duuid.b[0] = value >> 24 & 0xff;
+                        duuid.b[1] = value >> 16 & 0xff;
+                        duuid.b[2] = value >> 8 & 0xff;
+                        duuid.b[3] = value & 0xff;
+
+                        if (memcmp(&duuid, uuid, sizeof(duuid)) == 0)
+                                return (0);
+                        break;
+                case SDP_DATA_UUID128:
+                        if (buf + 16 > eob)
+                                continue;
+                        SDP_GET_UUID128(&duuid, buf);
+
+                        if (memcmp(&duuid, uuid, sizeof(duuid)) == 0)
+                                return (0);
+                        break;
+                case SDP_DATA_UINT8:
+                case SDP_DATA_INT8:
+                case SDP_DATA_SEQ8:
+                        buf++;
+                        break;
+                case SDP_DATA_UINT16:
+                case SDP_DATA_INT16:
+                case SDP_DATA_SEQ16:
+                        buf += 2;
+                        break;
+                case SDP_DATA_UINT32:
+                case SDP_DATA_INT32:
+                case SDP_DATA_SEQ32:
+                        buf += 4;
+                        break;
+                case SDP_DATA_UINT64:
+                case SDP_DATA_INT64:
+                        buf += 8;
+                        break;
+                case SDP_DATA_UINT128:
+                case SDP_DATA_INT128:
+                        buf += 16;
+                        break;
+                case SDP_DATA_STR8:
+                        if (buf + 1 > eob)
+                                continue;
+                        SDP_GET8(value, buf);
+                        buf += value;
+                        break;
+                case SDP_DATA_STR16:
+                        if (buf + 2 > eob)
+                                continue;
+                        SDP_GET16(value, buf);
+                        if (value > (eob - buf))
+                                return (1);
+                        buf += value;
+                        break;
+                case SDP_DATA_STR32:
+                        if (buf + 4 > eob)
+                                continue;
+                        SDP_GET32(value, buf);
+                        if (value > (eob - buf))
+                                return (1);
+                        buf += value;
+                        break;
+                case SDP_DATA_BOOL:
+                        buf += 1;
+                        break;
+                default:
+                        return (1);
+                }
+        }
+        return (1);
+}
+
+/*
+ * Search a provider for matching UUID in its attributes.
+ */
+static int
+server_search_uuid(provider_p const provider, const uint128_t *uuid)
+{
+        uint8_t buffer[256];
+        const attr_t *attr;
+        int len;
+
+        for (attr = provider->profile->attrs; attr->create != NULL; attr++) {
+
+                len = attr->create(buffer, buffer + sizeof(buffer),
+                    (const uint8_t *)provider->profile, sizeof(*provider->profile));
+                if (len < 0)
+                        continue;
+                if (server_search_uuid_sub(buffer, buffer + len, uuid) == 0)
+                        return (0);
+        }
+        return (1);
+}
+
+/*
  * Prepare SDP Service Search Attribute Response
  */
 
@@ -225,7 +350,8 @@ server_prepare_service_search_attribute_response(serve
 			puuid.b[3] = provider->profile->uuid;
 
 			if (memcmp(&uuid, &puuid, sizeof(uuid)) != 0 &&
-			    memcmp(&uuid, &uuid_public_browse_group, sizeof(uuid)) != 0)
+			    memcmp(&uuid, &uuid_public_browse_group, sizeof(uuid)) != 0 &&
+			    server_search_uuid(provider, &uuid) != 0)
 				continue;
 
 			cs = server_prepare_attr_list(provider,



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