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

📄 sdpclt.c

📁 affix是一个Open Source的蓝牙协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
/*    Affix - Bluetooth Protocol Stack for Linux   Copyright (C) 2001,2002 Nokia Corporation   Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>   Original Author: Guruprasad Krishnamurthy <kgprasad@hotmail.com>   This program is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by the   Free Software Foundation; either version 2 of the License, or (at your   option) any later version.   This program is distributed in the hope that it will be useful, but   WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   General Public License for more details.   You should have received a copy of the GNU General Public License along   with this program; if not, write to the Free Software Foundation, Inc.,   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*//*   $Id: sdpclt.c,v 1.59 2004/02/26 13:56:47 kassatki Exp $   Contains the implementation of the SDP service discovery API    Fixes:   		Dmitry Kasatkin		- Continuation Mechanism		Dmitry Kasatkin		- Port Request		Dmitry Kasatkin		- cleaning		Dmitry Kasatkin		- new simple API*/	 #include <affix/config.h>#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <string.h>#include <affix/sdp.h>#include <affix/sdpclt.h>#include "utils.h"#include "cstate.h"#include "attr.h"/*** This is a service search request. **** INPUT :****   slist_t *svcSearchList**     Singly linked list containing elements of the search**     pattern. Each entry in the list is a uuid_t (DataTypeSDP_DTD_UUID16)**     of the service to be searched****   uint16_t maxSvcRecordCount**      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 > maxSvcRecordCount entries**** OUTPUT :****   int return value**     E_OK **       The request completed successfully. This does not**       mean the requested services were found**     E_FAILURE**       On any failure**     E_TIMEOUT **       The request completed unsuccessfully due to a timeout****   slist_t **svcHandleList**     This variable is set on a successful return if there are**     non-zero service handles. It is a singly linked list of**     service record handles (uint32_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**     svcHandleList*/int sdp_search_req(		int srvHandle,		slist_t *svcSearchList, 		uint16_t maxSvcRecordCount,		slist_t **svcResponseList,		uint16_t *handleCountInResponse){	int status = 0;	int requestSize = 0, _requestSize;	int responseSize = 0;	int seqLength = 0;	char *pdata, *_pdata;	char *requestBuffer =  NULL;	char *responseBuffer =  NULL;	sdp_hdr_t *pduRequestHeader;	sdp_hdr_t *pduResponseHeader;	sdp_cs_t *pCState = NULL;	//sdppdu_t concatenatedResponseBuffer;	int responseLength = 0;	*handleCountInResponse = 0;	requestBuffer = (char *)malloc(SDP_REQ_BUF_SIZE);	if (!requestBuffer)		return -1;	responseBuffer = (char *)malloc(SDP_RSP_BUF_SIZE);	if (!responseBuffer) {		free(requestBuffer);		return -1;	}	pduRequestHeader = (sdp_hdr_t *)requestBuffer;	pduRequestHeader->pduId = SDP_PDU_SEARCH_REQ;	pdata = (char *)(requestBuffer + sizeof(sdp_hdr_t));	requestSize = sizeof(sdp_hdr_t);	/*	 ** Add service class IDs for search	 */	seqLength = sdp_gen_uuid_seq_pdu(pdata, svcSearchList);	DBPRT("Data seq added : %d\n", seqLength);	/*	 ** Now set the length and increment the pointer	 */	requestSize += seqLength;	pdata += seqLength;	/*	 ** Specify the maximum svc rec count that	 ** client expects	 */	__put_u16(pdata, htons(maxSvcRecordCount));	requestSize += sizeof(uint16_t);	pdata += sizeof(uint16_t);	_requestSize = requestSize;	_pdata = pdata;	*svcResponseList = NULL;	//important	do {		int bytesScanned = 0;		int totalServiceRecordCount, currentServiceRecordCount;		/*		 ** Add continuation state or NULL (first time)		 */		requestSize = _requestSize + sdp_copy_cstate(_pdata, pCState);		/*		 ** Set the request header's param length		 */		pduRequestHeader->paramLength = htons(requestSize - sizeof(sdp_hdr_t));		pduRequestHeader->transactionId = htons(sdp_gen_trans());		/*		 ** Send the request, wait for response and if		 ** not error, set the appropriate values		 ** and return		 */		status = sdp_send_req_w4_rsp(srvHandle, requestBuffer, 				responseBuffer, requestSize, &responseSize);		if (status)			break;		pduResponseHeader = (sdp_hdr_t *)responseBuffer;		if (pduResponseHeader->pduId == SDP_PDU_ERROR_RSP) {			status = pduResponseHeader->data[0];	// ErorrCode			break;		}		responseLength = ntohs(pduResponseHeader->paramLength);		pdata = responseBuffer + sizeof(sdp_hdr_t);		/*		 ** Net service record match count		 */		totalServiceRecordCount = 0;		currentServiceRecordCount = 0;		totalServiceRecordCount = ntohs(__get_u16(pdata));		pdata += sizeof(uint16_t);		bytesScanned += sizeof(uint16_t);		currentServiceRecordCount = ntohs(__get_u16(pdata));		pdata += sizeof(uint16_t);		bytesScanned += sizeof(uint16_t);		DBPRT("Total svc count : %d\n", totalServiceRecordCount);		DBPRT("Current svc count : %d\n", currentServiceRecordCount);		DBPRT("ResponseLength : %d\n", responseLength);		if (currentServiceRecordCount == 0)			break;		status = sdp_extr_svc_handles(pdata, svcResponseList, 				currentServiceRecordCount, &bytesScanned);		if (status)			break;				*handleCountInResponse = currentServiceRecordCount;		/*		 ** Check if we have sdp_cstate_t set, if yes,		 ** set the pCState pointer		 */		DBPRT("BytesScanned : %d\n", bytesScanned);		if (responseLength > bytesScanned) {			uint8_t cStateLength = 0;			pdata = responseBuffer + sizeof(sdp_hdr_t) + bytesScanned;			cStateLength = __get_u8(pdata);			if (cStateLength > 0) {				pCState = (sdp_cs_t *)pdata;				DBPRT("Continuation state present\n");				DBPRT("sdp_cs_t length : %d\n", cStateLength);			} else				pCState = NULL;		}	} while (pCState);		free(requestBuffer);	free(responseBuffer);	//if (concatenatedResponseBuffer.data != NULL)	//free(concatenatedResponseBuffer.data);	return status;}int __sdp_search_req(		struct sockaddr_affix *sa,		slist_t *svcSearchList, 		uint16_t maxSvcRecordCount,		slist_t **svcResponseList,		uint16_t *handleCountInResponse){	int status = 0;	int srvHandle;	srvHandle = sdp_connect(sa);	if (srvHandle < 0)		return srvHandle;	status  = sdp_search_req(srvHandle, svcSearchList, 			maxSvcRecordCount, svcResponseList, handleCountInResponse);	sdp_close(srvHandle);	return status;}/*** This is a service attribute request. **** INPUT :****   uint32_t svcHandle**     The handle of the service for which the attribute(s) are**     requested****   sdp_attrreq_t attrReqType**     Attribute identifiers are 16 bit unsigned integers specified**     in one of 2 ways described below :**     IndividualAttributes - 16bit individual identifiers**        They are the actual attribute identifiers in ascending order****     RangeOfAttributes - 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****   slist_t *attrIDList**     Singly linked list containing attribute identifiers desired.**     Every element is either a uint16_t(attrSpec = IndividualAttributes)  **     or a uint32_t(attrSpec=RangeOfAttributes)****   uint16_t maxAttrIDByteCount**     The byte count of the number of attribute IDs specified**     in the request list**** OUTPUT :**   int return value**     E_OK **       The request completed successfully. This does not**       mean the requested services were found**     E_TIMEOUT **       The request completed unsuccessfully due to a timeout****   uint16_t *maxAttrResponseByteCount**     This is a pointer to a 16 bit integer, which is set to **     indicate the number of bytes of attributes returned. **     This pointer is set on successful return***/int sdp_attr_req(		int srvHandle,		uint32_t svcHandle,		sdp_attrreq_t attrReqType,		slist_t *attrIDList,		uint16_t maxAttrIDByteCount,		sdpsvc_t **_svcRec,		uint16_t *maxAttrResponseByteCount){	int		status = 0;	int 		requestSize = 0, _requestSize;	int 		responseSize = 0;	int 		attrListByteCount = 0;	int 		seqLength = 0;	char 		*pdata = NULL, *_pdata;	char 		*requestBuffer =  NULL;	char 		*responseBuffer =  NULL;	sdp_hdr_t	*pduRequestHeader;	sdp_hdr_t	*pduResponseHeader;	sdp_cs_t	*pCState = NULL;	uint8_t		cStateLength = 0;	sdppdu_t	concatenatedResponseBuffer;	sdpsvc_t	*svcRec = NULL;	*_svcRec = NULL;	*maxAttrResponseByteCount = 0;	if ((attrReqType != IndividualAttributes) && (attrReqType != RangeOfAttributes))		return SDP_ERR_INVALID_ARG;	requestBuffer = (char *)malloc(SDP_REQ_BUF_SIZE);	if (!requestBuffer)		return SDP_ERR_INVALID_ARG;	responseBuffer = (char *)malloc(SDP_RSP_BUF_SIZE);	if (!responseBuffer) {		free(requestBuffer);		return SDP_ERR_INVALID_ARG;	}	memset((char *)&concatenatedResponseBuffer, 0, sizeof(sdppdu_t));	pduRequestHeader = (sdp_hdr_t *)requestBuffer;	pduRequestHeader->pduId = SDP_PDU_ATTR_REQ;	pdata = (char *)(requestBuffer + sizeof(sdp_hdr_t));	requestSize = sizeof(sdp_hdr_t);	/*	 ** Add the service record handle	 */	__put_u32(pdata, htonl(svcHandle));	requestSize += sizeof(uint32_t);	pdata += sizeof(uint32_t);	/*	 ** Add the maxAttrIDByteCount specifying response limit	 */	__put_u16(pdata, htons(maxAttrIDByteCount));	requestSize += sizeof(uint16_t);	pdata += sizeof(uint16_t);	/*	 ** Get attr seq PDU form 	 */	seqLength = sdp_gen_attr_seq_pdu(pdata, attrIDList, 			((attrReqType == IndividualAttributes) ? SDP_DTD_UINT16 : SDP_DTD_UINT32));	if (seqLength < 0) {		status = seqLength;		goto exit;	} 	pdata += seqLength;	requestSize += seqLength;	DBPRT("Attr list length : %d\n", seqLength);	// save before Continuation State	_pdata = pdata;	_requestSize = requestSize;	do {		int responseCount = 0;		/*		 ** Add NULL continuation state		 */		requestSize = _requestSize + sdp_copy_cstate(_pdata, pCState);		/*		 ** Set the request header's param length		 */		pduRequestHeader->transactionId = htons(sdp_gen_trans());		pduRequestHeader->paramLength = htons(requestSize - sizeof(sdp_hdr_t));		status = sdp_send_req_w4_rsp(srvHandle, requestBuffer, 				responseBuffer, requestSize, &responseSize);		if (status)			goto exit;		pduResponseHeader = (sdp_hdr_t *)responseBuffer;		if (pduResponseHeader->pduId == SDP_PDU_ERROR_RSP) {			status = pduResponseHeader->data[0];	// ErrorCode			goto exit;		}		pdata = responseBuffer + sizeof(sdp_hdr_t);		responseCount  = ntohs(__get_u16(pdata));		attrListByteCount += responseCount;		pdata += sizeof(uint16_t);

⌨️ 快捷键说明

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