⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 attr.c

📁 蓝牙的各种编程接口和各种按理介绍,还有一些例子和说明
💻 C
字号:
/*   Service Discovery Protocol (SDP)   Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>, Stephen Crane <steve.crane@rococosoft.com>      Based on original SDP implementation by Nokia Corporation.   Copyright (C) 2001,2002 Nokia Corporation.   Original author Guruprasad Krishnamurthy <guruprasad.krishnamurthy@nokia.com>      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License version 2 as   published by the Free Software Foundation;      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM,   OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER   RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,   NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE   USE OR PERFORMANCE OF THIS SOFTWARE.      ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS,   TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED.*//*   Fixes:	Guruprasad Krishnamurthy <guruprasad.krishnamurthy@nokia.com>*//* * $Id: attr.c,v 1.33 2003/08/19 11:15:00 jscrane Exp $ */#include <malloc.h>#include "sdp.h"#include "sdp_lib.h"#include "sdp_internal.h"sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value){	sdp_data_t *seq;	int len = 0;	sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t));	if (!d)		return NULL;	memset(d, 0, sizeof(sdp_data_t));	d->dtd = dtd;	d->unitSize = sizeof(uint8_t);	switch (dtd) {	case SDP_DATA_NIL:		break;	case SDP_UINT8:		d->val.uint8 = *(uint8_t *)value;		d->unitSize += sizeof(uint8_t);		break;	case SDP_INT8:	case SDP_BOOL:		d->val.int8 = *(int8_t *)value;		d->unitSize += sizeof(int8_t);		break;	case SDP_UINT16:		d->val.uint16 = sdp_get_unaligned((uint16_t *)value);		d->unitSize += sizeof(uint16_t);		break;	case SDP_INT16:		d->val.int16 = sdp_get_unaligned((int16_t *)value);		d->unitSize += sizeof(int16_t);		break;	case SDP_UINT32:		d->val.uint32 = sdp_get_unaligned((uint32_t *)value);		d->unitSize += sizeof(uint32_t);		break;	case SDP_INT32:		d->val.int32 = sdp_get_unaligned((int32_t *)value);		d->unitSize += sizeof(int32_t);		break;	case SDP_INT64:		d->val.int64 = sdp_get_unaligned((int64_t *)value);		d->unitSize += sizeof(int64_t);		break;	case SDP_UINT64:		d->val.uint64 = sdp_get_unaligned((uint64_t *)value);		d->unitSize += sizeof(uint64_t);		break;	case SDP_UINT128:		memcpy(&d->val.uint128.data, value, sizeof(uint128_t));		d->unitSize += sizeof(uint128_t);		break;	case SDP_INT128:		memcpy(&d->val.int128.data, value, sizeof(uint128_t));		d->unitSize += sizeof(uint128_t);		break;	case SDP_UUID16:		sdp_uuid16_create(&d->val.uuid, sdp_get_unaligned((uint16_t *)value));		d->unitSize += sizeof(uint16_t);		break;	case SDP_UUID32:		sdp_uuid32_create(&d->val.uuid, sdp_get_unaligned((uint32_t *)value));		d->unitSize += sizeof(uint32_t);		break;	case SDP_UUID128:		sdp_uuid128_create(&d->val.uuid, value);		d->unitSize += sizeof(uint128_t);		break;	case SDP_URL_STR8:	case SDP_TEXT_STR8:	case SDP_URL_STR16:	case SDP_TEXT_STR16:		if (!value)			goto out_error;			len = strlen(value);		d->unitSize += len;		if (len <= USHRT_MAX) {			d->val.str = (char *)malloc(len + 1);			if (!d->val.str)				goto out_error;			strcpy(d->val.str, value);			if (len <= UCHAR_MAX) {				d->unitSize += sizeof(uint8_t);				if (dtd != SDP_URL_STR8 && dtd != SDP_TEXT_STR8) {					if (dtd == SDP_URL_STR16)						dtd = SDP_URL_STR8;					else						dtd = SDP_TEXT_STR8;				}			} else {				d->unitSize += sizeof(uint16_t);				if (dtd == SDP_TEXT_STR8)					dtd = SDP_TEXT_STR16;				else					dtd = SDP_URL_STR16;			}		} else {			SDPERR("Strings of size > USHRT_MAX not supported\n");			goto out_error;		}		break;	case SDP_URL_STR32:	case SDP_TEXT_STR32:		SDPERR("Strings of size > USHRT_MAX not supported\n");		break;	case SDP_ALT8:	case SDP_ALT16:	case SDP_ALT32:	case SDP_SEQ8:	case SDP_SEQ16:	case SDP_SEQ32:		if (dtd == SDP_ALT8 || dtd == SDP_SEQ8)			d->unitSize += sizeof(uint8_t);		else if (dtd == SDP_ALT16 || dtd == SDP_SEQ16)			d->unitSize += sizeof(uint16_t);		else if (dtd == SDP_ALT32 || dtd == SDP_SEQ32)			d->unitSize += sizeof(uint32_t);		seq = (sdp_data_t *)value;		d->val.dataseq = seq;		for (; seq; seq = seq->next)			d->unitSize += seq->unitSize;		break;	default:		goto out_error;	}	return d;out_error:	free(d);	return NULL;}sdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d){	if (seq) {		sdp_data_t *p;		for (p = seq; p->next; p = p->next);		p->next = d;	} else		seq = d;	d->next = NULL;	return seq;}sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len){	sdp_data_t *curr = NULL, *seq = NULL;	int i;	for (i = 0; i < len; i++) {		sdp_data_t *data;		uint8_t dtd = *(uint8_t *)dtds[i];		if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)			data = (sdp_data_t *)values[i];		else			data = sdp_data_alloc(dtd, values[i]);		if (!data)			return NULL;		if (curr)			curr->next = data;		else			seq = data;		curr = data;	}	return sdp_data_alloc(SDP_SEQ8, seq);}int sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d){	sdp_data_t *p = sdp_data_get(rec, attr);	if (p)		return -1;	d->attrId = attr;	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);	return 0;}void sdp_attr_remove(sdp_record_t *rec, uint16_t attr){	sdp_data_t *d = sdp_data_get(rec, attr);	if (d)		rec->attrlist = sdp_list_remove(rec->attrlist, d);}void sdp_set_seq_len(char *ptr, int length){	uint8_t dtd = *(uint8_t *)ptr++;	switch (dtd) {	case SDP_SEQ8:	case SDP_ALT8:	case SDP_TEXT_STR8:	case SDP_URL_STR8:		*(uint8_t *)ptr = (uint8_t)length;		break;	case SDP_SEQ16:	case SDP_ALT16:	case SDP_TEXT_STR16:	case SDP_URL_STR16:		sdp_put_unaligned(htons(length), (uint16_t *)ptr);		break;	case SDP_SEQ32:	case SDP_ALT32:	case SDP_TEXT_STR32:	case SDP_URL_STR32:		sdp_put_unaligned(htons(length), (uint32_t *)ptr);		break;	}}int sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd){	int orig = buf->data_size;	uint8_t *p = buf->data + buf->data_size;	*p++ = dtd;	buf->data_size += sizeof(uint8_t);	switch (dtd) {	case SDP_SEQ8:	case SDP_TEXT_STR8:	case SDP_URL_STR8:	case SDP_ALT8:		buf->data_size += sizeof(uint8_t);		break;	case SDP_SEQ16:	case SDP_TEXT_STR16:	case SDP_URL_STR16:	case SDP_ALT16:		buf->data_size += sizeof(uint16_t);		break;	case SDP_SEQ32:	case SDP_TEXT_STR32:	case SDP_URL_STR32:	case SDP_ALT32:		buf->data_size += sizeof(uint32_t);		break;	}	return buf->data_size - orig;}void sdp_set_attrid(sdp_buf_t *buf, uint16_t attr){	uint8_t *p = buf->data;	// data type for attr	*p++ = SDP_UINT16;	buf->data_size = sizeof(uint8_t);	sdp_put_unaligned(htons(attr), (uint16_t *)p);	p += sizeof(uint16_t);	buf->data_size += sizeof(uint16_t);}static int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata){	sdp_data_t *d;	int n = 0;	for (d = sdpdata->val.dataseq; d; d = d->next)		n += sdp_gen_pdu(buf, d);	return n;}int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d){	int pdu_size = 0, data_size = 0;	unsigned char *src = NULL, is_seq = 0, is_alt = 0;	uint8_t dtd = d->dtd;	uint16_t u16;	uint32_t u32;	uint64_t u64;	uint128_t u128;	char *seqp = buf->data + buf->data_size;	pdu_size = sdp_set_data_type(buf, dtd);	switch (dtd) {	case SDP_DATA_NIL:		break;	case SDP_UINT8:		src = &d->val.uint8;		data_size = sizeof(uint8_t);		break;	case SDP_UINT16:		u16 = htons(d->val.uint16);		src = (unsigned char *)&u16;		data_size = sizeof(uint16_t);		break;	case SDP_UINT32:		u32 = htonl(d->val.uint32);		src = (unsigned char *)&u32;		data_size = sizeof(uint32_t);		break;	case SDP_UINT64:		u64 = hton64(d->val.uint64);		src = (unsigned char *)&u64;		data_size = sizeof(uint64_t);		break;	case SDP_UINT128:		hton128(&d->val.uint128, &u128);		src = (unsigned char *)&u128;		data_size = sizeof(uint128_t);		break;	case SDP_INT8:	case SDP_BOOL:		src = (unsigned char *)&d->val.int8;		data_size = sizeof(int8_t);		break;	case SDP_INT16:		u16 = htons(d->val.int16);		src = (unsigned char *)&u16;		data_size = sizeof(int16_t);		break;	case SDP_INT32:		u32 = htonl(d->val.int32);		src = (unsigned char *)&u32;		data_size = sizeof(int32_t);		break;	case SDP_INT64:		u64 = hton64(d->val.int64);		src = (unsigned char *)&u64;		data_size = sizeof(int64_t);		break;	case SDP_INT128:		hton128(&d->val.int128, &u128);		src = (unsigned char *)&u128;		data_size = sizeof(uint128_t);		break;	case SDP_TEXT_STR8:	case SDP_URL_STR8:	case SDP_TEXT_STR16:	case SDP_TEXT_STR32:	case SDP_URL_STR16:	case SDP_URL_STR32:		src = (unsigned char *)d->val.str;		data_size = strlen(d->val.str);		sdp_set_seq_len(seqp, data_size);		break;	case SDP_SEQ8:	case SDP_SEQ16:	case SDP_SEQ32:		is_seq = 1;		data_size = get_data_size(buf, d);		sdp_set_seq_len(seqp, data_size);		break;	case SDP_ALT8:	case SDP_ALT16:	case SDP_ALT32:		is_alt = 1;		data_size = get_data_size(buf, d);		sdp_set_seq_len(seqp, data_size);		break;	case SDP_UUID16:		u16 = htons(d->val.uuid.value.uuid16);		src = (unsigned char *)&u16;		data_size = sizeof(uint16_t);		break;	case SDP_UUID32:		u32 = htonl(d->val.uuid.value.uuid32);		src = (unsigned char *)&u32;		data_size = sizeof(uint32_t);		break;	case SDP_UUID128:		src = (unsigned char *)&d->val.uuid.value.uuid128;		data_size = sizeof(uint128_t);		break;	default:		break;	}	if (!is_seq && !is_alt) {		if (src && buf) {			memcpy(buf->data + buf->data_size, src, data_size);			buf->data_size += data_size;		} else if (dtd != SDP_DATA_NIL)			SDPDBG("Gen PDU : Cant copy from NULL source or dest\n");	}	pdu_size += data_size;	return pdu_size;}static void sdp_attr_pdu(void *value, void *udata){	sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value);}int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf){	buf->data = (char *)malloc(SDP_PDU_CHUNK_SIZE);	if (buf->data) {		buf->buf_size = SDP_PDU_CHUNK_SIZE;		buf->data_size = 0;		memset(buf->data, 0, buf->buf_size);		sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf);		return 0;	}	return -1;}void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d){	sdp_data_t *p = sdp_data_get(rec, attr);	if (p) {		rec->attrlist = sdp_list_remove(rec->attrlist, p);		sdp_data_free(p);	}	d->attrId = attr;	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, (void *)d, sdp_attrid_comp_func);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -