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

📄 uuid.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.*//* * $Id: uuid.c,v 1.24 2003/03/31 15:28:37 jscrane Exp $ *//*   Fixes:	Guruprasad Krishnamurthy <guruprasad.krishnamurthy@nokia.com>	Manel Guerrero Zapata <manel.guerrero-zapata@nokia.com>*/#include <stdio.h>#include <stdlib.h>#include "sdp.h"#include "sdp_lib.h"#include "sdp_internal.h"#define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB"static uint128_t *bluetooth_base_uuid = NULL;/* Message structure. */struct tupla {	int index;	char *str;};static struct tupla Protocol[] = {	{ SDP_UUID,     "SDP"     },	{ RFCOMM_UUID,  "RFCOMM"  },	{ TCS_BIN_UUID, "TCS-BIN" },	{ L2CAP_UUID,   "L2CAP"   },	{ IP_UUID,      "IP"      },	{ UDP_UUID,     "UDP"     },	{ TCP_UUID,     "TCP"     },	{ TCS_AT_UUID,  "TCS-AT"  },	{ OBEX_UUID,    "OBEX"    },	{ FTP_UUID,     "FTP"     },	{ HTTP_UUID,    "HTTP"    },	{ WSP_UUID,     "WSP"     },	{ BNEP_UUID,    "BNEP"    },	{ 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,	        "IrMCSync" },	{ OBEX_OBJPUSH_SVCLASS_ID,      "OBEX Object Push" },	{ OBEX_FILETRANS_SVCLASS_ID,    "OBEX File Transfer" },	{ IRMC_SYNC_CMD_SVCLASS_ID,     "IrMCSync Command" },	{ HEADSET_SVCLASS_ID,           "Headset" },	{ CORDLESS_TELEPHONY_SVCLASS_ID,"Cordless Telephony" },	{ INTERCOM_SVCLASS_ID,          "Intercom" },	{ FAX_SVCLASS_ID,               "Fax" },	{ HEADSET_AGW_SVCLASS_ID,       "Headset Audio Gateway" },	{ 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" },	{ PANU_SVCLASS_ID,              "PAN user" },	{ NAP_SVCLASS_ID,               "Network access point" },	{ GN_SVCLASS_ID,                "PAN group network" },	{ 0 }};static struct tupla Profile[] = {	{ SERIAL_PORT_PROFILE_ID,        "Serial Port" },	{ LAN_ACCESS_PROFILE_ID,         "LAN Access Using PPP" },	{ DIALUP_NET_PROFILE_ID,         "Dialup Networking" },	{ IRMC_SYNC_PROFILE_ID,          "IrMCSync" },	{ OBEX_OBJPUSH_PROFILE_ID,       "OBEX Object Push" },	{ OBEX_FILETRANS_PROFILE_ID,     "OBEX File Transfer" },	{ IRMC_SYNC_CMD_PROFILE_ID,      "IrMCSync Command" },	{ HEADSET_PROFILE_ID,            "Headset" },	{ CORDLESS_TELEPHONY_PROFILE_ID, "Cordless Telephony" },	{ INTERCOM_PROFILE_ID,           "Intercom" },	{ FAX_PROFILE_ID,                "Fax" },	{ HEADSET_AGW_PROFILE_ID,        "Headset Audio Gateway" },	{ PANU_PROFILE_ID,               "PAN user" },	{ NAP_PROFILE_ID,                "PAN access point" },	{ GN_PROFILE_ID,                 "PAN group network" },	{ 0 }};static 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:		snprintf(str, n, "Error: This is uuid32");		return -3;	case SDP_UUID128:		snprintf(str, n, "Error: This is uuid128");		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");}#endif/* * The code in this function is executed only once per * thread. We compute the actual bit value of the Bluetooth * base UUID which is a string defined in bt_std_values.h  * and is assumed to be of the standard form with "-" separators. * * The algorithm however converts the string to 4 unsigned longs * using the strtoul() and assigns the values in sequence to * the 128bit value */uint128_t *sdp_create_base_uuid(void){	char baseStr[128];	int delim = '-';	unsigned long dataLongValue;	char *delimPtr;	char *dataPtr;	char temp[10];	int toBeCopied;	char *data;	if (bluetooth_base_uuid == NULL) {		strcpy(baseStr, BASE_UUID);		bluetooth_base_uuid = (uint128_t *)malloc(sizeof(uint128_t));		data = bluetooth_base_uuid->data;		memset(data, '\0', sizeof(uint128_t));		memset(temp, '\0', 10);		dataPtr = baseStr;		delimPtr = NULL;		delimPtr = strchr(dataPtr, delim);		toBeCopied = delimPtr - dataPtr;		if (toBeCopied != 8) {			SDPDBG("To be copied(1) : %d\n", toBeCopied);			return NULL;		}		strncpy(temp, dataPtr, toBeCopied);		dataLongValue = htonl(strtoul(temp, NULL, 16));		memcpy(&data[0], &dataLongValue, 4);		/*		 * Get the next 4 bytes (note that there is a "-"		 * between them now)		 */		memset(temp, '\0', 10);		dataPtr = delimPtr + 1;		delimPtr = strchr(dataPtr, delim);		toBeCopied = delimPtr - dataPtr;		if (toBeCopied != 4) {			SDPDBG("To be copied(2) : %d\n", toBeCopied);			return NULL;		}		strncpy(temp, dataPtr, toBeCopied);		dataPtr = delimPtr + 1;		delimPtr = strchr(dataPtr, delim);		toBeCopied = delimPtr - dataPtr;		if (toBeCopied != 4) {			SDPDBG("To be copied(3) : %d\n", toBeCopied);			return NULL;		}		strncat(temp, dataPtr, toBeCopied);		dataLongValue = htonl(strtoul(temp, NULL, 16));		memcpy(&data[4], &dataLongValue, 4);		/*		 * Get the last 4 bytes (note that there are 6 bytes		 * after the last separator, which is truncated (2+4)		 */		memset(temp, '\0', 10);		dataPtr = delimPtr + 1;		dataPtr = delimPtr + 1;		delimPtr = strchr(dataPtr, delim);		toBeCopied = delimPtr - dataPtr;		if (toBeCopied != 4) {			SDPDBG("To be copied(4) : %d\n", toBeCopied);			return NULL;		}		strncpy(temp, dataPtr, toBeCopied);		strncat(temp, (delimPtr + 1), 4);		dataLongValue = htonl(strtoul(temp, NULL, 16));		memcpy(&data[8], &dataLongValue, 4);		dataLongValue = htonl(strtoul(delimPtr + 5, NULL, 16));		memcpy(&data[12], &dataLongValue, 4);	}	return bluetooth_base_uuid;}uuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val){	memset(u, 0, sizeof(uuid_t));	u->type = SDP_UUID16;	u->value.uuid16 = val;	return u;}uuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val){	memset(u, 0, sizeof(uuid_t));	u->type = SDP_UUID32;	u->value.uuid32 = val;	return u;}uuid_t *sdp_uuid128_create(uuid_t *u, const void *val){ 	memset(u, 0, sizeof(uuid_t));	u->type = SDP_UUID128;	memcpy(&u->value.uuid128, val, sizeof(uint128_t));	return u;}/* * UUID comparison function * returns 0 if uuidValue1 == uuidValue2 else -1 */int sdp_uuid_cmp(const void *p1, const void *p2){	const uuid_t *u1 = (const uuid_t *)p1;	const uuid_t *u2 = (const uuid_t *)p2;	return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t));}/* * 128 to 16 bit and 32 to 16 bit UUID conversion functions * yet to be implemented. Note that the input is in NBO in * both 32 and 128 bit UUIDs and conversion is needed */void sdp_uuid16_to_uuid128(uuid_t *uuid128, uuid_t *uuid16){	/*	 * We have a 16 bit value, which needs to be added to	 * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base	 */	unsigned short data1;	// allocate a 128bit UUID and init to the Bluetooth base UUID	uint128_t *pBTBase128Bit = sdp_create_base_uuid();	uuid128->value.uuid128 = *pBTBase128Bit;	uuid128->type = SDP_UUID128;	// extract bytes 2 and 3 of 128bit BT base UUID	memcpy(&data1, &pBTBase128Bit->data[2], 2);	// add the given UUID (16 bits)	data1 += htons(uuid16->value.uuid16);	// set bytes 2 and 3 of the 128 bit value	memcpy(&uuid128->value.uuid128.data[2], &data1, 2);}void sdp_uuid32_to_uuid128(uuid_t *uuid128, uuid_t *uuid32){	/*	 * We have a 32 bit value, which needs to be added to	 * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base	 */	unsigned int data0;	// allocate a 128bit UUID and init to the Bluetooth base UUID	uint128_t *pBTBase128Bit = sdp_create_base_uuid();	uuid128->value.uuid128 = *pBTBase128Bit;	uuid128->type = SDP_UUID128;	// extract first 4 bytes	memcpy(&data0, &pBTBase128Bit->data[0], 4);	// add the given UUID (32bits)	data0 += htonl(uuid32->value.uuid32);	// set the 4 bytes of the 128 bit value	memcpy(&uuid128->value.uuid128.data[0], &data0, 4);}uuid_t *sdp_uuid_to_uuid128(uuid_t *uuid){	uuid_t *uuid128 = (uuid_t *)malloc(sizeof(uuid_t));	memset(uuid128, 0, sizeof(uuid_t));	switch (uuid->type) {	case SDP_UUID128:		*uuid128 = *uuid;		break;	case SDP_UUID32:		sdp_uuid32_to_uuid128(uuid128, uuid);		break;	case SDP_UUID16:		sdp_uuid16_to_uuid128(uuid128, uuid);		break;	}	return uuid128;}/*  * converts a 128-bit uuid to a 16/32-bit one if possible * returns true if uuid contains a 16/32-bit UUID at exit */int sdp_uuid128_to_uuid(uuid_t *uuid){	extern uint128_t *sdp_create_base_uuid();	int i;	uint128_t *b = sdp_create_base_uuid();	uint128_t *u = &uuid->value.uuid128;	uint32_t data;		if (uuid->type != SDP_UUID128)		return 1;		for (i = 4; i < sizeof(b->data); i++)		if (b->data[i] != u->data[i])			return 0;		memcpy(&data, u->data, 4);	data = htonl(data);	if (data <= 0xffff) {		uuid->type = SDP_UUID16;		uuid->value.uuid16 = (uint16_t)data;	} else {		uuid->type = SDP_UUID32;		uuid->value.uuid32 = data;	}	return 1;}/* * convert a UUID to the 16-bit short-form */int sdp_uuid_to_proto(uuid_t *uuid){	uuid_t u = *uuid;	if (sdp_uuid128_to_uuid(&u) && u.type == SDP_UUID16)		return u.value.uuid16;	return 0;}int sdp_uuid_extract(const char *p, uuid_t *uuid, int *scanned){	uint8_t type = *(const uint8_t *)p;	if (!SDP_IS_UUID(type)) {		SDPERR("Unknown data type : %d expecting a svc UUID\n", type);		return -1;	}	p += sizeof(uint8_t);	*scanned += sizeof(uint8_t);	if (type == SDP_UUID16) {		sdp_uuid16_create(uuid, ntohs(sdp_get_unaligned((uint16_t *)p)));		*scanned += sizeof(uint16_t);		p += sizeof(uint16_t);	} else if (type == SDP_UUID32) {		sdp_uuid32_create(uuid, ntohl(sdp_get_unaligned((uint32_t *)p)));		*scanned += sizeof(uint32_t);		p += sizeof(uint32_t);	} else {		sdp_uuid128_create(uuid, p);		*scanned += sizeof(uint128_t);		p += sizeof(uint128_t);	}	return 0;}

⌨️ 快捷键说明

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