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

📄 sdpclt.c

📁 affix是一个Open Source的蓝牙协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
		/*		 ** Check if we have continuation state set, if yes, we		 ** need to re-issue request before we parse ..		 */		cStateLength = __get_u8(pdata + responseCount);		DBPRT("Response id : %d\n", pduResponseHeader->pduId);		DBPRT("Attrlist byte count : %d\n", responseCount);		DBPRT("sdp_cs_t length : %d\n", cStateLength);		/*		 ** This is a split response, need to concatenate the intermediate		 ** responses as well as the last one which will have cStateLength == 0		 */		if ((cStateLength > 0) || (concatenatedResponseBuffer.length != 0)) {			char *targetPtr = NULL;			if (cStateLength > 0)				pCState = (sdp_cs_t *)(pdata + responseCount);			else				pCState = NULL;			/*			 ** Build concatenated response buffer			 */			concatenatedResponseBuffer.data = (char *)realloc(					concatenatedResponseBuffer.data, 					concatenatedResponseBuffer.length + responseCount);			concatenatedResponseBuffer.size = 				concatenatedResponseBuffer.length + responseCount;			targetPtr = concatenatedResponseBuffer.data + 				concatenatedResponseBuffer.length;			memcpy(targetPtr, pdata, responseCount);			concatenatedResponseBuffer.length += responseCount;		}	} while (pCState);	if (attrListByteCount > 0) {		int bytesScanned = 0;		if (concatenatedResponseBuffer.length != 0) {			pdata = concatenatedResponseBuffer.data;		}		svcRec = sdp_clt_extr_pdu(pdata, svcHandle, &bytesScanned);		DBPRT("In sdp_attr_req function \n");		DBPRT("The status of extractServiceRecord is %d\n", status);		DBPRT("The svcHandle is 0x%x\n", svcHandle);		if (!svcRec) {			status = -1;			goto exit;		}		*_svcRec = svcRec;		*maxAttrResponseByteCount = bytesScanned;	}exit:	free(requestBuffer);	free(responseBuffer);	if (concatenatedResponseBuffer.data != NULL)		free(concatenatedResponseBuffer.data);	return status;}int __sdp_attr_req(		struct sockaddr_affix *sa,		uint32_t svcHandle,		sdp_attrreq_t attrReqType,		slist_t *attrIDList,		uint16_t maxAttrIDByteCount,		sdpsvc_t	**svcRec,		uint16_t *maxAttrResponseByteCount){	int status = 0;	int srvHandle;	srvHandle = sdp_connect(sa);	if (srvHandle < 0)		return srvHandle;	status = sdp_attr_req(srvHandle, svcHandle, attrReqType,			attrIDList, maxAttrIDByteCount, svcRec, maxAttrResponseByteCount);	sdp_close(srvHandle);	return status;}/*** This is a service search request combined with the service** attribute request. First a service class match is done and** for matching service, requested attributes are extracted**** 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****   AttributeSpecification attrSpec**     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****   slist_t **svcResponseList**     This variable is set on a successful return to point to**     service(s) found. Each element of this list is of type**     uint32_t (of the services which matched the search list)****   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_search_attr_req(		int srvHandle,		slist_t *svcSearchList, 		sdp_attrreq_t attrReqType,		slist_t *attrIDList,		uint16_t maxAttrByteCount,		slist_t **svcResponseList,		uint16_t *maxAttrResponseByteCount		){	int status = 0;	int requestSize = 0, _requestSize;	int responseSize = 0;	int seqLength = 0;	int attrListByteCount = 0;	char *pdata = NULL, *_pdata;	char *requestBuffer =  NULL;	char *responseBuffer =  NULL;	sdp_hdr_t *pduRequestHeader;	sdp_hdr_t *pduResponseHeader;	uint8_t dataType;	slist_t *svcRecHandleList = NULL;	sdppdu_t concatenatedResponseBuffer;	sdp_cs_t	*pCState = NULL;	int bytesScanned = 0;	*maxAttrResponseByteCount = 0;	if ((attrReqType != IndividualAttributes) && (attrReqType != RangeOfAttributes))		return SDP_ERR_INVALID_ARG;		requestBuffer = (char *)malloc(SDP_REQ_BUF_SIZE);	if (!requestBuffer)		return -1;	responseBuffer = (char *)malloc(SDP_RSP_BUF_SIZE);	if (!responseBuffer) {		free(requestBuffer);		return -1;	}	memset((char *)&concatenatedResponseBuffer, 0, sizeof(sdppdu_t));	pduRequestHeader = (sdp_hdr_t *)requestBuffer;	pduRequestHeader->pduId = SDP_PDU_SEARCH_ATTR_REQ;	// generate PDU	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 attr count that client expects	 */	__put_u16(pdata, htons(maxAttrByteCount));	requestSize += sizeof(uint16_t);	pdata += sizeof(uint16_t);	DBPRT("Max attr byte count : %d\n", maxAttrByteCount);	/*	 ** 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;	DBPRT("Attr list length : %d\n", seqLength);	requestSize += seqLength;	// save before Continuation State	_pdata = pdata;	_requestSize = requestSize;	do {		int responseCount = 0;		int cStateLength = 0;		pduRequestHeader->transactionId = htons(sdp_gen_trans());		/*		 * Add continuation state		 * pCState can be null		 */		requestSize = _requestSize + sdp_copy_cstate(_pdata, pCState);		/*		 ** Set the request header's param length		 */		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);	// pdata points to attribute list		/*		 ** Check if we have continuation state set, if yes, we		 ** need to re-issue request before we parse ..		 */		cStateLength = __get_u8(pdata + responseCount);		DBPRT("Attrlist byte count : %d\n", attrListByteCount);		DBPRT("Response byte count : %d\n", responseCount);		DBPRT("Cstate length : %d\n", cStateLength);		/*		 ** This is a split response, need to concatenate the intermediate		 ** responses as well as the last one which will have cStateLength == 0		 */		if ((cStateLength > 0) || (concatenatedResponseBuffer.length != 0)) {			char *targetPtr = NULL;			if (cStateLength > 0) 				pCState = (sdp_cs_t *)(pdata + responseCount);			else				pCState = NULL;			/*			 ** Build concatenated response buffer			 */			concatenatedResponseBuffer.data = (char *)realloc(					concatenatedResponseBuffer.data, 					concatenatedResponseBuffer.length + responseCount);			targetPtr = concatenatedResponseBuffer.data + 				concatenatedResponseBuffer.length;			concatenatedResponseBuffer.size = 				concatenatedResponseBuffer.length + responseCount;			memcpy(targetPtr, pdata, responseCount);			concatenatedResponseBuffer.length += responseCount;		}	} while (pCState);	if (attrListByteCount <= 0)		goto exit;	if (concatenatedResponseBuffer.length != 0)		pdata = concatenatedResponseBuffer.data;	/*	 ** Response is a sequence of sequence(s) for one or	 ** more data element sequence(s) representing services	 ** for which attributes are returned	 */	pdata = sdp_extr_seq_dtd(pdata, &dataType, &seqLength, &bytesScanned);	DBPRT("Bytes scanned : %d\n", bytesScanned);	DBPRT("Seq length : %d\n", seqLength);	if (!pdata || seqLength == 0)		goto exit;	for (;;) {		int		localSeqSize;		sdpsvc_t	*svcRec = NULL;		localSeqSize = 0;		svcRec = sdp_clt_extr_pdu(pdata, 0xffffffff, &localSeqSize);		if (!svcRec) {			BTERROR("SVC REC is null\n");			status = -1;			break;		}		bytesScanned += localSeqSize;		*maxAttrResponseByteCount += localSeqSize;		pdata += localSeqSize;		DBPRT("Loc seq length : %d\n", localSeqSize);		DBPRT("Svc Rec Handle : 0x%x\n", svcRec->serviceRecordHandle);		DBPRT("Bytes scanned : %d\n", bytesScanned);		DBPRT("Attrlist byte count : %d\n", attrListByteCount);		s_list_append(&svcRecHandleList, svcRec);		if (attrListByteCount == bytesScanned) {			DBPRT("Successful scan of service attr lists\n");			*svcResponseList = svcRecHandleList;			break;		}	}exit:	free(requestBuffer);	free(responseBuffer);	if (concatenatedResponseBuffer.data != NULL)		free(concatenatedResponseBuffer.data);	return status;}int __sdp_search_attr_req(		struct sockaddr_affix *sa,		slist_t *svcSearchList, 		sdp_attrreq_t attrReqType,		slist_t *attrIDList,		uint16_t maxAttrByteCount,		slist_t **svcResponseList,		uint16_t *maxAttrResponseByteCount		){	int status = 0;	int srvHandle;	srvHandle = sdp_connect(sa);	if (srvHandle < 0)		return srvHandle;	status = sdp_search_attr_req(srvHandle, svcSearchList, attrReqType, attrIDList,			maxAttrByteCount, svcResponseList, maxAttrResponseByteCount);	sdp_close(srvHandle);	return status;}/* --------------------------------------------------------------------------*//*   Contains utilities for use by SDP service discovery clients   to extract individual attributes from a service record   All utility functions below have a signature    int getXXX(uint32_t svcRec, XXX *pXXX)   The pointer pXXX is set to point at the attribute value if   it is present in the service record and 0 is returned, else   E_NOT_EXIST is returned*/int sdp_is_proto_alt(sdpsvc_t *svcRec){	sdpdata_t	*attr;	attr = sdp_get_attr(svcRec, SDP_ATTR_PROTO_DESC_LIST);	if (!attr)		return -1;	if (sdp_is_alt(attr))		return 1;	return 0;}int sdp_get_proto_alt_attr(sdpsvc_t *svcRec, void **seq, void **state){	sdpdata_t	*attr;	slist_t		*list;	if (state && *state) {		list = *state;		goto get;	}	attr = sdp_get_attr(svcRec, SDP_ATTR_PROTO_DESC_LIST);	if (!attr)		return SDP_ERR_NOT_EXIST;	if (sdp_is_seq(attr)) {		/* not an alternate  - consider as only one alternative */		*seq = attr;		if (state)			*state = NULL;		return 0;	}

⌨️ 快捷键说明

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