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

📄 sdp.c

📁 linux下的蓝牙协议栈
💻 C
📖 第 1 页 / 共 5 页
字号:
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);}int sdp_attrid_comp_func(const void *key1, const void *key2){	const sdp_data_t *d1 = (const sdp_data_t *)key1;	const sdp_data_t *d2 = (const sdp_data_t *)key2;	if (d1 && d2)		return d1->attrId - d2->attrId;	return 0;}static void data_seq_free(sdp_data_t *seq){	sdp_data_t *d = seq->val.dataseq;	while (d) {		sdp_data_t *next = d->next;		sdp_data_free(d);		d = next;	}}void sdp_data_free(sdp_data_t *d){	switch (d->dtd) {	case SDP_SEQ8:	case SDP_SEQ16:	case SDP_SEQ32:		data_seq_free(d);		break;	case SDP_URL_STR8:	case SDP_URL_STR16:	case SDP_URL_STR32:	case SDP_TEXT_STR8:	case SDP_TEXT_STR16:	case SDP_TEXT_STR32:		free(d->val.str);		break;	}	free(d);}static sdp_data_t *extract_int(const void *p, int *len){	sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t));	SDPDBG("Extracting integer\n");	memset(d, 0, sizeof(sdp_data_t));	d->dtd = *(uint8_t *)p;	p += sizeof(uint8_t);	*len += sizeof(uint8_t);	switch (d->dtd) {	case SDP_DATA_NIL:		break;	case SDP_BOOL:	case SDP_INT8:	case SDP_UINT8:		*len += sizeof(uint8_t);		d->val.uint8 = *(uint8_t *)p;		break;	case SDP_INT16:	case SDP_UINT16:		*len += sizeof(uint16_t);		d->val.uint16 = ntohs(sdp_get_unaligned((uint16_t *)p));		break;	case SDP_INT32:	case SDP_UINT32:		*len += sizeof(uint32_t);		d->val.uint32 = ntohl(sdp_get_unaligned((uint32_t *)p));		break;	case SDP_INT64:	case SDP_UINT64:		*len += sizeof(uint64_t);		d->val.uint64 = ntoh64(sdp_get_unaligned((uint64_t *)p));		break;	case SDP_INT128:	case SDP_UINT128:		*len += sizeof(uint128_t);		ntoh128((uint128_t *)p, &d->val.uint128);		break;	default:		free(d);		d = NULL;	}	return d;}static sdp_data_t *extract_uuid(const void *p, int *len, sdp_record_t *rec){	sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t));	SDPDBG("Extracting UUID");	memset(d, 0, sizeof(sdp_data_t));	if (0 > sdp_uuid_extract(p, &d->val.uuid, len)) {		free(d);		return NULL;	}	d->dtd = *(uint8_t *)p;	sdp_pattern_add_uuid(rec, &d->val.uuid);	return d;}/* * Extract strings from the PDU (could be service description and similar info)  */static sdp_data_t *extract_str(const void *p, int *len){	char *s;	int n;	sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t));	memset(d, 0, sizeof(sdp_data_t));	d->dtd = *(uint8_t *)p;	p += sizeof(uint8_t);	*len += sizeof(uint8_t);	switch (d->dtd) {	case SDP_TEXT_STR8:	case SDP_URL_STR8:		n = *(uint8_t *)p;		p += sizeof(uint8_t);		*len += sizeof(uint8_t) + n;		break;	case SDP_TEXT_STR16:	case SDP_URL_STR16:		n = ntohs(sdp_get_unaligned((uint16_t *)p));		p += sizeof(uint16_t);		*len += sizeof(uint16_t) + n;		break;	default:		SDPERR("Sizeof text string > UINT16_MAX\n");		free(d);		return 0;	}	s = malloc(n + 1);	memset(s, 0, n + 1);	memcpy(s, p, n);	SDPDBG("Len : %d\n", n);	SDPDBG("Str : %s\n", s);	d->val.str = s;	d->unitSize = n;	return d;}static sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec){	int seqlen, n = 0;	sdp_data_t *curr, *prev;	sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t));	SDPDBG("Extracting SEQ");	memset(d, 0, sizeof(sdp_data_t));	*len = sdp_extract_seqtype(p, &d->dtd, &seqlen);	SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen);	if (*len == 0)		return d;	p += *len;	curr = prev = NULL;	while (n < seqlen) {		int attrlen = 0;		curr = sdp_extract_attr(p, &attrlen, rec);		if (curr == NULL)			break;		if (prev)			prev->next = curr;		else			d->val.dataseq = curr;		prev = curr;		p += attrlen;		n += attrlen;		SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen);	}	*len += n;	return d;}sdp_data_t *sdp_extract_attr(const char *p, int *size, sdp_record_t *rec){	sdp_data_t *elem;	int n = 0;	uint8_t dtd = *(const uint8_t *)p;	SDPDBG("extract_attr: dtd=0x%x", dtd);	switch (dtd) {	case SDP_DATA_NIL:	case SDP_BOOL:	case SDP_UINT8:	case SDP_UINT16:	case SDP_UINT32:	case SDP_UINT64:	case SDP_UINT128:	case SDP_INT8:	case SDP_INT16:	case SDP_INT32:	case SDP_INT64:	case SDP_INT128:		elem = extract_int(p, &n);		break;	case SDP_UUID16:	case SDP_UUID32:	case SDP_UUID128:		elem = extract_uuid(p, &n, rec);		break;	case SDP_TEXT_STR8:	case SDP_TEXT_STR16:	case SDP_TEXT_STR32:	case SDP_URL_STR8:	case SDP_URL_STR16:	case SDP_URL_STR32:		elem = extract_str(p, &n);		break;	case SDP_SEQ8:	case SDP_SEQ16:	case SDP_SEQ32:	case SDP_ALT8:	case SDP_ALT16:	case SDP_ALT32:		elem = extract_seq(p, &n, rec);		break;	default:		SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd);		return NULL;	}	*size += n;	return elem;}#ifdef SDP_DEBUGstatic void attr_print_func(void *value, void *userData){	sdp_data_t *d = (sdp_data_t *)value;	SDPDBG("=====================================\n");	SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x\n",  d->attrId);	SDPDBG("ATTRIBUTE VALUE PTR : 0x%x\n", (uint32_t)value);	if (d)		sdp_data_print(d);	else		SDPDBG("NULL value\n");	SDPDBG("=====================================\n");}void sdp_print_service_attr(sdp_list_t *svcAttrList){	sdp_list_foreach(svcAttrList, attr_print_func, NULL);}#endifsdp_record_t *sdp_extract_pdu(const char *buf, int *scanned){	int extracted = 0, seqlen = 0;	uint8_t dtd;	uint16_t attr;	sdp_record_t *rec = sdp_record_alloc();	const char *p = buf;	*scanned = sdp_extract_seqtype(buf, &dtd, &seqlen);	p += *scanned;	rec->attrlist = NULL;	while (extracted < seqlen) {		int n = sizeof(uint8_t), attrlen = 0;		sdp_data_t *data = NULL;		SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, extracted);		dtd = *(uint8_t *)p;		attr = ntohs(sdp_get_unaligned((uint16_t *)(p+n)));		n += sizeof(uint16_t);		SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr);		data = sdp_extract_attr(p+n, &attrlen, rec);		SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen);		n += attrlen;		if (data == NULL) {			SDPDBG("Terminating extraction of attributes");			break;		}		if (attr == SDP_ATTR_RECORD_HANDLE)			rec->handle = data->val.uint32;		extracted += n;		p += n;		sdp_attr_replace(rec, attr, data);		SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d",					seqlen, extracted);	}#ifdef SDP_DEBUG	SDPDBG("Successful extracting of Svc Rec attributes\n");	sdp_print_service_attr(rec->attrlist);#endif	*scanned += seqlen;	return rec;}#ifdef SDP_DEBUGstatic void print_dataseq(sdp_data_t *p){	sdp_data_t *d;	for (d = p; d; d = d->next)		sdp_data_print(d);}#endifvoid sdp_record_print(const sdp_record_t *rec){	sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);	if (d)		printf("Service Name: %s\n", d->val.str);	d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);	if (d)		printf("Service Description: %s\n", d->val.str);	d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY);	if (d)		printf("Service Provider: %s\n", d->val.str);}#ifdef SDP_DEBUGvoid sdp_data_print(sdp_data_t *d){	switch (d->dtd) {	case SDP_DATA_NIL:		SDPDBG("NIL\n");		break;	case SDP_BOOL:	case SDP_UINT8:	case SDP_UINT16:	case SDP_UINT32:	case SDP_UINT64:	case SDP_UINT128:	case SDP_INT8:	case SDP_INT16:	case SDP_INT32:	case SDP_INT64:	case SDP_INT128:		SDPDBG("Integer : 0x%x\n", d->val.uint32);		break;	case SDP_UUID16:	case SDP_UUID32:	case SDP_UUID128:		SDPDBG("UUID\n");		sdp_uuid_print(&d->val.uuid);		break;	case SDP_TEXT_STR8:	case SDP_TEXT_STR16:	case SDP_TEXT_STR32:		SDPDBG("Text : %s\n", d->val.str);		break;	case SDP_URL_STR8:	case SDP_URL_STR16:	case SDP_URL_STR32:		SDPDBG("URL : %s\n", d->val.str);		break;	case SDP_SEQ8:	case SDP_SEQ16:	case SDP_SEQ32:		print_dataseq(d->val.dataseq);		break;	case SDP_ALT8:	case SDP_ALT16:	case SDP_ALT32:		SDPDBG("Data Sequence Alternates\n");		print_dataseq(d->val.dataseq);		break;	}

⌨️ 快捷键说明

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