additionally query the "PnP Information" service record to discover
any USB Forum vendor-id and product-id values and store them in the property list if found.
This commit is contained in:
parent
0f7dbb350e
commit
366a13e705
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: print.c,v 1.9 2007/08/17 17:59:16 pavel Exp $ */
|
||||
/* $NetBSD: print.c,v 1.10 2010/04/28 06:18:07 plunky Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
@ -58,7 +58,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: print.c,v 1.9 2007/08/17 17:59:16 pavel Exp $");
|
||||
__RCSID("$NetBSD: print.c,v 1.10 2010/04/28 06:18:07 plunky Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
@ -86,6 +86,7 @@ void
|
||||
cfg_print(prop_dictionary_t dict)
|
||||
{
|
||||
prop_object_t obj;
|
||||
uint16_t v;
|
||||
|
||||
obj = prop_dictionary_get(dict, BTDEVladdr);
|
||||
if (prop_object_type(obj) != PROP_TYPE_DATA) {
|
||||
@ -103,6 +104,12 @@ cfg_print(prop_dictionary_t dict)
|
||||
if (prop_object_type(obj) == PROP_TYPE_STRING)
|
||||
printf("link mode: %s\n", prop_string_cstring_nocopy(obj));
|
||||
|
||||
if (prop_dictionary_get_uint16(dict, BTDEVvendor, &v))
|
||||
printf("vendor id: 0x%04x\n", v);
|
||||
|
||||
if (prop_dictionary_get_uint16(dict, BTDEVproduct, &v))
|
||||
printf("product id: 0x%04x\n", v);
|
||||
|
||||
obj = prop_dictionary_get(dict, BTDEVtype);
|
||||
if (prop_object_type(obj) != PROP_TYPE_STRING) {
|
||||
printf("No device type!\n");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sdp.c,v 1.7 2009/05/12 18:39:20 plunky Exp $ */
|
||||
/* $NetBSD: sdp.c,v 1.8 2010/04/28 06:18:07 plunky Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
@ -56,7 +56,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: sdp.c,v 1.7 2009/05/12 18:39:20 plunky Exp $");
|
||||
__RCSID("$NetBSD: sdp.c,v 1.8 2010/04/28 06:18:07 plunky Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
@ -84,10 +84,15 @@ 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_pnp(prop_dictionary_t, sdp_data_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 pnp_services[] = {
|
||||
SDP_SERVICE_CLASS_PNP_INFORMATION,
|
||||
};
|
||||
|
||||
uint16_t hid_services[] = {
|
||||
SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE,
|
||||
};
|
||||
@ -123,14 +128,58 @@ static struct {
|
||||
|
||||
#define MAX_SSP (2 + 1 * 3) /* largest nservices is 1 */
|
||||
|
||||
static bool
|
||||
cfg_ssa(sdp_session_t ss, uint16_t *services, size_t nservices, sdp_data_t *rsp)
|
||||
{
|
||||
uint8_t buf[MAX_SSP];
|
||||
sdp_data_t ssp;
|
||||
size_t i;
|
||||
|
||||
ssp.next = buf;
|
||||
ssp.end = buf + sizeof(buf);
|
||||
|
||||
for (i = 0; i < nservices; i++)
|
||||
sdp_put_uuid16(&ssp, services[i]);
|
||||
|
||||
ssp.end = ssp.next;
|
||||
ssp.next = buf;
|
||||
|
||||
return sdp_service_search_attribute(ss, &ssp, NULL, rsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
cfg_search(sdp_session_t ss, int i, prop_dictionary_t dict)
|
||||
{
|
||||
sdp_data_t rsp, rec;
|
||||
|
||||
/* check PnP Information first */
|
||||
if (!cfg_ssa(ss, pnp_services, __arraycount(pnp_services), &rsp))
|
||||
return false;
|
||||
|
||||
while (sdp_get_seq(&rsp, &rec)) {
|
||||
if (config_pnp(dict, &rec) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* then requested service */
|
||||
if (!cfg_ssa(ss, cfgtype[i].services, cfgtype[i].nservices, &rsp))
|
||||
return false;
|
||||
|
||||
while (sdp_get_seq(&rsp, &rec)) {
|
||||
errno = (*cfgtype[i].handler)(dict, &rec);
|
||||
if (errno == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
cfg_query(bdaddr_t *laddr, bdaddr_t *raddr, const char *service)
|
||||
{
|
||||
prop_dictionary_t dict;
|
||||
sdp_session_t ss;
|
||||
uint8_t buf[MAX_SSP];
|
||||
sdp_data_t ssp, rsp, rec;
|
||||
size_t i, n;
|
||||
size_t i;
|
||||
bool rv;
|
||||
|
||||
dict = prop_dictionary_create();
|
||||
@ -140,35 +189,15 @@ cfg_query(bdaddr_t *laddr, bdaddr_t *raddr, const char *service)
|
||||
for (i = 0; i < __arraycount(cfgtype); i++) {
|
||||
if (strcasecmp(service, cfgtype[i].name) == 0) {
|
||||
ss = sdp_open(laddr, raddr);
|
||||
if (ss == NULL)
|
||||
return NULL;
|
||||
if (ss != NULL) {
|
||||
rv = cfg_search(ss, i, dict);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
while (sdp_get_seq(&rsp, &rec)) {
|
||||
errno = (*cfgtype[i].handler)(dict, &rec);
|
||||
if (errno == 0) {
|
||||
sdp_close(ss);
|
||||
if (rv == true)
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
|
||||
sdp_close(ss);
|
||||
prop_object_release(dict);
|
||||
return NULL;
|
||||
}
|
||||
@ -181,6 +210,64 @@ cfg_query(bdaddr_t *laddr, bdaddr_t *raddr, const char *service)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure PnP Information results
|
||||
*/
|
||||
static int
|
||||
config_pnp(prop_dictionary_t dict, sdp_data_t *rec)
|
||||
{
|
||||
sdp_data_t value;
|
||||
uintmax_t v;
|
||||
uint16_t attr;
|
||||
int vendor, product, source;
|
||||
|
||||
vendor = -1;
|
||||
product = -1;
|
||||
source = -1;
|
||||
|
||||
while (sdp_get_attr(rec, &attr, &value)) {
|
||||
switch (attr) {
|
||||
case 0x0201: /* Vendor ID */
|
||||
if (sdp_get_uint(&value, &v)
|
||||
&& v <= UINT16_MAX)
|
||||
vendor = (int)v;
|
||||
|
||||
break;
|
||||
|
||||
case 0x0202: /* Product ID */
|
||||
if (sdp_get_uint(&value, &v)
|
||||
&& v <= UINT16_MAX)
|
||||
product = (int)v;
|
||||
|
||||
break;
|
||||
|
||||
case 0x0205: /* Vendor ID Source */
|
||||
if (sdp_get_uint(&value, &v)
|
||||
&& v <= UINT16_MAX)
|
||||
source = (int)v;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vendor == -1 || product == -1)
|
||||
return ENOATTR;
|
||||
|
||||
if (source != 0x0002) /* "USB Implementers Forum" */
|
||||
return ENOATTR;
|
||||
|
||||
if (!prop_dictionary_set_uint16(dict, BTDEVvendor, (uint16_t)vendor))
|
||||
return errno;
|
||||
|
||||
if (!prop_dictionary_set_uint16(dict, BTDEVproduct, (uint16_t)product))
|
||||
return errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure HID results
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user