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

📄 service.c

📁 Bluezan implementation of the Bluetooth&#8482 wireless standards specifications for Linux. The code
💻 C
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2001-2002  Nokia Corporation *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> *  Copyright (C) 2002-2004  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 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: service.c,v 1.6 2005/02/22 15:22:08 holtmann Exp $ */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <netinet/in.h>#include <sys/socket.h>#include <bluetooth/bluetooth.h>#include <bluetooth/sdp.h>#include <bluetooth/sdp_lib.h>#include "sdpd.h"extern void update_db_timestamp(void);// FIXME: refactor for server-sidestatic sdp_record_t *extract_pdu_server(char *p, 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, &dtd, &seqlen);	p += *scanned;	lookAheadAttrId = ntohs(sdp_get_unaligned((uint16_t *)(p + sizeof(uint8_t))));	SDPDBG("Look ahead attr id : %d\n", lookAheadAttrId);	if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) {		handle = ntohl(sdp_get_unaligned((uint32_t *)(p +				sizeof(uint8_t) + sizeof(uint16_t) +				sizeof(uint8_t))));		SDPDBG("SvcRecHandle : 0x%x\n", handle);		rec = sdp_record_find(handle);	} else if (handleExpected != 0xffffffff)		rec = sdp_record_find(handleExpected);	if (rec == NULL) {		rec = sdp_record_alloc();		rec->attrlist = NULL;		if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) {			rec->handle = handle;			sdp_record_add(rec);		} else if (handleExpected != 0xffffffff) {			rec->handle = handleExpected;			sdp_record_add(rec);		}	}	while (localExtractedLength < seqlen) {		int attrSize = sizeof(uint8_t);		int attrValueLength = 0;		SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, localExtractedLength);		dtd = *(uint8_t *)p;		attrId = ntohs(sdp_get_unaligned((uint16_t *)(p + attrSize)));		attrSize += sizeof(uint16_t);				SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attrId);		pAttr = sdp_extract_attr(p + attrSize, &attrValueLength, rec);		SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attrId, attrValueLength);		attrSize += attrValueLength;		if (pAttr == NULL) {			SDPDBG("Terminating extraction of attributes");			break;		}		localExtractedLength += attrSize;		p += attrSize;		sdp_attr_replace(rec, attrId, pAttr);		extractStatus = 0;		SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d",					seqlen, localExtractedLength);	}	if (extractStatus == 0) {		SDPDBG("Successful extracting of Svc Rec attributes\n");#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;	char *p = req->buf + sizeof(sdp_pdu_hdr_t);	sdp_record_t *rec;	req->flags = *p++;	// save image of PDU: we need it when clients request this attribute	rec = extract_pdu_server(p, 0xffffffff, &scanned);	if (rec == NULL) {		sdp_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *)rsp->data);		rsp->data_size = sizeof(uint16_t);		return -1;	}	rec->handle = sdp_next_handle();	if (rec->handle < 0x10000)		return -1;	sdp_record_add(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);	/*	 * 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();	/* Build a rsp buffer */	sdp_put_unaligned(htonl(rec->handle), (uint32_t *)rsp->data);	rsp->data_size = sizeof(uint32_t);	return 0;}/* * 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;	char *p = req->buf + sizeof(sdp_pdu_hdr_t);	uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p));	SDPDBG("");	SDPDBG("Svc Rec Handle: 0x%x\n", handle);		p += sizeof(uint32_t);	orec = sdp_record_find(handle);		SDPDBG("SvcRecOld: 0x%x\n", (uint32_t)orec);	if (orec) {		sdp_record_t *nrec = extract_pdu_server(p, handle, &scanned);		if (nrec && handle == nrec->handle)			update_db_timestamp();		else {			SDPDBG("SvcRecHandle : 0x%x\n", handle);			SDPDBG("SvcRecHandleNew : 0x%x\n", nrec->handle);			SDPDBG("SvcRecNew : 0x%x\n", (uint32_t) nrec);			SDPDBG("SvcRecOld : 0x%x\n", (uint32_t) orec);			SDPDBG("Failure to update, restore old value\n");			if (nrec)				sdp_record_free(nrec);			status = SDP_INVALID_SYNTAX;		}	} else		status = SDP_INVALID_RECORD_HANDLE;	p = rsp->data;	sdp_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){	char *p = req->buf + sizeof(sdp_pdu_hdr_t);	uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p));	sdp_record_t *rec;	int status = 0;	SDPDBG("");		/* 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();	} else {		status = SDP_INVALID_RECORD_HANDLE;		SDPDBG("Could not find record : 0x%x\n", handle);	}	p = rsp->data;	sdp_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 + -