Module Name: src
Committed By: plunky
Date: Tue May 12 18:39:20 UTC 2009
Modified Files:
src/usr.sbin/btdevctl: Makefile btdevctl.c sdp.c
Log Message:
update to use new sdp(3) and sdp_data(3) APIs
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/usr.sbin/btdevctl/Makefile
cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/btdevctl/btdevctl.c
cvs rdiff -u -r1.6 -r1.7 src/usr.sbin/btdevctl/sdp.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.sbin/btdevctl/Makefile
diff -u src/usr.sbin/btdevctl/Makefile:1.4 src/usr.sbin/btdevctl/Makefile:1.5
--- src/usr.sbin/btdevctl/Makefile:1.4 Tue May 12 13:09:43 2009
+++ src/usr.sbin/btdevctl/Makefile Tue May 12 18:39:20 2009
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.4 2009/05/12 13:09:43 plunky Exp $
+# $NetBSD: Makefile,v 1.5 2009/05/12 18:39:20 plunky Exp $
PROG= btdevctl
MAN= btdevctl.8
@@ -7,6 +7,4 @@
DPADD+= ${LIBBLUETOOTH} ${LIBPROP} ${LIBUSBHID}
LDADD+= -lbluetooth -lprop -lusbhid
-CPPFLAGS+= -DSDP_COMPAT
-
.include <bsd.prog.mk>
Index: src/usr.sbin/btdevctl/btdevctl.c
diff -u src/usr.sbin/btdevctl/btdevctl.c:1.7 src/usr.sbin/btdevctl/btdevctl.c:1.8
--- src/usr.sbin/btdevctl/btdevctl.c:1.7 Mon Jul 21 13:36:57 2008
+++ src/usr.sbin/btdevctl/btdevctl.c Tue May 12 18:39:20 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: btdevctl.c,v 1.7 2008/07/21 13:36:57 lukem Exp $ */
+/* $NetBSD: btdevctl.c,v 1.8 2009/05/12 18:39:20 plunky Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -32,8 +32,10 @@
*/
#include <sys/cdefs.h>
-__COPYRIGHT("@(#) Copyright (c) 2006 Itronix, Inc. All rights reserved.");
-__RCSID("$NetBSD: btdevctl.c,v 1.7 2008/07/21 13:36:57 lukem Exp $");
+__COPYRIGHT("@(#) Copyright (c) 2006 The NetBSD Foundation, Inc.\
+ @(#) Copyright (c) 2006 Itronix, Inc.\
+ All rights reserved.");
+__RCSID("$NetBSD: btdevctl.c,v 1.8 2009/05/12 18:39:20 plunky Exp $");
#include <prop/proplib.h>
#include <sys/ioctl.h>
Index: src/usr.sbin/btdevctl/sdp.c
diff -u src/usr.sbin/btdevctl/sdp.c:1.6 src/usr.sbin/btdevctl/sdp.c:1.7
--- src/usr.sbin/btdevctl/sdp.c:1.6 Wed Apr 15 00:35:04 2009
+++ src/usr.sbin/btdevctl/sdp.c Tue May 12 18:39:20 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: sdp.c,v 1.6 2009/04/15 00:35:04 lukem Exp $ */
+/* $NetBSD: sdp.c,v 1.7 2009/05/12 18:39:20 plunky Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -29,6 +29,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
* Copyright (c) 2004 Maksim Yevmenkin <[email protected]>
* All rights reserved.
*
@@ -55,7 +56,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: sdp.c,v 1.6 2009/04/15 00:35:04 lukem Exp $");
+__RCSID("$NetBSD: sdp.c,v 1.7 2009/05/12 18:39:20 plunky Exp $");
#include <sys/types.h>
@@ -72,125 +73,104 @@
#include <errno.h>
#include <sdp.h>
#include <stdlib.h>
+#include <strings.h>
#include <usbhid.h>
#include "btdevctl.h"
-static int32_t parse_l2cap_psm(sdp_attr_t *);
-static int32_t parse_rfcomm_channel(sdp_attr_t *);
-static int32_t parse_hid_descriptor(sdp_attr_t *);
-static int32_t parse_boolean(sdp_attr_t *);
-
-static int config_hid(prop_dictionary_t);
-static int config_hset(prop_dictionary_t);
-static int config_hf(prop_dictionary_t);
+static bool parse_hid_descriptor(sdp_data_t *);
+static int32_t parse_boolean(sdp_data_t *);
+static int32_t parse_pdl_param(sdp_data_t *, uint16_t);
+static int32_t parse_pdl(sdp_data_t *, uint16_t);
+static int32_t parse_apdl(sdp_data_t *, uint16_t);
+
+static int config_hid(prop_dictionary_t, sdp_data_t *);
+static int config_hset(prop_dictionary_t, sdp_data_t *);
+static int config_hf(prop_dictionary_t, sdp_data_t *);
uint16_t hid_services[] = {
- SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE
-};
-
-uint32_t hid_attrs[] = {
- SDP_ATTR_RANGE( SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
- SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST),
- SDP_ATTR_RANGE( SDP_ATTR_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS,
- SDP_ATTR_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS),
- SDP_ATTR_RANGE( 0x0205, /* HIDReconnectInitiate */
- 0x0206), /* HIDDescriptorList */
- SDP_ATTR_RANGE( 0x0209, /* HIDBatteryPower */
- 0x0209),
- SDP_ATTR_RANGE( 0x020d, /* HIDNormallyConnectable */
- 0x020d)
+ SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE,
};
uint16_t hset_services[] = {
- SDP_SERVICE_CLASS_HEADSET
-};
-
-uint32_t hset_attrs[] = {
- SDP_ATTR_RANGE( SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
- SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST),
+ SDP_SERVICE_CLASS_HEADSET,
};
uint16_t hf_services[] = {
- SDP_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY
-};
-
-uint32_t hf_attrs[] = {
- SDP_ATTR_RANGE( SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
- SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST),
+ SDP_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY,
};
static struct {
const char *name;
- int (*handler)(prop_dictionary_t);
+ int (*handler)(prop_dictionary_t, sdp_data_t *);
const char *description;
uint16_t *services;
- int nservices;
- uint32_t *attrs;
- int nattrs;
+ size_t nservices;
} cfgtype[] = {
{
"HID", config_hid, "Human Interface Device",
hid_services, __arraycount(hid_services),
- hid_attrs, __arraycount(hid_attrs),
},
{
"HSET", config_hset, "Headset",
hset_services, __arraycount(hset_services),
- hset_attrs, __arraycount(hset_attrs),
},
{
"HF", config_hf, "Handsfree",
hf_services, __arraycount(hf_services),
- hf_attrs, __arraycount(hf_attrs),
},
};
-static sdp_attr_t values[8];
-static uint8_t buffer[__arraycount(values)][512];
+#define MAX_SSP (2 + 1 * 3) /* largest nservices is 1 */
prop_dictionary_t
cfg_query(bdaddr_t *laddr, bdaddr_t *raddr, const char *service)
{
prop_dictionary_t dict;
- void *ss;
- int rv;
- size_t i;
+ sdp_session_t ss;
+ uint8_t buf[MAX_SSP];
+ sdp_data_t ssp, rsp, rec;
+ size_t i, n;
+ bool rv;
dict = prop_dictionary_create();
if (dict == NULL)
return NULL;
- for (i = 0; i < __arraycount(values); i++) {
- values[i].flags = SDP_ATTR_INVALID;
- values[i].attr = 0;
- values[i].vlen = sizeof(buffer[i]);
- values[i].value = buffer[i];
- }
-
for (i = 0; i < __arraycount(cfgtype); i++) {
if (strcasecmp(service, cfgtype[i].name) == 0) {
ss = sdp_open(laddr, raddr);
-
- if (ss == NULL || (errno = sdp_error(ss)) != 0)
+ if (ss == NULL)
return NULL;
- rv = sdp_search(ss,
- cfgtype[i].nservices, cfgtype[i].services,
- cfgtype[i].nattrs, cfgtype[i].attrs,
- __arraycount(values), values);
-
- if (rv != 0) {
- errno = sdp_error(ss);
+ /* build ServiceSearchPattern */
+ ssp.next = buf;
+ ssp.end = buf + sizeof(buf);
+
+ for (n = 0; n < cfgtype[i].nservices; n++)
+ sdp_put_uuid16(&ssp, cfgtype[i].services[n]);
+
+ ssp.end = ssp.next;
+ ssp.next = buf;
+
+ rv = sdp_service_search_attribute(ss, &ssp, NULL, &rsp);
+ if (!rv) {
+ prop_object_release(dict);
+ sdp_close(ss);
return NULL;
}
- sdp_close(ss);
- rv = (*cfgtype[i].handler)(dict);
- if (rv != 0)
- return NULL;
+ while (sdp_get_seq(&rsp, &rec)) {
+ errno = (*cfgtype[i].handler)(dict, &rec);
+ if (errno == 0) {
+ sdp_close(ss);
+ return dict;
+ }
+ }
- return dict;
+ sdp_close(ss);
+ prop_object_release(dict);
+ return NULL;
}
}
@@ -205,54 +185,44 @@
* Configure HID results
*/
static int
-config_hid(prop_dictionary_t dict)
+config_hid(prop_dictionary_t dict, sdp_data_t *rec)
{
prop_object_t obj;
int32_t control_psm, interrupt_psm,
- reconnect_initiate, battery_power,
- normally_connectable, hid_length;
+ reconnect_initiate, hid_length;
uint8_t *hid_descriptor;
+ sdp_data_t value;
const char *mode;
- size_t i;
+ uint16_t attr;
control_psm = -1;
interrupt_psm = -1;
reconnect_initiate = -1;
- normally_connectable = 0;
- battery_power = 0;
hid_descriptor = NULL;
hid_length = -1;
- for (i = 0; i < __arraycount(values); i++) {
- if (values[i].flags != SDP_ATTR_OK)
- continue;
-
- switch (values[i].attr) {
+ while (sdp_get_attr(rec, &attr, &value)) {
+ switch (attr) {
case SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST:
- control_psm = parse_l2cap_psm(&values[i]);
+ control_psm = parse_pdl(&value, SDP_UUID_PROTOCOL_L2CAP);
break;
case SDP_ATTR_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS:
- interrupt_psm = parse_l2cap_psm(&values[i]);
+ interrupt_psm = parse_apdl(&value, SDP_UUID_PROTOCOL_L2CAP);
break;
case 0x0205: /* HIDReconnectInitiate */
- reconnect_initiate = parse_boolean(&values[i]);
+ reconnect_initiate = parse_boolean(&value);
break;
case 0x0206: /* HIDDescriptorList */
- if (parse_hid_descriptor(&values[i]) == 0) {
- hid_descriptor = values[i].value;
- hid_length = values[i].vlen;
+ if (parse_hid_descriptor(&value)) {
+ hid_descriptor = value.next;
+ hid_length = value.end - value.next;
}
break;
- case 0x0209: /* HIDBatteryPower */
- battery_power = parse_boolean(&values[i]);
- break;
-
- case 0x020d: /* HIDNormallyConnectable */
- normally_connectable = parse_boolean(&values[i]);
+ default:
break;
}
}
@@ -310,26 +280,27 @@
* Configure HSET results
*/
static int
-config_hset(prop_dictionary_t dict)
+config_hset(prop_dictionary_t dict, sdp_data_t *rec)
{
prop_object_t obj;
- uint32_t channel;
- size_t i;
+ sdp_data_t value;
+ int32_t channel;
+ uint16_t attr;
channel = -1;
- for (i = 0; i < __arraycount(values); i++) {
- if (values[i].flags != SDP_ATTR_OK)
- continue;
-
- switch (values[i].attr) {
+ while (sdp_get_attr(rec, &attr, &value)) {
+ switch (attr) {
case SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST:
- channel = parse_rfcomm_channel(&values[i]);
+ channel = parse_pdl(&value, SDP_UUID_PROTOCOL_RFCOMM);
+ break;
+
+ default:
break;
}
}
- if (channel == (uint32_t)-1)
+ if (channel == -1)
return ENOATTR;
obj = prop_string_create_cstring_nocopy("btsco");
@@ -351,26 +322,27 @@
* Configure HF results
*/
static int
-config_hf(prop_dictionary_t dict)
+config_hf(prop_dictionary_t dict, sdp_data_t *rec)
{
prop_object_t obj;
- uint32_t channel;
- size_t i;
+ sdp_data_t value;
+ int32_t channel;
+ uint16_t attr;
channel = -1;
- for (i = 0; i < __arraycount(values); i++) {
- if (values[i].flags != SDP_ATTR_OK)
- continue;
-
- switch (values[i].attr) {
+ while (sdp_get_attr(rec, &attr, &value)) {
+ switch (attr) {
case SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST:
- channel = parse_rfcomm_channel(&values[i]);
+ channel = parse_pdl(&value, SDP_UUID_PROTOCOL_RFCOMM);
+ break;
+
+ default:
break;
}
}
- if (channel == (uint32_t)-1)
+ if (channel == -1)
return ENOATTR;
obj = prop_string_create_cstring_nocopy("btsco");
@@ -395,381 +367,138 @@
}
/*
- * Parse [additional] protocol descriptor list for L2CAP PSM
+ * Parse HIDDescriptorList . This is a sequence of HIDDescriptors, of which
+ * each is a data element sequence containing, minimally, a ClassDescriptorType
+ * and ClassDescriptorData containing a byte array of data. Any extra elements
+ * should be ignored.
*
- * seq8 len8 2
- * seq8 len8 2
- * uuid16 value16 3 L2CAP
- * uint16 value16 3 PSM
- * seq8 len8 2
- * uuid16 value16 3 HID Protocol
- * ===
- * 15
+ * If a ClassDescriptorType "Report" is found, set SDP data value to the
+ * ClassDescriptorData content and return true. Note that we don't need to
+ * extract the actual length as the SDP data is guaranteed valid.
*/
-static int32_t
-parse_l2cap_psm(sdp_attr_t *a)
+static bool
+parse_hid_descriptor(sdp_data_t *value)
{
- uint8_t *ptr = a->value;
- uint8_t *end = a->value + a->vlen;
- int32_t type, len, uuid, psm;
-
- if (end - ptr < 15)
- return (-1);
-
- if (a->attr == SDP_ATTR_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS) {
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_SEQ8:
- SDP_GET8(len, ptr);
- break;
-
- case SDP_DATA_SEQ16:
- SDP_GET16(len, ptr);
- break;
-
- case SDP_DATA_SEQ32:
- SDP_GET32(len, ptr);
- break;
-
- default:
- return (-1);
+ sdp_data_t list, desc;
+ uintmax_t type;
+ char *str;
+ size_t len;
+
+ if (!sdp_get_seq(value, &list))
+ return false;
+
+ while (sdp_get_seq(&list, &desc)) {
+ if (sdp_get_uint(&desc, &type)
+ && type == UDESC_REPORT
+ && sdp_get_str(&desc, &str, &len)) {
+ value->next = (uint8_t *)str;
+ value->end = (uint8_t *)(str + len);
+ return true;
}
- if (ptr + len > end)
- return (-1);
}
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_SEQ8:
- SDP_GET8(len, ptr);
- break;
-
- case SDP_DATA_SEQ16:
- SDP_GET16(len, ptr);
- break;
-
- case SDP_DATA_SEQ32:
- SDP_GET32(len, ptr);
- break;
-
- default:
- return (-1);
- }
- if (ptr + len > end)
- return (-1);
-
- /* Protocol */
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_SEQ8:
- SDP_GET8(len, ptr);
- break;
-
- case SDP_DATA_SEQ16:
- SDP_GET16(len, ptr);
- break;
-
- case SDP_DATA_SEQ32:
- SDP_GET32(len, ptr);
- break;
-
- default:
- return (-1);
- }
- if (ptr + len > end)
- return (-1);
-
- /* UUID */
- if (ptr + 3 > end)
- return (-1);
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_UUID16:
- SDP_GET16(uuid, ptr);
- if (uuid != SDP_UUID_PROTOCOL_L2CAP)
- return (-1);
- break;
+ return false;
+}
- case SDP_DATA_UUID32: /* XXX FIXME can we have 32-bit UUID */
- case SDP_DATA_UUID128: /* XXX FIXME can we have 128-bit UUID */
- default:
- return (-1);
- }
+static int32_t
+parse_boolean(sdp_data_t *value)
+{
+ bool bv;
- /* PSM */
- if (ptr + 3 > end)
- return (-1);
- SDP_GET8(type, ptr);
- if (type != SDP_DATA_UINT16)
- return (-1);
- SDP_GET16(psm, ptr);
+ if (!sdp_get_bool(value, &bv))
+ return -1;
- return (psm);
+ return bv;
}
/*
- * Parse HID descriptor string
+ * The ProtocolDescriptorList attribute describes one or
+ * more protocol stacks that may be used to gain access to
+ * the service dscribed by the service record.
+ *
+ * If the ProtocolDescriptorList describes a single stack,
+ * the attribute value takes the form of a data element
+ * sequence in which each element of the sequence is a
+ * protocol descriptor.
*
- * seq8 len8 2
- * seq8 len8 2
- * uint8 value8 2
- * str value 3
- * ===
- * 9
+ * seq
+ * <list>
+ *
+ * If it is possible for more than one kind of protocol
+ * stack to be used to gain access to the service, the
+ * ProtocolDescriptorList takes the form of a data element
+ * alternative where each member is a data element sequence
+ * consisting of a list of sequences describing each protocol
+ *
+ * alt
+ * seq
+ * <list>
+ * seq
+ * <list>
+ *
+ * Each ProtocolDescriptorList is a list containing a sequence for
+ * each protocol, where each sequence contains the protocol UUUID
+ * and any protocol specific parameters.
+ *
+ * seq
+ * uuid L2CAP
+ * uint16 psm
+ * seq
+ * uuid RFCOMM
+ * uint8 channel
+ *
+ * We want to extract the ProtocolSpecificParameter#1 for the
+ * given protocol, which will be an unsigned int.
*/
-
static int32_t
-parse_hid_descriptor(sdp_attr_t *a)
+parse_pdl_param(sdp_data_t *pdl, uint16_t proto)
{
- uint8_t *ptr = a->value;
- uint8_t *end = a->value + a->vlen;
- int32_t type, len, descriptor_type;
-
- if (end - ptr < 9)
- return (-1);
-
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_SEQ8:
- SDP_GET8(len, ptr);
- break;
+ sdp_data_t seq;
+ uintmax_t param;
- case SDP_DATA_SEQ16:
- SDP_GET16(len, ptr);
- break;
-
- case SDP_DATA_SEQ32:
- SDP_GET32(len, ptr);
- break;
-
- default:
- return (-1);
- }
- if (ptr + len > end)
- return (-1);
-
- while (ptr < end) {
- /* Descriptor */
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_SEQ8:
- if (ptr + 1 > end)
- return (-1);
- SDP_GET8(len, ptr);
- break;
-
- case SDP_DATA_SEQ16:
- if (ptr + 2 > end)
- return (-1);
- SDP_GET16(len, ptr);
- break;
-
- case SDP_DATA_SEQ32:
- if (ptr + 4 > end)
- return (-1);
- SDP_GET32(len, ptr);
- break;
-
- default:
- return (-1);
- }
-
- /* Descripor type */
- if (ptr + 1 > end)
- return (-1);
- SDP_GET8(type, ptr);
- if (type != SDP_DATA_UINT8 || ptr + 1 > end)
- return (-1);
- SDP_GET8(descriptor_type, ptr);
-
- /* Descriptor value */
- if (ptr + 1 > end)
- return (-1);
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_STR8:
- if (ptr + 1 > end)
- return (-1);
- SDP_GET8(len, ptr);
- break;
-
- case SDP_DATA_STR16:
- if (ptr + 2 > end)
- return (-1);
- SDP_GET16(len, ptr);
- break;
-
- case SDP_DATA_STR32:
- if (ptr + 4 > end)
- return (-1);
- SDP_GET32(len, ptr);
- break;
-
- default:
- return (-1);
- }
- if (ptr + len > end)
- return (-1);
-
- if (descriptor_type == UDESC_REPORT && len > 0) {
- a->value = ptr;
- a->vlen = len;
+ while (sdp_get_seq(pdl, &seq)) {
+ if (!sdp_match_uuid16(&seq, proto))
+ continue;
- return (0);
- }
+ if (sdp_get_uint(&seq, ¶m))
+ return param;
- ptr += len;
+ break;
}
- return (-1);
+ return -1;
}
-/*
- * Parse boolean value
- *
- * bool8 int8
- */
-
static int32_t
-parse_boolean(sdp_attr_t *a)
+parse_pdl(sdp_data_t *value, uint16_t proto)
{
- if (a->vlen != 2 || a->value[0] != SDP_DATA_BOOL)
- return (-1);
+ sdp_data_t seq;
+ int32_t param = -1;
+
+ sdp_get_alt(value, value); /* strip any alt header */
- return (a->value[1]);
+ while (param == -1 && sdp_get_seq(value, &seq))
+ param = parse_pdl_param(&seq, proto);
+
+ return param;
}
/*
- * Parse protocol descriptor list for the RFCOMM channel
- *
- * seq8 len8 2
- * seq8 len8 2
- * uuid16 value16 3 L2CAP
- * seq8 len8 2
- * uuid16 value16 3 RFCOMM
- * uint8 value8 2 channel
- * ===
- * 14
+ * Parse AdditionalProtocolDescriptorList
*/
-
static int32_t
-parse_rfcomm_channel(sdp_attr_t *a)
+parse_apdl(sdp_data_t *value, uint16_t proto)
{
- uint8_t *ptr = a->value;
- uint8_t *end = a->value + a->vlen;
- int32_t type, len, uuid, channel;
-
- if (end - ptr < 14)
- return (-1);
-
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_SEQ8:
- SDP_GET8(len, ptr);
- break;
-
- case SDP_DATA_SEQ16:
- SDP_GET16(len, ptr);
- break;
-
- case SDP_DATA_SEQ32:
- SDP_GET32(len, ptr);
- break;
-
- default:
- return (-1);
- }
- if (ptr + len > end)
- return (-1);
-
- /* Protocol */
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_SEQ8:
- SDP_GET8(len, ptr);
- break;
-
- case SDP_DATA_SEQ16:
- SDP_GET16(len, ptr);
- break;
-
- case SDP_DATA_SEQ32:
- SDP_GET32(len, ptr);
- break;
-
- default:
- return (-1);
- }
- if (ptr + len > end)
- return (-1);
-
- /* UUID */
- if (ptr + 3 > end)
- return (-1);
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_UUID16:
- SDP_GET16(uuid, ptr);
- if (uuid != SDP_UUID_PROTOCOL_L2CAP)
- return (-1);
- break;
-
- case SDP_DATA_UUID32: /* XXX FIXME can we have 32-bit UUID */
- case SDP_DATA_UUID128: /* XXX FIXME can we have 128-bit UUID */
- default:
- return (-1);
- }
-
- /* Protocol */
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_SEQ8:
- SDP_GET8(len, ptr);
- break;
-
- case SDP_DATA_SEQ16:
- SDP_GET16(len, ptr);
- break;
-
- case SDP_DATA_SEQ32:
- SDP_GET32(len, ptr);
- break;
-
- default:
- return (-1);
- }
- if (ptr + len > end)
- return (-1);
-
- /* UUID */
- if (ptr + 3 > end)
- return (-1);
- SDP_GET8(type, ptr);
- switch (type) {
- case SDP_DATA_UUID16:
- SDP_GET16(uuid, ptr);
- if (uuid != SDP_UUID_PROTOCOL_RFCOMM)
- return (-1);
- break;
-
- case SDP_DATA_UUID32: /* XXX FIXME can we have 32-bit UUID */
- case SDP_DATA_UUID128: /* XXX FIXME can we have 128-bit UUID */
- default:
- return (-1);
- }
-
- /* channel */
- if (ptr + 2 > end)
- return (-1);
+ sdp_data_t seq;
+ int32_t param = -1;
- SDP_GET8(type, ptr);
- if (type != SDP_DATA_UINT8)
- return (-1);
+ sdp_get_seq(value, value); /* strip seq header */
- SDP_GET8(channel, ptr);
+ while (param == -1 && sdp_get_seq(value, &seq))
+ param = parse_pdl_param(&seq, proto);
- return (channel);
+ return param;
}
/*