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

📄 sdp.c

📁 bluezlib blueztool,bluez
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (SDP_IS_UUID(seq->dtd)) {			uuid = &seq->val.uuid;		} else {			sdp_data_t *puuid = seq->val.dataseq;			sdp_data_t *pVnum = seq->val.dataseq->next;			if (puuid && pVnum) {				uuid = &puuid->val.uuid;				version = pVnum->val.uint16;			}		}		if (uuid != NULL) {			profDesc = malloc(sizeof(sdp_profile_desc_t));			profDesc->uuid = *uuid;			profDesc->version = version;#ifdef SDP_DEBUG			sdp_uuid_print(&profDesc->uuid);			SDPDBG("Vnum : 0x%04x\n", profDesc->version);#endif			*profDescSeq = sdp_list_append(*profDescSeq, profDesc);		}	}	return 0;}int sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16){	sdp_data_t *d, *curr;	*u16 = NULL;	d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST);	if (d == NULL) {		errno = ENODATA;		return -1;	}	for (curr = d->val.dataseq; curr; curr = curr->next)		*u16 = sdp_list_append(*u16, &curr->val.uint16);	return 0;}/* flexible extraction of basic attributes - Jean II *//* How do we expect caller to extract predefined data sequences? */int sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value){	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);	if (sdpdata)		/* Verify that it is what the caller expects */		if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 ||		sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 ||		sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 ||		sdpdata->dtd == SDP_INT32) {			*value = sdpdata->val.uint32;			return 0;		}	errno = EINVAL;	return -1;}int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value, int valuelen){	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);	if (sdpdata)		/* Verify that it is what the caller expects */		if (sdpdata->dtd == SDP_TEXT_STR8 || sdpdata->dtd == SDP_TEXT_STR16 || sdpdata->dtd == SDP_TEXT_STR32)			if (strlen(sdpdata->val.str) < valuelen) {				strcpy(value, sdpdata->val.str);				return 0;			}	errno = EINVAL;	return -1;}#define get_basic_attr(attrID, pAttrValue, fieldName)		\	sdp_data_t *data = sdp_data_get(rec, attrID);		\	if (data) {						\		*pAttrValue = data->val.fieldName;		\		return 0;					\	}							\	errno = EINVAL;						\	return -1;int sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid){	get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid);}int sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid){	get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid);}int sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState){	get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32);}int sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail){	get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8);}int sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo){	get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32);}int sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState){	get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32);}/* * NOTE that none of the setXXX() functions below will * actually update the SDP server, unless the * {register, update}sdp_record_t() function is invoked. */int sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd, const void *value){	sdp_data_t *d = sdp_data_alloc(dtd, value);	if (d) {		sdp_attr_replace(rec, attr, d);		return 0;	}	return -1;}/* * Set the information attributes of the service * pointed to by rec. The attributes are * service name, description and provider name */void sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov, const char *desc){	if (name)		sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY, SDP_TEXT_STR8, (void *)name);	if (prov)		sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY, SDP_TEXT_STR8, (void *)prov);	if (desc)		sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY, SDP_TEXT_STR8, (void *)desc);}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;}/* * sets the access protocols of the service specified * to the value specified in "access_proto" * * Note that if there are alternate mechanisms by  * which the service is accessed, then they should  * be specified as sequences  * * Using a value of NULL for accessProtocols has * effect of removing this attribute (if previously set) *  * This function replaces the existing sdp_access_proto_t * structure (if any) with the new one specified. * * returns 0 if successful or -1 if there is a failure. */int sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap){	const sdp_list_t *p;	sdp_data_t *protos = NULL;	for (p = ap; p; p = p->next) {		sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data);		protos = sdp_seq_append(protos, seq);	}	sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos);	return 0;}int sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap){	const sdp_list_t *p;	sdp_data_t *protos = NULL;	for (p = ap; p; p = p->next) {		sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data);		protos = sdp_seq_append(protos, seq);	}	sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST,			protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL);	return 0;}/* * set the "LanguageBase" attributes of the service record * record to the value specified in "langAttrList". * * "langAttrList" is a linked list of "sdp_lang_attr_t" * objects, one for each language in which user visible * attributes are present in the service record. * * Using a value of NULL for langAttrList has * effect of removing this attribute (if previously set) *  * This function replaces the exisiting sdp_lang_attr_t * structure (if any) with the new one specified. * * returns 0 if successful or -1 if there is a failure. */int sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq){	uint8_t uint16 = SDP_UINT16;	int status = 0, i = 0, seqlen = sdp_list_len(seq);	void **dtds = (void **)malloc(3 * seqlen * sizeof(void *));	void **values = (void **)malloc(3 * seqlen * sizeof(void *));	const sdp_list_t *p;	for (p = seq; p; p = p->next) {		sdp_lang_attr_t *lang = (sdp_lang_attr_t *)p->data;		if (!lang) {			status = -1;			break;		}		dtds[i] = &uint16;		values[i] = &lang->code_ISO639;		i++;		dtds[i] = &uint16;		values[i] = &lang->encoding;		i++;		dtds[i] = &uint16;		values[i] = &lang->base_offset;		i++;	}	if (status == 0) {		sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen);		sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq);	}	free(dtds);	free(values);	return status;}/* * set the "ServiceID" attribute of the service.  *  * This is the UUID of the service.  *  * returns 0 if successful or -1 if there is a failure. */void sdp_set_service_id(sdp_record_t *rec, uuid_t uuid){	switch (uuid.type) {	case SDP_UUID16:		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16, &uuid.value.uuid16);		break;	case SDP_UUID32:		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32, &uuid.value.uuid32);		break;	case SDP_UUID128:		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128, &uuid.value.uuid128);		break;	}	sdp_pattern_add_uuid(rec, &uuid);}/* * set the GroupID attribute of the service record defining a group.  *  * This is the UUID of the group.  *  * returns 0 if successful or -1 if there is a failure. */void sdp_set_group_id(sdp_record_t *rec, uuid_t uuid){	switch (uuid.type) {	case SDP_UUID16:		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16, &uuid.value.uuid16);		break;	case SDP_UUID32:		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32, &uuid.value.uuid32);		break;	case SDP_UUID128:		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128, &uuid.value.uuid128);		break;	}	sdp_pattern_add_uuid(rec, &uuid);}/* * set the ProfileDescriptorList attribute of the service record * pointed to by record to the value specified in "profileDesc". * * Each element in the list is an object of type * sdp_profile_desc_t which is a definition of the * Bluetooth profile that this service conforms to. * * Using a value of NULL for profileDesc has * effect of removing this attribute (if previously set) *  * This function replaces the exisiting ProfileDescriptorList * structure (if any) with the new one specified. * * returns 0 if successful or -1 if there is a failure. */int sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles){	int status = 0;	uint8_t uuid16 = SDP_UUID16;	uint8_t uuid32 = SDP_UUID32;	uint8_t uuid128 = SDP_UUID128;	uint8_t uint16 = SDP_UINT16;	int i = 0, seqlen = sdp_list_len(profiles);	void **seqDTDs = (void **)malloc(seqlen * sizeof(void *));	void **seqs = (void **)malloc(seqlen * sizeof(void *));	const sdp_list_t *p;	for (p = profiles; p; p = p->next) {		sdp_data_t *seq;		void *dtds[2], *values[2];		sdp_profile_desc_t *profile = (sdp_profile_desc_t *)p->data;		if (!profile) {			status = -1;			break;		}		switch (profile->uuid.type) {		case SDP_UUID16:			dtds[0] = &uuid16;			values[0] = &profile->uuid.value.uuid16;			break;		case SDP_UUID32:			dtds[0] = &uuid32;			values[0] = &profile->uuid.value.uuid32;			break;		case SDP_UUID128:			dtds[0] = &uuid128;			values[0] = &profile->uuid.value.uuid128;			break;		default:			status = -1;			break;		}		dtds[1] = &uint16;		values[1] = &profile->version;		seq = sdp_seq_alloc(dtds, values, 2);		if (seq) {			seqDTDs[i] = &seq->dtd;			seqs[i] = seq;			sdp_pattern_add_uuid(rec, &profile->uuid);		}		i++;	}	if (status == 0) {		sdp_data_t *pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen);		sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq);	}	free(seqDTDs);	free(seqs);	return status;}/* * sets various URL attributes of the service * pointed to by record. The URL include * * client: a URL to the client's *   platform specific (WinCE, PalmOS) executable *   code that can be used to access this service. * * doc: a URL pointing to service documentation * * icon: a URL to an icon that can be used to represent *   this service. * * Note that you need to pass NULL for any URLs * that you don't want to set or remove */void sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc, const char *icon){	sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client);	sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc);	sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon);}/* * 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){	uint128_t *base_uuid;	char baseStr[128];	int delim = '-';	unsigned long dataLongValue;	char *delimPtr;	char *dataPtr;	char temp[10];	int toBeCopied;	uint8_t *data;	strcpy(baseStr, BASE_UUID);	base_uuid = malloc(sizeof(uint128_t));	if (!base_uuid)		return NULL;	data = 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);		free(base_uuid);		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);		free(base_uuid);		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);		free(base_uuid);		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);		free(base_uuid);		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 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));

⌨️ 快捷键说明

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