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

📄 sdpd-service.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	sdp_attr_add(record, SDP_ATTR_RECORD_HANDLE, sdp_data);	sdp_uuid16_create(&class_uuid, PNP_INFO_SVCLASS_ID);	class_list = sdp_list_append(0, &class_uuid);	sdp_set_service_classes(record, class_list);	sdp_list_free(class_list, NULL);	sdp_uuid16_create(&group_uuid, PUBLIC_BROWSE_GROUP);	group_list = sdp_list_append(NULL, &group_uuid);	sdp_set_browse_groups(record, group_list);	sdp_list_free(group_list, NULL);	sdp_uuid16_create(&profile.uuid, PNP_INFO_PROFILE_ID);	profile.version = spec;	profile_list = sdp_list_append(NULL, &profile);	sdp_set_profile_descs(record, profile_list);	sdp_list_free(profile_list, NULL);	spec_data = sdp_data_alloc(SDP_UINT16, &spec);	sdp_attr_add(record, 0x0200, spec_data);	vendor_data = sdp_data_alloc(SDP_UINT16, &vendor);	sdp_attr_add(record, 0x0201, vendor_data);	product_data = sdp_data_alloc(SDP_UINT16, &product);	sdp_attr_add(record, 0x0202, product_data);	version_data = sdp_data_alloc(SDP_UINT16, &version);	sdp_attr_add(record, 0x0203, version_data);	primary_data = sdp_data_alloc(SDP_BOOL, &primary);	sdp_attr_add(record, 0x0204, primary_data);	source_data = sdp_data_alloc(SDP_UINT16, &source);	sdp_attr_add(record, 0x0205, source_data);	update_db_timestamp();	update_svclass_list();}int add_record_to_server(bdaddr_t *src, sdp_record_t *rec){	sdp_data_t *data;	if (rec->handle == 0xffffffff) {		rec->handle = sdp_next_handle();		if (rec->handle < 0x10000)			return -1;	} else {		if (sdp_record_find(rec->handle))			return -1; 	}	debug("Adding record with handle 0x%05x", rec->handle);	sdp_record_add(src, rec);	data = sdp_data_alloc(SDP_UINT32, &rec->handle);	sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);	if (sdp_data_get(rec, SDP_ATTR_BROWSE_GRP_LIST) == NULL) {		uuid_t uuid;		sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP);		sdp_pattern_add_uuid(rec, &uuid);	}	update_db_timestamp();	update_svclass_list();	return 0;}int remove_record_from_server(uint32_t handle){	sdp_record_t *rec;	debug("Removing record with handle 0x%05x", handle);	rec = sdp_record_find(handle);	if (!rec)		return -ENOENT;	if (sdp_record_remove(handle) == 0) {		update_db_timestamp();		update_svclass_list();	}	sdp_record_free(rec);	return 0;}// FIXME: refactor for server-sidestatic sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, int bufsize, uint32_t handleExpected, int *scanned){	int extractStatus = -1, localExtractedLength = 0;	uint8_t dtd;	int seqlen = 0;	sdp_record_t *rec = NULL;	uint16_t attrId, lookAheadAttrId;	sdp_data_t *pAttr = NULL;	uint32_t handle = 0xffffffff;	*scanned = sdp_extract_seqtype(p, bufsize, &dtd, &seqlen);	p += *scanned;	bufsize -= *scanned;	if (bufsize < sizeof(uint8_t) + sizeof(uint8_t)) {		debug("Unexpected end of packet");		return NULL;	}	lookAheadAttrId = ntohs(bt_get_unaligned((uint16_t *) (p + sizeof(uint8_t))));	debug("Look ahead attr id : %d", lookAheadAttrId);	if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) {		if (bufsize < (sizeof(uint8_t) * 2) + sizeof(uint16_t) + sizeof(uint32_t)) {			debug("Unexpected end of packet");			return NULL;		}		handle = ntohl(bt_get_unaligned((uint32_t *) (p +				sizeof(uint8_t) + sizeof(uint16_t) +				sizeof(uint8_t))));		debug("SvcRecHandle : 0x%x", handle);		rec = sdp_record_find(handle);	} else if (handleExpected != 0xffffffff)		rec = sdp_record_find(handleExpected);	if (!rec) {		rec = sdp_record_alloc();		rec->attrlist = NULL;		if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) {			rec->handle = handle;			sdp_record_add(device, rec);		} else if (handleExpected != 0xffffffff) {			rec->handle = handleExpected;			sdp_record_add(device, rec);		}	} else {		sdp_list_free(rec->attrlist, (sdp_free_func_t) sdp_data_free);		rec->attrlist = NULL;	}	while (localExtractedLength < seqlen) {		int attrSize = sizeof(uint8_t);		int attrValueLength = 0;		if (bufsize < attrSize + sizeof(uint16_t)) {			debug("Unexpected end of packet: Terminating extraction of attributes");			break;		}		debug("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, localExtractedLength);		dtd = *(uint8_t *) p;		attrId = ntohs(bt_get_unaligned((uint16_t *) (p + attrSize)));		attrSize += sizeof(uint16_t);				debug("DTD of attrId : %d Attr id : 0x%x", dtd, attrId);		pAttr = sdp_extract_attr(p + attrSize, bufsize - attrSize,							&attrValueLength, rec);		debug("Attr id : 0x%x attrValueLength : %d", attrId, attrValueLength);		attrSize += attrValueLength;		if (pAttr == NULL) {			debug("Terminating extraction of attributes");			break;		}		localExtractedLength += attrSize;		p += attrSize;		bufsize -= attrSize;		sdp_attr_replace(rec, attrId, pAttr);		extractStatus = 0;		debug("Extract PDU, seqLength: %d localExtractedLength: %d",					seqlen, localExtractedLength);	}	if (extractStatus == 0) {		debug("Successful extracting of Svc Rec attributes");#ifdef SDP_DEBUG		sdp_print_service_attr(rec->attrlist);#endif		*scanned += seqlen;	}	return rec;}/* * Add the newly created service record to the service repository */int service_register_req(sdp_req_t *req, sdp_buf_t *rsp){	int scanned = 0;	sdp_data_t *handle;	uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t);	int bufsize = req->len - sizeof(sdp_pdu_hdr_t);	sdp_record_t *rec;	req->flags = *p++;	if (req->flags & SDP_DEVICE_RECORD) {		bacpy(&req->device, (bdaddr_t *) p);		p += sizeof(bdaddr_t);		bufsize -= sizeof(bdaddr_t);	}	// save image of PDU: we need it when clients request this attribute	rec = extract_pdu_server(&req->device, p, bufsize, 0xffffffff, &scanned);	if (!rec)		goto invalid;	if (rec->handle == 0xffffffff) {		rec->handle = sdp_next_handle();		if (rec->handle < 0x10000) {			sdp_record_free(rec);			goto invalid;		}	} else {		if (sdp_record_find(rec->handle)) {			/* extract_pdu_server will add the record handle			 * if it is missing. So instead of failing, skip			 * the record adding to avoid duplication. */			goto success;		}	}	sdp_record_add(&req->device, rec);	if (!(req->flags & SDP_RECORD_PERSIST))		sdp_svcdb_set_collectable(rec, req->sock);	handle = sdp_data_alloc(SDP_UINT32, &rec->handle);	sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, handle);success:	/* if the browse group descriptor is NULL,	 * ensure that the record belongs to the ROOT group */	if (sdp_data_get(rec, SDP_ATTR_BROWSE_GRP_LIST) == NULL) {		 uuid_t uuid;		 sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP);		 sdp_pattern_add_uuid(rec, &uuid);	}	update_db_timestamp();	update_svclass_list();	/* Build a rsp buffer */	bt_put_unaligned(htonl(rec->handle), (uint32_t *) rsp->data);	rsp->data_size = sizeof(uint32_t);	return 0;invalid:	bt_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *) rsp->data);	rsp->data_size = sizeof(uint16_t);	return -1;}/* * Update a service record */int service_update_req(sdp_req_t *req, sdp_buf_t *rsp){	sdp_record_t *orec;	int status = 0, scanned = 0;	uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t);	int bufsize = req->len - sizeof(sdp_pdu_hdr_t);	uint32_t handle = ntohl(bt_get_unaligned((uint32_t *) p));	debug("Svc Rec Handle: 0x%x", handle);	p += sizeof(uint32_t);	bufsize -= sizeof(uint32_t);	orec = sdp_record_find(handle);	debug("SvcRecOld: %p", orec);	if (orec) {		sdp_record_t *nrec = extract_pdu_server(BDADDR_ANY, p, bufsize, handle, &scanned);		if (nrec && handle == nrec->handle) {			update_db_timestamp();			update_svclass_list();		} else {			debug("SvcRecHandle : 0x%x", handle);			debug("SvcRecHandleNew : 0x%x", nrec->handle);			debug("SvcRecNew : %p", nrec);			debug("SvcRecOld : %p", orec);			debug("Failure to update, restore old value");			if (nrec)				sdp_record_free(nrec);			status = SDP_INVALID_SYNTAX;		}	} else		status = SDP_INVALID_RECORD_HANDLE;	p = rsp->data;	bt_put_unaligned(htons(status), (uint16_t *) p);	rsp->data_size = sizeof(uint16_t);	return status;}/* * Remove a registered service record */int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp){	uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t);	uint32_t handle = ntohl(bt_get_unaligned((uint32_t *) p));	sdp_record_t *rec;	int status = 0;	/* extract service record handle */	p += sizeof(uint32_t);	rec = sdp_record_find(handle);	if (rec) {		sdp_svcdb_collect(rec);		status = sdp_record_remove(handle);		sdp_record_free(rec);		if (status == 0) {			update_db_timestamp();			update_svclass_list();		}	} else {		status = SDP_INVALID_RECORD_HANDLE;		debug("Could not find record : 0x%x", handle);	}	p = rsp->data;	bt_put_unaligned(htons(status), (uint16_t *) p);	rsp->data_size = sizeof(uint16_t);	return status;}

⌨️ 快捷键说明

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