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

📄 request.c

📁 蓝牙的各种编程接口和各种按理介绍,还有一些例子和说明
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  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.*//*  SDP service discovery API   Fixes:  Guruprasad Krishnamurthy  Dmitry Kasatkin			-	Continuation mechanism*//* * $Id: request.c,v 1.37 2003/02/12 13:18:06 jscrane Exp $ */#include <malloc.h>#include <errno.h>#include <sys/socket.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#include "sdp.h"#include "sdp_internal.h"#include "sdp_lib.h"/* * Extract a sequence of service record handles from a PDU buffer * and add the entries to a sdp_list_t. Note that the service record * handles are not in "data element sequence" form, but just like * an array of service handles */static void extract_record_handle_seq(char *pdu, sdp_list_t **seq, int count, int *scanned){	sdp_list_t *pSeq = *seq;	char *pdata = pdu;	int n;	for (n = 0; n < count; n++) {		uint32_t *pSvcRec = (uint32_t *) malloc(sizeof(uint32_t));		*pSvcRec = ntohl(sdp_get_unaligned((uint32_t *)pdata));		pSeq = sdp_list_append(pSeq, pSvcRec);		pdata += sizeof(uint32_t);		*scanned += sizeof(uint32_t);	}	*seq = pSeq;}/* * Generate the attribute sequence pdu form * from sdp_list_t elements. Return length of attr seq */static int gen_dataseq_pdu(char *dst, const sdp_list_t *seq, uint8_t dtd){	sdp_data_t *dataseq;	void **types, **values;	sdp_buf_t buf;	int i, seqlen = sdp_list_len(seq);	// Fill up the value and the dtd arrays	SDPDBG("");		memset(&buf, 0, sizeof(sdp_buf_t));	buf.data = (char *)malloc(SDP_UUID_SEQ_SIZE);	buf.buf_size = SDP_UUID_SEQ_SIZE;	SDPDBG("Seq length : %d\n", seqlen);	types = malloc(seqlen * sizeof(void *));	values = malloc(seqlen * sizeof(void *));	for (i = 0; i < seqlen; i++) {		void *data = seq->data;		types[i] = &dtd;		if (SDP_IS_UUID(dtd))			data = &((uuid_t *)data)->value;		values[i] = data;		seq = seq->next;	}	dataseq = sdp_seq_alloc(types, values, seqlen);	SDPDBG("Data Seq : 0x%p\n", seq);	seqlen = sdp_gen_pdu(&buf, dataseq);	SDPDBG("Copying : %d\n", buf.data_size);	memcpy(dst, buf.data, buf.data_size);	sdp_data_free(dataseq);	free(types);	free(values);	free(buf.data);	return seqlen;}static int gen_searchseq_pdu(char *dst, const sdp_list_t *seq){	uuid_t *uuid = (uuid_t *)seq->data;	return gen_dataseq_pdu(dst, seq, uuid->type);}static int gen_attridseq_pdu(char *dst, const sdp_list_t *seq, uint8_t dataType){	return gen_dataseq_pdu(dst, seq, dataType);}static int copy_cstate(char *pdata, const sdp_cstate_t *cstate){	if (cstate) {		*pdata++ = cstate->length;		memcpy(pdata, cstate->data, cstate->length);		return cstate->length + 1;	}	*pdata = 0;	return 1;}/* * This is a service search request.  * * INPUT : * *   sdp_list_t *search_list *     Singly linked list containing elements of the search *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16) *     of the service to be searched * *   uint16_t max_rec_num *      A 16 bit integer which tells the service, the maximum *      entries that the client can handle in the response. The *      server is obliged not to return > max_rec_num entries * * OUTPUT : * *   int return value *     0: *       The request completed successfully. This does not *       mean the requested services were found *     -1: *       On any failure and sets errno * *   sdp_list_t **rsp_list *     This variable is set on a successful return if there are *     non-zero service handles. It is a singly linked list of *     service records (sdp_record_t *) * *   uint16_t *handleCount *     This is a pointer to a 16 bit integer, which is set to  *     indicate the number of service record handles present in *     rec_list */int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search,			uint16_t max_rec_num, sdp_list_t **rsp){	int status = 0;	int reqsize = 0, _reqsize;	int rspsize = 0, rsplen;	int seqlen = 0;	int scanned, total_rec_count, rec_count;	char *pdata, *_pdata;	char *reqbuf, *rspbuf;	sdp_pdu_hdr_t *reqhdr, *rsphdr;	sdp_cstate_t *cstate = NULL;	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);	if (!reqbuf || !rspbuf) {		errno = ENOMEM;		status = -1;		goto end;	}	reqhdr = (sdp_pdu_hdr_t *)reqbuf;	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);	reqsize = sizeof(sdp_pdu_hdr_t);	// add service class IDs for search	seqlen = gen_searchseq_pdu(pdata, search);	SDPDBG("Data seq added : %d\n", seqlen);	// set the length and increment the pointer	reqsize += seqlen;	pdata += seqlen;	// specify the maximum svc rec count that client expects	sdp_put_unaligned(htons(max_rec_num), (uint16_t *)pdata);	reqsize += sizeof(uint16_t);	pdata += sizeof(uint16_t);	_reqsize = reqsize;	_pdata   = pdata;	*rsp = NULL;	do {		// Add continuation state or NULL (first time)		reqsize = _reqsize + copy_cstate(_pdata, cstate);		// Set the request header's param length		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));		reqhdr->tid  = htons(sdp_gen_tid(session));		/*		 * Send the request, wait for response and if		 * no error, set the appropriate values and return		 */		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);		if (status < 0)			goto end;		rsplen = 0;		rsphdr = (sdp_pdu_hdr_t *)rspbuf;		rsplen = ntohs(rsphdr->plen);		if (rsphdr->pdu_id == SDP_ERROR_RSP) {			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);			status = -1;			goto end;		}		scanned = 0;		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);		// net service record match count		total_rec_count = ntohs(sdp_get_unaligned((uint16_t *)pdata));		pdata += sizeof(uint16_t);		scanned += sizeof(uint16_t);		rec_count = ntohs(sdp_get_unaligned((uint16_t *)pdata));		pdata += sizeof(uint16_t);		scanned += sizeof(uint16_t);		SDPDBG("Total svc count: %d\n", total_rec_count);		SDPDBG("Current svc count: %d\n", rec_count);		SDPDBG("ResponseLength: %d\n", rsplen);		if (!rec_count) {			status = -1;			goto end;		}		extract_record_handle_seq(pdata, rsp, rec_count, &scanned);		SDPDBG("BytesScanned : %d\n", scanned);		if (rsplen > scanned) {			uint8_t cstate_len;			pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned;			cstate_len = *(uint8_t *)pdata;			if (cstate_len > 0) {				cstate = (sdp_cstate_t *)pdata;				SDPDBG("Cont state length: %d\n", cstate_len);			} else				cstate = NULL;		}	} while (cstate);  end:	if (reqbuf)		free(reqbuf);	if (rspbuf)		free(rspbuf);	return status;}/* * This is a service attribute request.  * * INPUT : * *   uint32_t handle *     The handle of the service for which the attribute(s) are *     requested * *   sdp_attrreq_type_t reqtype *     Attribute identifiers are 16 bit unsigned integers specified *     in one of 2 ways described below : *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers *        They are the actual attribute identifiers in ascending order * *     SDP_ATTR_REQ_RANGE - 32bit identifier range *        The high-order 16bits is the start of range *        the low-order 16bits are the end of range *        0x0000 to 0xFFFF gets all attributes * *   sdp_list_t *attrid *     Singly linked list containing attribute identifiers desired. *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)   *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) * * OUTPUT : *   return sdp_record_t * *     0: *       On any error and sets errno *     !0: *	 The service record */sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, 			sdp_attrreq_type_t reqtype, const sdp_list_t *attrids){	int status = 0;	int reqsize = 0, _reqsize;	int rspsize = 0, rsp_count;	int attr_list_len = 0;	int seqlen = 0;	char *pdata, *_pdata;	char *reqbuf, *rspbuf;	sdp_pdu_hdr_t *reqhdr, *rsphdr;	sdp_cstate_t *cstate = NULL;	uint8_t cstate_len = 0;	sdp_buf_t rsp_concat_buf;	sdp_record_t *rec = 0;	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {

⌨️ 快捷键说明

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