Exemplo n.º 1
0
	switch (cfg->codec) {
	case CODEC_SBC:
		break;
#ifdef HAVE_FFMPEG
	case CODEC_AAC:
		break;
#endif

	default:
		break;
	}
	return (bt_close(pbe));
}

static const uint32_t bt_attrs[] = {
	SDP_ATTR_RANGE(SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
	    SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST),
};

#define	BT_NUM_VALUES 32
#define	BT_BUF_SIZE 32

static int
bt_find_psm(const uint8_t *start, const uint8_t *end)
{
	uint32_t type;
	uint32_t len;
	int protover = 0;
	int psm = -1;

	if ((end - start) < 2)
		return (-1);
Exemplo n.º 2
0
 * $Id: search.c,v 1.2 2003/09/08 17:35:15 max Exp $
 * $FreeBSD: release/9.0.0/usr.sbin/bluetooth/sdpcontrol/search.c 173335 2007-11-04 21:24:33Z emax $
 */

#include <netinet/in.h>
#include <bluetooth.h>
#include <ctype.h>
#include <sdp.h>
#include <stdio.h>
#include <stdlib.h>
#include "sdpcontrol.h"

/* List of the attributes we are looking for */
static uint32_t	attrs[] =
{
	SDP_ATTR_RANGE(	SDP_ATTR_SERVICE_RECORD_HANDLE,
			SDP_ATTR_SERVICE_RECORD_HANDLE),
	SDP_ATTR_RANGE(	SDP_ATTR_SERVICE_CLASS_ID_LIST,
			SDP_ATTR_SERVICE_CLASS_ID_LIST),
	SDP_ATTR_RANGE(	SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
			SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST),
	SDP_ATTR_RANGE(	SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST,
			SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST)
};
#define attrs_len	(sizeof(attrs)/sizeof(attrs[0]))

/* Buffer for the attributes */
#define NRECS	25	/* request this much records from the SDP server */
#define	BSIZE	256	/* one attribute buffer size */
static uint8_t		buffer[NRECS * attrs_len][BSIZE];

/* SDP attributes */
Exemplo n.º 3
0
static int find_service_channel(bdaddr_t *adapter, bdaddr_t *device, int only_gnapplet, uint16_t svclass_id)
{
	int i, channel = -1;
	char name[64];
	void *ss = NULL;
	uint32_t attrs[] = {
		SDP_ATTR_RANGE( SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
			SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST),
		SDP_ATTR_RANGE( SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET,
			SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET),
	};
	/* Buffer for the attributes */
	static uint8_t          buffer[NRECS * attrs_len][BSIZE];
	/* SDP attributes */
	static sdp_attr_t       values[NRECS * attrs_len];

	/* Initialize attribute values array */
	for (i = 0; i < values_len; i ++) {
		values[i].flags = SDP_ATTR_INVALID;
		values[i].attr = 0;
		values[i].vlen = BSIZE;
		values[i].value = buffer[i];
	}

	if ((ss = sdp_open(adapter, device)) == NULL)
		return -1;

	if (sdp_error(ss) != 0)
		goto end;

	if (sdp_search(ss, 1, &svclass_id, attrs_len, attrs, values_len, values) != 0)
		goto end;

	for (i = 0; i < values_len; i++) {
		union {
			uint8_t		uint8;
			uint16_t	uint16;
			uint32_t	uint32;
			uint64_t	uint64;
			int128_t	int128;
		} value;
		uint8_t *start, *end;
		uint32_t type, len;

		if (values[i].flags != SDP_ATTR_OK)
			break;

		start = values[i].value;
		end = values[i].value + values[i].vlen;

		switch (values[i].attr) {
		case SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST:
			SDP_GET8(type, start);
			switch (type) {
			case SDP_DATA_SEQ8:
				SDP_GET8(len, start);
				break;

			case SDP_DATA_SEQ16:
				SDP_GET16(len, start);
				break;

			case SDP_DATA_SEQ32:
				SDP_GET32(len, start);
				break;

			default:
				goto end;
				break;
			}

			SDP_GET8(type, start);
			switch (type) {
			case SDP_DATA_SEQ8:
				SDP_GET8(len, start);
				break;

			case SDP_DATA_SEQ16:
				SDP_GET16(len, start);
				break;

			case SDP_DATA_SEQ32:
				SDP_GET32(len, start);
				break;

			default:
				goto end;
			}

			while (start < end) {
				SDP_GET8(type, start);
				switch (type) {
				case SDP_DATA_UUID16:
					SDP_GET16(value.uint16, start);
					break;

				case SDP_DATA_UUID32:
					SDP_GET32(value.uint32, start);
					break;

				case SDP_DATA_UUID128:
					SDP_GET_UUID128(&value.int128, start);
					break;

				default:
					goto end;
				}
				if (value.uint16 == 3) {
					SDP_GET8(type, start);
					switch (type) {
					case SDP_DATA_UINT8:
					case SDP_DATA_INT8:
						SDP_GET8(value.uint8, start);
						channel = value.uint8;
						break;

					case SDP_DATA_UINT16:
					case SDP_DATA_INT16:
						SDP_GET16(value.uint16, start);
						channel = value.uint16;
						break;

					case SDP_DATA_UINT32:
					case SDP_DATA_INT32:
						SDP_GET32(value.uint32, start);
						channel = value.uint32;
						break;

					default:
						goto end;
					}
				} else {
					SDP_GET8(type, start);
					switch (type) {
					case SDP_DATA_SEQ8:
					case SDP_DATA_UINT8:
					case SDP_DATA_INT8:
					case SDP_DATA_BOOL:
						SDP_GET8(value.uint8, start);
						break;

					case SDP_DATA_SEQ16:
					case SDP_DATA_UINT16:
					case SDP_DATA_INT16:
					case SDP_DATA_UUID16:
						SDP_GET16(value.uint16, start);
						break;

					case SDP_DATA_SEQ32:
					case SDP_DATA_UINT32:
					case SDP_DATA_INT32:
					case SDP_DATA_UUID32:
						SDP_GET32(value.uint32, start);
						break;

					case SDP_DATA_UINT64:
					case SDP_DATA_INT64:
						SDP_GET64(value.uint64, start);
						break;

					case SDP_DATA_UINT128:
					case SDP_DATA_INT128:
						SDP_GET128(&value.int128, start);
						break;

					default:
						goto end;
					}
				}
			}
			start += len;
			break;

		case SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET:
			if (channel == -1)
				break;
			
			SDP_GET8(type, start);
			switch (type) {
				case SDP_DATA_STR8:
				case SDP_DATA_URL8:
					SDP_GET8(len, start);
					snprintf(name, sizeof(name), "%*.*s", len, len, (char *) start);
					start += len;
					break;

				case SDP_DATA_STR16:
				case SDP_DATA_URL16:
					SDP_GET16(len, start);
					snprintf(name, sizeof(name), "%*.*s", len, len, (char *) start);
					start += len;
					break;

				case SDP_DATA_STR32:
				case SDP_DATA_URL32:
					SDP_GET32(len, start);
					snprintf(name, sizeof(name), "%*.*s", len, len, (char *) start);
					start += len;
					break;

				default:
					goto end;
			}
			if (name == NULL)
				break;

			if (only_gnapplet != 0) {
				if (strcmp(name, "gnapplet") == 0)
					goto end;
				else {
					channel = -1;
					break;
				}
			}
			
			if (strstr(name, "Nokia PC Suite") != NULL) {
				channel = -1;
				break;
			}

			if (strstr(name, "Bluetooth Serial Port") != NULL) {
				channel = -1;
				break;
			}

			if (strstr(name, "m-Router Connectivity") != NULL) {
				channel = -1;
				break;
			}

			goto end;
		}
	}

end:
	sdp_close(ss);
	return channel;
}
Exemplo n.º 4
0
static void
client_query(void)
{
	uint8_t buffer[512];
	sdp_attr_t attr;
	uint32_t range;
	void *ss;
	int rv;
	uint8_t *seq0, *seq1;

	attr.flags = SDP_ATTR_INVALID;
	attr.attr = 0;
	attr.vlen = sizeof(buffer);
	attr.value = buffer;

	range = SDP_ATTR_RANGE(SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
			       SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);

	ss = sdp_open(&local_bdaddr, &remote_bdaddr);
	if (ss == NULL || (errno = sdp_error(ss)) != 0) {
		log_err("%s: %m", service_name);
		exit(EXIT_FAILURE);
	}

	log_info("Searching for %s service at %s",
	    service_name, bt_ntoa(&remote_bdaddr, NULL));

	rv = sdp_search(ss, 1, &service_class, 1, &range, 1, &attr);
	if (rv != 0) {
		log_err("%s: %s", service_name, strerror(sdp_error(ss)));
		exit(EXIT_FAILURE);
	}

	sdp_close(ss);

	if (attr.flags != SDP_ATTR_OK
	    || attr.attr != SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST) {
		log_err("%s service not found", service_name);
		exit(EXIT_FAILURE);
	}

	/*
	 * we expect the following protocol descriptor list
	 *
	 *	seq len
	 *	  seq len
	 *	    uuid value == L2CAP
	 *	    uint16 value16 => PSM
	 *	  seq len
	 *	    uuid value == BNEP
	 */
	if (_sdp_get_seq(&attr.value, attr.value + attr.vlen, &seq0)
	    && _sdp_get_seq(&seq0, attr.value, &seq1)
	    && _sdp_match_uuid16(&seq1, seq0, SDP_UUID_PROTOCOL_L2CAP)
	    && _sdp_get_uint16(&seq1, seq0, &l2cap_psm)
	    && _sdp_get_seq(&seq0, attr.value, &seq1)
	    && _sdp_match_uuid16(&seq1, seq0, SDP_UUID_PROTOCOL_BNEP)) {
		log_info("Found PSM %d for service %s", l2cap_psm, service_name);
		return;
	}

	log_err("%s query failed", service_name);
	exit(EXIT_FAILURE);
}
Exemplo n.º 5
0
int
rfcomm_channel_lookup(bdaddr_t const *local, bdaddr_t const *remote,
			int service, int *channel, int *error)
{
	uint8_t		 buffer[PROTOCOL_DESCRIPTOR_LIST_BUFFER_SIZE];
	void		*ss    = NULL;
	uint16_t	 serv  = (uint16_t) service;
	uint32_t	 attr  = SDP_ATTR_RANGE(
					SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
					SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
	sdp_attr_t	 proto = { SDP_ATTR_INVALID,0,sizeof(buffer),buffer };
	uint32_t	 type, len;

	if (local == NULL)
		local = NG_HCI_BDADDR_ANY;
	if (remote == NULL || channel == NULL)
		rfcomm_channel_lookup_exit(EINVAL);

	if ((ss = sdp_open(local, remote)) == NULL)
		rfcomm_channel_lookup_exit(ENOMEM);
	if (sdp_error(ss) != 0)
		rfcomm_channel_lookup_exit(sdp_error(ss));

	if (sdp_search(ss, 1, &serv, 1, &attr, 1, &proto) != 0)
		rfcomm_channel_lookup_exit(sdp_error(ss));
	if (proto.flags != SDP_ATTR_OK)
		rfcomm_channel_lookup_exit(ENOATTR);

	sdp_close(ss);
	ss = NULL;

	/*
	 * 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. We always use the
	 * first protocol stack.
	 *
	 * A minimal Protocol Descriptor List for RFCOMM based service would
	 * look like
	 *
	 * seq8 len8			- 2 bytes
	 *	seq8 len8		- 2 bytes
	 *		uuid16 value16	- 3 bytes	L2CAP
	 *	seq8 len8		- 2 bytes
	 *		uuid16 value16	- 3 bytes	RFCOMM
	 *		uint8  value8	- 2 bytes	RFCOMM param #1 
	 *				=========
	 *				 14 bytes
	 *
	 * Lets not count first [seq8 len8] wrapper, so the minimal size of 
	 * the Protocol Descriptor List (the data we are actually interested
	 * in) for RFCOMM based service would be 12 bytes.
	 */

	if (proto.vlen < PROTOCOL_DESCRIPTOR_LIST_MINIMAL_SIZE)
		rfcomm_channel_lookup_exit(EINVAL);

	SDP_GET8(type, proto.value);

	if (type == SDP_DATA_ALT8) {
		SDP_GET8(len, proto.value);
	} else if (type == SDP_DATA_ALT16) {
		SDP_GET16(len, proto.value);
	} else if (type == SDP_DATA_ALT32) {
		SDP_GET32(len, proto.value);
	} else
		len = 0;

	if (len > 0)
		SDP_GET8(type, proto.value);

	switch (type) {
	case SDP_DATA_SEQ8:
		SDP_GET8(len, proto.value);
		break;

	case SDP_DATA_SEQ16:
		SDP_GET16(len, proto.value);
		break;

	case SDP_DATA_SEQ32:
		SDP_GET32(len, proto.value);
		break;

	default:
		rfcomm_channel_lookup_exit(ENOATTR);
		/* NOT REACHED */
	}

	if (len < PROTOCOL_DESCRIPTOR_LIST_MINIMAL_SIZE)
		rfcomm_channel_lookup_exit(EINVAL);

	return (rfcomm_proto_list_parse(proto.value,
					buffer + proto.vlen, channel, error));
}
Exemplo n.º 6
0
#include <sdp.h>
#include <stdio.h>
#include <string.h>
#include <usbhid.h>
#include "bthid_config.h"
#include "bthidcontrol.h"

static int32_t hid_sdp_query				(bdaddr_t const *local, struct hid_device *hd, int32_t *error);
static int32_t hid_sdp_parse_protocol_descriptor_list	(sdp_attr_p a);
static int32_t hid_sdp_parse_hid_descriptor		(sdp_attr_p a);
static int32_t hid_sdp_parse_boolean			(sdp_attr_p a);

static uint16_t		service = SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE;

static uint32_t		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 */
		0x0205),
SDP_ATTR_RANGE(	0x0206,		/* HIDDescriptorList */
		0x0206),
SDP_ATTR_RANGE(	0x0209,		/* HIDBatteryPower */
		0x0209),
SDP_ATTR_RANGE(	0x020d,		/* HIDNormallyConnectable */
		0x020d)
	};
#define	nattrs	(sizeof(attrs)/sizeof(attrs[0]))

static sdp_attr_t	values[8];
#define	nvalues	(sizeof(values)/sizeof(values[0]))