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

📄 sdp.c

📁 bluez is the standed offical bluetooth stack with all lib source under linux.
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2001-2002  Nokia Corporation *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> *  Copyright (C) 2002-2005  Marcel Holtmann <marcel@holtmann.org> *  Copyright (C) 2002-2003  Stephen Crane <steve.crane@rococosoft.com> * * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA * */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <errno.h>#include <unistd.h>#include <stdlib.h>#include <malloc.h>#include <syslog.h>#include <sys/un.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/types.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#include <bluetooth/l2cap.h>#include <bluetooth/sdp.h>#include <bluetooth/sdp_lib.h>#include <netinet/in.h>#define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg)#define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg)#ifdef SDP_DEBUG#define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg)#else#define SDPDBG(fmt...)#endif#if __BYTE_ORDER == __BIG_ENDIAN#define ntoh64(x) (x)static inline void ntoh128(uint128_t *src, uint128_t *dst){	int i;	for (i = 0; i < 16; i++)		dst->data[i] = src->data[i];}#elsestatic inline uint64_t ntoh64(uint64_t n){	uint64_t h;	uint64_t tmp = ntohl(n & 0x00000000ffffffff);	h = ntohl(n >> 32);	h |= tmp << 32;	return h;}static inline void ntoh128(uint128_t *src, uint128_t *dst){	int i;	for (i = 0; i < 16; i++)		dst->data[15 - i] = src->data[i];}#endif#define hton64(x)     ntoh64(x)#define hton128(x, y) ntoh128(x, y)#define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB"static uint128_t *bluetooth_base_uuid = NULL;#define SDP_BASIC_ATTR_PDUFORM_SIZE 32#define SDP_SEQ_PDUFORM_SIZE 128#define SDP_UUID_SEQ_SIZE 256#define SDP_MAX_ATTR_LEN 65535/* Message structure. */struct tupla {	int index;	char *str;};static struct tupla Protocol[] = {	{ SDP_UUID,		"SDP"		},	{ UDP_UUID,		"UDP"		},	{ RFCOMM_UUID,		"RFCOMM"	},	{ TCP_UUID,		"TCP"		},	{ TCS_BIN_UUID,		"TCS-BIN"	},	{ TCS_AT_UUID,		"TCS-AT"	},	{ OBEX_UUID,		"OBEX"		},	{ IP_UUID,		"IP"		},	{ FTP_UUID,		"FTP"		},	{ HTTP_UUID,		"HTTP"		},	{ WSP_UUID,		"WSP"		},	{ BNEP_UUID,		"BNEP"		},	{ UPNP_UUID,		"UPNP"		},	{ HIDP_UUID,		"HIDP"		},	{ HCRP_CTRL_UUID,	"HCRP-Ctrl"	},	{ HCRP_DATA_UUID,	"HCRP-Data"	},	{ HCRP_NOTE_UUID,	"HCRP-Notify"	},	{ AVCTP_UUID,		"AVCTP"		},	{ AVDTP_UUID,		"AVDTP"		},	{ CMTP_UUID,		"CMTP"		},	{ UDI_UUID,		"UDI"		},	{ L2CAP_UUID,		"L2CAP"		},	{ 0 }};static struct tupla ServiceClass[] = {	{ SDP_SERVER_SVCLASS_ID,		"SDP Server"			},	{ BROWSE_GRP_DESC_SVCLASS_ID,		"Browse Group Descriptor"	},	{ PUBLIC_BROWSE_GROUP,			"Public Browse Group"		},	{ SERIAL_PORT_SVCLASS_ID,		"Serial Port"			},	{ LAN_ACCESS_SVCLASS_ID,		"LAN Access Using PPP"		},	{ DIALUP_NET_SVCLASS_ID,		"Dialup Networking"		},	{ IRMC_SYNC_SVCLASS_ID,			"IrMC Sync"			},	{ OBEX_OBJPUSH_SVCLASS_ID,		"OBEX Object Push"		},	{ OBEX_FILETRANS_SVCLASS_ID,		"OBEX File Transfer"		},	{ IRMC_SYNC_CMD_SVCLASS_ID,		"IrMC Sync Command"		},	{ HEADSET_SVCLASS_ID,			"Headset"			},	{ CORDLESS_TELEPHONY_SVCLASS_ID,	"Cordless Telephony"		},	{ AUDIO_SOURCE_SVCLASS_ID,		"Audio Source"			},	{ AUDIO_SINK_SVCLASS_ID,		"Audio Sink"			},	{ AV_REMOTE_TARGET_SVCLASS_ID,		"AV Remote Target"		},	{ ADVANCED_AUDIO_SVCLASS_ID,		"Advanced Audio"		},	{ AV_REMOTE_SVCLASS_ID,			"AV Remote"			},	{ VIDEO_CONF_SVCLASS_ID,		"Video Conferencing"		},	{ INTERCOM_SVCLASS_ID,			"Intercom"			},	{ FAX_SVCLASS_ID,			"Fax"				},	{ HEADSET_AGW_SVCLASS_ID,		"Headset Audio Gateway"		},	{ WAP_SVCLASS_ID,			"WAP"				},	{ WAP_CLIENT_SVCLASS_ID,		"WAP Client"			},	{ PANU_SVCLASS_ID,			"PAN User"			},	{ NAP_SVCLASS_ID,			"Network Access Point"		},	{ GN_SVCLASS_ID,			"PAN Group Network"		},	{ DIRECT_PRINTING_SVCLASS_ID,		"Direct Printing"		},	{ REFERENCE_PRINTING_SVCLASS_ID,	"Reference Printing"		},	{ IMAGING_SVCLASS_ID,			"Imaging"			},	{ IMAGING_RESPONDER_SVCLASS_ID,		"Imaging Responder"		},	{ IMAGING_ARCHIVE_SVCLASS_ID,		"Imaging Automatic Archive"	},	{ IMAGING_REFOBJS_SVCLASS_ID,		"Imaging Referenced Objects"	},	{ HANDSFREE_SVCLASS_ID,			"Handsfree"			},	{ HANDSFREE_AGW_SVCLASS_ID,		"Handfree Audio Gateway"	},	{ DIRECT_PRT_REFOBJS_SVCLASS_ID,	"Direct Printing Ref. Objects"	},	{ REFLECTED_UI_SVCLASS_ID,		"Reflected UI"			},	{ BASIC_PRINTING_SVCLASS_ID,		"Basic Printing"		},	{ PRINTING_STATUS_SVCLASS_ID,		"Printing Status"		},	{ HID_SVCLASS_ID,			"Human Interface Device"	},	{ HCR_SVCLASS_ID,			"Hardcopy Cable Replacement"	},	{ HCR_PRINT_SVCLASS_ID,			"HCR Print"			},	{ HCR_SCAN_SVCLASS_ID,			"HCR Scan"			},	{ CIP_SVCLASS_ID,			"Common ISDN Access"		},	{ VIDEO_CONF_GW_SVCLASS_ID,		"Video Conferencing Gateway"	},	{ UDI_MT_SVCLASS_ID,			"UDI MT"			},	{ UDI_TA_SVCLASS_ID,			"UDI TA"			},	{ AV_SVCLASS_ID,			"Audio/Video"			},	{ SAP_SVCLASS_ID,			"SIM Access"			},	{ PBAP_PCE_SVCLASS_ID,			"Phonebook Access - PCE"	},	{ PBAP_PSE_SVCLASS_ID,			"Phonebook Access - PSE"	},	{ PNP_INFO_SVCLASS_ID,			"PnP Information"		},	{ GENERIC_NETWORKING_SVCLASS_ID,	"Generic Networking"		},	{ GENERIC_FILETRANS_SVCLASS_ID,		"Generic File Transfer"		},	{ GENERIC_AUDIO_SVCLASS_ID,		"Generic Audio"			},	{ GENERIC_TELEPHONY_SVCLASS_ID,		"Generic Telephony"		},	{ UPNP_SVCLASS_ID,			"UPnP"				},	{ UPNP_IP_SVCLASS_ID,			"UPnP IP"			},	{ UPNP_PAN_SVCLASS_ID,			"UPnP PAN"			},	{ UPNP_LAP_SVCLASS_ID,			"UPnP LAP"			},	{ UPNP_L2CAP_SVCLASS_ID,		"UPnP L2CAP"			},	{ VIDEO_SOURCE_SVCLASS_ID,		"Video Source"			},	{ VIDEO_SINK_SVCLASS_ID,		"Video Sink"			},	{ VIDEO_DISTRIBUTION_SVCLASS_ID,	"Video Distribution"		},	{ 0 }};#define Profile ServiceClassstatic char *string_lookup(struct tupla *pt0, int index){	struct tupla *pt;	for (pt = pt0; pt->index; pt++)		if (pt->index == index)			return pt->str;	return "";}/* * Prints into a string the Protocol UUID * coping a maximum of n characters. */static int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t n) {	char *str2;	if (!uuid) {		snprintf(str, n, "NULL");		return -2;	}	switch (uuid->type) {	case SDP_UUID16:		str2 = string_lookup(message, uuid->value.uuid16);		snprintf(str, n, str2);		break;	case SDP_UUID32:		str2 = string_lookup(message, uuid->value.uuid32);		snprintf(str, n, str2);		break;	case SDP_UUID128:		snprintf(str, n, "Error: This is UUID-128");		return -4;	default:		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);		return -1;	}	return 0;}int sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n){	return uuid2str(Protocol, uuid, str, n);}int sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n){	return uuid2str(ServiceClass, uuid, str, n);}int sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n){	return uuid2str(Profile, uuid, str, n);}/* * convert the UUID to string, copying a maximum of n characters. */int sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n){	if (!uuid) {		snprintf(str, n, "NULL");		return -2;	}	switch (uuid->type) {	case SDP_UUID16:		snprintf(str, n, "%.4x", uuid->value.uuid16);		break;	case SDP_UUID32:		snprintf(str, n, "%.8x", uuid->value.uuid32);		break;	case SDP_UUID128:{		unsigned int   data0;		unsigned short data1;		unsigned short data2;		unsigned short data3;		unsigned int   data4;		unsigned short data5;		memcpy(&data0, &uuid->value.uuid128.data[0], 4);		memcpy(&data1, &uuid->value.uuid128.data[4], 2);		memcpy(&data2, &uuid->value.uuid128.data[6], 2);		memcpy(&data3, &uuid->value.uuid128.data[8], 2);		memcpy(&data4, &uuid->value.uuid128.data[10], 4);		memcpy(&data5, &uuid->value.uuid128.data[14], 2);		snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x", 				ntohl(data0), ntohs(data1), 				ntohs(data2), ntohs(data3), 				ntohl(data4), ntohs(data5));		}		break;	default:		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);		return -1;	// Enum type of UUID not set	}	return 0;}#ifdef SDP_DEBUG/* * Function prints the UUID in hex as per defined syntax - * * 4bytes-2bytes-2bytes-2bytes-6bytes * * There is some ugly code, including hardcoding, but * that is just the way it is converting 16 and 32 bit * UUIDs to 128 bit as defined in the SDP doc */void sdp_uuid_print(const uuid_t *uuid){	if (uuid == NULL) {		SDPERR("Null passed to print UUID\n");		return;	}	if (uuid->type == SDP_UUID16) {		SDPDBG("  uint16_t : 0x%.4x\n", uuid->value.uuid16);	} else if (uuid->type == SDP_UUID32) {		SDPDBG("  uint32_t : 0x%.8x\n", uuid->value.uuid32);	} else if (uuid->type == SDP_UUID128) {		unsigned int data0;		unsigned short data1;		unsigned short data2;		unsigned short data3;		unsigned int data4;		unsigned short data5;		memcpy(&data0, &uuid->value.uuid128.data[0], 4);		memcpy(&data1, &uuid->value.uuid128.data[4], 2);		memcpy(&data2, &uuid->value.uuid128.data[6], 2);		memcpy(&data3, &uuid->value.uuid128.data[8], 2);		memcpy(&data4, &uuid->value.uuid128.data[10], 4);		memcpy(&data5, &uuid->value.uuid128.data[14], 2);		SDPDBG("  uint128_t : 0x%.8x-", ntohl(data0));		SDPDBG("%.4x-", ntohs(data1));		SDPDBG("%.4x-", ntohs(data2));		SDPDBG("%.4x-", ntohs(data3));		SDPDBG("%.8x", ntohl(data4));		SDPDBG("%.4x\n", ntohs(data5));	} else		SDPERR("Enum type of UUID not set\n");}#endifsdp_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 = bt_get_unaligned((uint16_t *) value);		d->unitSize += sizeof(uint16_t);		break;	case SDP_INT16:		d->val.int16 = bt_get_unaligned((int16_t *) value);		d->unitSize += sizeof(int16_t);		break;	case SDP_UINT32:		d->val.uint32 = bt_get_unaligned((uint32_t *) value);		d->unitSize += sizeof(uint32_t);		break;	case SDP_INT32:		d->val.int32 = bt_get_unaligned((int32_t *) value);		d->unitSize += sizeof(int32_t);		break;	case SDP_INT64:		d->val.int64 = bt_get_unaligned((int64_t *) value);		d->unitSize += sizeof(int64_t);		break;	case SDP_UINT64:		d->val.uint64 = bt_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, bt_get_unaligned((uint16_t *) value));		d->unitSize += sizeof(uint16_t);		break;	case SDP_UUID32:		sdp_uuid32_create(&d->val.uuid, bt_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)

⌨️ 快捷键说明

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