Ejemplo n.º 1
0
/*
 * The matching process is defined as "each and every UUID
 * specified in the "search pattern" must be present in the
 * "target pattern". Here "search pattern" is the set of UUIDs
 * specified by the service discovery client and "target pattern"
 * is the set of UUIDs present in a service record.
 *
 * Return 1 if each and every UUID in the search
 * pattern exists in the target pattern, 0 if the
 * match succeeds and -1 on error.
 */
static int sdp_match_uuid(sdp_list_t *search, sdp_list_t *pattern)
{
	/*
	 * The target is a sorted list, so we need not look
	 * at all elements to confirm existence of an element
	 * from the search pattern
	 */
	int patlen = sdp_list_len(pattern);

	if (patlen < sdp_list_len(search))
		return -1;
	for (; search; search = search->next) {
		uuid_t *uuid128;
		void *data = search->data;
		sdp_list_t *list;
		if (data == NULL)
			return -1;

		// create 128-bit form of the search UUID
		uuid128 = sdp_uuid_to_uuid128((uuid_t *)data);
		list = sdp_list_find(pattern, uuid128, sdp_uuid128_cmp);
		bt_free(uuid128);
		if (!list)
			return 0;
	}
	return 1;
}
Ejemplo n.º 2
0
/*
 * Extract attribute identifiers from the request PDU.
 * Clients could request a subset of attributes (by id)
 * from a service record, instead of the whole set. The
 * requested identifiers are present in the PDU form of
 * the request
 */
static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, sdp_buf_t *buf)
{
	sdp_buf_t pdu;

	if (!rec)
		return SDP_INVALID_RECORD_HANDLE;

	if (seq) {
		SDPDBG("Entries in attr seq : %d", sdp_list_len(seq));
	} else {
		SDPDBG("NULL attribute descriptor");
	}

	if (seq == NULL) {
		SDPDBG("Attribute sequence is NULL");
		return 0;
	}

	sdp_gen_record_pdu(rec, &pdu);

	for (; seq; seq = seq->next) {
		struct attrid *aid = seq->data;

		SDPDBG("AttrDataType : %d", aid->dtd);

		if (aid->dtd == SDP_UINT16) {
			uint16_t attr = bt_get_unaligned((uint16_t *)&aid->uint16);
			sdp_data_t *a = (sdp_data_t *)sdp_data_get(rec, attr);
			if (a)
				sdp_append_to_pdu(buf, a);
		} else if (aid->dtd == SDP_UINT32) {
			uint32_t range = bt_get_unaligned((uint32_t *)&aid->uint32);
			uint16_t attr;
			uint16_t low = (0xffff0000 & range) >> 16;
			uint16_t high = 0x0000ffff & range;
			sdp_data_t *data;

			SDPDBG("attr range : 0x%x", range);
			SDPDBG("Low id : 0x%x", low);
			SDPDBG("High id : 0x%x", high);

			if (low == 0x0000 && high == 0xffff && pdu.data_size <= buf->buf_size) {
				/* copy it */
				memcpy(buf->data, pdu.data, pdu.data_size);
				buf->data_size = pdu.data_size;
				break;
			}
			/* (else) sub-range of attributes */
			for (attr = low; attr < high; attr++) {
				data = sdp_data_get(rec, attr);
				if (data)
					sdp_append_to_pdu(buf, data);
			}
			data = sdp_data_get(rec, high);
			if (data)
				sdp_append_to_pdu(buf, data);
		} else {
Ejemplo n.º 3
0
/*
 *  100% taken from bluez-utils (sdptool)
 */
static sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto)
{
	sdp_data_t *seq = NULL;
	void *dtds[10], *values[10];
	void **seqDTDs, **seqs;
	int i, seqlen;
	sdp_list_t *p;

	seqlen = sdp_list_len(proto);
	seqDTDs = (void **)malloc(seqlen * sizeof(void *));
	seqs = (void **)malloc(seqlen * sizeof(void *));
	for (i = 0, p = proto; p; p = p->next, i++) {
		sdp_list_t *elt = (sdp_list_t *)p->data;
		sdp_data_t *s;
		int pslen = 0;
		for (; elt && pslen < sizeof(dtds); elt = elt->next, pslen++) {
			sdp_data_t *d = (sdp_data_t *)elt->data;
			dtds[pslen] = &d->dtd;
			switch (d->dtd) {
			case SDP_UUID16:
				values[pslen] = &((uuid_t *)d)->value.uuid16;
				break;
			case SDP_UUID32:
				values[pslen] = &((uuid_t *)d)->value.uuid32;
				break;
			case SDP_UUID128:
				values[pslen] = &((uuid_t *)d)->value.uuid128;
				break;
			case SDP_UINT8:
				values[pslen] = &d->val.uint8;
				break;
			case SDP_UINT16:
				values[pslen] = &d->val.uint16;
				break;
			case SDP_SEQ8:
			case SDP_SEQ16:
			case SDP_SEQ32:
				values[pslen] = d;
				break;
			// FIXME: more
			}
		}
		s = sdp_seq_alloc(dtds, values, pslen);
		if (s) {
			seqDTDs[i] = &s->dtd;
			seqs[i] = s;
		}
	}
	seq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
	free(seqDTDs);
	free(seqs);
	return seq;
}
Ejemplo n.º 4
0
/*
 * Extract attribute identifiers from the request PDU.
 * Clients could request a subset of attributes (by id)
 * from a service record, instead of the whole set. The
 * requested identifiers are present in the PDU form of
 * the request
 */
static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_buf_t *buf)
{
	if (!rec)
		return SDP_INVALID_RECORD_HANDLE;

#ifdef SDP_DEBUG
	if (seq)
		SDPDBG("Entries in attr seq : %d\n", sdp_list_len(seq));
	else
		SDPDBG("NULL attribute descriptor\n");
	SDPDBG("AttrDataType : %d\n", dtd);
#endif
	if (seq == NULL) {
		SDPDBG("Attribute sequence is NULL\n");
		return 0;
	}
	if (dtd == SDP_UINT16)
		for (; seq; seq = seq->next) {
			uint16_t attr = sdp_get_unaligned((uint16_t *)seq->data);
			sdp_data_t *a = (sdp_data_t *)sdp_data_get(rec, attr);
			if (a)
				sdp_append_to_pdu(buf, a);
		}
	else if (dtd == SDP_UINT32) {
		sdp_buf_t pdu;
		sdp_gen_record_pdu(rec, &pdu);
		for (; seq; seq = seq->next) {
			uint32_t range = sdp_get_unaligned((uint32_t *)seq->data);
			uint16_t attr;
			uint16_t low = (0xffff0000 & range) >> 16;
			uint16_t high = 0x0000ffff & range;

			SDPDBG("attr range : 0x%x\n", range);
			SDPDBG("Low id : 0x%x\n", low);
			SDPDBG("High id : 0x%x\n", high);

			if (low == 0x0000 && high == 0xffff && pdu.data_size <= buf->buf_size) {
				/* copy it */
				memcpy(buf->data, pdu.data, pdu.data_size);
				buf->data_size = pdu.data_size;
				break;
			}
			/* (else) sub-range of attributes */
			for (attr = low; attr <= high; attr++) {
				sdp_data_t *a = (sdp_data_t *)sdp_data_get(rec, attr);
				if (a)
					sdp_append_to_pdu(buf, a);
			}
		}
		free(pdu.data);
	} else {