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

📄 request.c

📁 Affix - Bluetooth Protocol Stack for Linux has been developed at Nokia Research Center in Helsinki
💻 C
📖 第 1 页 / 共 3 页
字号:
int sdp_gen_svc_pdu_by_attrs(		sdpsvc_t *svcRec,		slist_t *attrSeq,		uint8_t attrDataType,		sdppdu_t *pdu,		int maxExpectedAttrSize		){	int 	status = 0;	int 	attrLength;	int 	index = 0;	if (!svcRec)		return SDP_ERR_SERVICE_RECORD_HANDLE;	if (!attrSeq) {		DBPRT("Attribute sequence is NULL");		return 0;	}#ifdef CONFIG_AFFIX_DEBUG	if (attrSeq != NULL) {		DBPRT("Entries in attr seq : %d", s_list_length(attrSeq));	}	DBPRT("AttrDataType : %d", attrDataType);#endif	/*	 ** Set the maximum expected size before hand	 */	pdu->size = maxExpectedAttrSize;	/*	 ** This is a request for the entire attribute range	 */	if (svcRec->pdu.data == NULL) {		DBPRT("Generating svc rec pdu form");		sdp_gen_svc_pdu(svcRec);	}	attrLength = 0;	if (attrDataType == SDP_DTD_UINT16) {		void	*pAttr;		// Fix for empty AttributeLists (Litos) 13-11-2003		int currentlength = pdu->length;		// End litos fix		for (index = 0; (pAttr = s_list_nth_data(attrSeq, index)); index++) {			uint16_t	attrId = 0;			attrId = *(uint16_t *)pAttr;			DBPRT("Attr id requested : 0x%x", attrId);			sdp_gen_svc_pdu_by_attr(svcRec, attrId, pdu);		}		// Fix for empty AttributeLists (Litos) 13-11-2003			if (currentlength == pdu->length){		//No attributes to be returned. So we have to return an empty sequence !!!!			DBPRT("Creating empty Data Sequence\n");			__put_u8(pdu->data,SDP_DTD_SEQ8);			__put_u8((pdu->data+sizeof(uint8_t)),0); //Size of the empty sequence is 0			pdu->length+=sizeof(uint8_t) + sizeof(uint8_t);			DBPRT("Pdu length: %d\n Pdu size:%d\n", pdu->length,pdu->size);		}		// End litos fix			} else if (attrDataType == SDP_DTD_UINT32) {			uint8_t	completeAttrSetBuilt = 0;			void	*pAttr;			for (index = 0; (pAttr = s_list_nth_data(attrSeq, index)); index++) {				uint32_t 	attrRange = 0;				uint16_t 	lowIdLim = 0;				uint16_t 	highIdLim = 0;				attrRange = *(uint32_t *)pAttr;				lowIdLim = ((0xffff0000 & attrRange) >> 16);				highIdLim = 0x0000ffff & attrRange;				DBPRT("attr range : 0x%x", attrRange);				DBPRT("Low id : 0x%x", lowIdLim);				DBPRT("High id : 0x%x", highIdLim);				if ((lowIdLim == 0x0000) &&						(highIdLim == 0xffff) &&						(completeAttrSetBuilt == 0) &&						(svcRec->pdu.length <= pdu->size)) {					completeAttrSetBuilt = 1;					/*					 ** Create a copy of it					 */					DBPRT("Copy attr pdu form : %d", svcRec->pdu.length);					memcpy(pdu->data, svcRec->pdu.data, 							svcRec->pdu.length);					pdu->length = svcRec->pdu.length;				} else {					/*					 ** Not the entire range of attributes, pick and choose					 ** attributes requested					 */					// Fix for empty AttributeLists (Litos) 13-11-2003					int currentlength = pdu->length;					// End litos fix								int attrId;					for (attrId = lowIdLim; attrId <= highIdLim; attrId++)						sdp_gen_svc_pdu_by_attr(svcRec, attrId, pdu);					// Fix for empty AttributeLists (Litos) 13-11-2003					if (currentlength == pdu->length){						//No attributes to be returned. So we have to return an empty sequence !!!!						__put_u8(pdu->data,SDP_DTD_SEQ8);						__put_u8((pdu->data+sizeof(uint8_t)),0); //Size of the empty sequence is 0						pdu->length+=sizeof(uint8_t) + sizeof(uint8_t);					}					// End litos fix						}			}	} else {		status = SDP_ERR_REQUEST_SYNTAX;		BTERROR("Unexpected data type : 0x%x", attrDataType);		BTERROR("Expect uint16_t or uint32_t");	}	return status;}/* ** A request for the attributes of a service record. ** First check if the service record (specified by ** service record handle) exists, then call the attribute ** streaming function */int _sdp_attr_req(sdp_request_t *requestPdu, sdppdu_t *pdu){	char		*pdata;	int		status = 0;	sdpsvc_t	*svcRec;	int		maxResponseSize;	uint32_t	svcRecHandle;	sdp_cstate_t	*pCState;	char		*pResponse = NULL;	short 		continuationStateSize = 0;	slist_t		*attrSeq = NULL;	uint8_t		attrDataType = 0;	int		bytesScanned = 0;	pdata = requestPdu->data + sizeof(sdp_hdr_t);	svcRecHandle = ntohl(__get_u32(pdata));	pdata += sizeof(uint32_t);	maxResponseSize = ntohs(__get_u16(pdata));	pdata += sizeof(uint16_t);	/*	 ** Extract the attribute list	 */	bytesScanned = sdp_extr_data_seq(pdata, &attrSeq, &attrDataType);	/*	 * Sencond condition checks : 	 * 			SDP Header: PDU ID (1 byte) + Transaction ID (2 bytes) + Parameter Length (2 bytes)	 * 			+	 * 			Parameter 1: service record handle (4 bytes)	 * 			+	 * 			Parameter 2: maximum attribute byte count (2 bytes)	 *			+	 *			Paramenter 3: Attribute ID list (variable length) 	 *			+	 *			Paramenter 4: Continuation State (1 byte) (We suppose the minimum continuation state size here)	 *				 *			bigger than (>)	 *				 *			Parameter Length value.	 */	if ((bytesScanned < 0) || ((sizeof(sdp_hdr_t) + sizeof(uint32_t) + sizeof(uint16_t) + bytesScanned+ sizeof(uint8_t)) > requestPdu->len)){ 		status = SDP_ERR_REQUEST_SYNTAX;		goto exit;	}	pdata += bytesScanned;	/*	 ** Check if continuation state exists, if yes attempt	 ** to get response remainder from cache, else send error	 */	pCState = sdp_get_cstate(pdata);	if ((pCState) && ((pCState->length + bytesScanned + sizeof(sdp_hdr_t) + sizeof(uint32_t) + sizeof(uint16_t)) > requestPdu->len)){		status = SDP_ERR_REQUEST_SYNTAX;		goto exit;	}		DBPRT("SvcRecHandle : 0x%x", svcRecHandle);	DBPRT("maxResponseSize : %d", maxResponseSize);	maxResponseSize = btmin(maxResponseSize,			(requestPdu->mtu-sizeof(sdp_hdr_t)-sizeof(uint16_t)-sizeof(sdp_cstate_t)));	/*	 * pull header for AttributeList byte count	 */	pdu->data += sizeof(uint16_t);	pdu->size -= sizeof(uint16_t);	if (pCState) {		sdppdu_t *pCache = NULL;		short bytesSent = 0;		pCache = sdp_get_rsp_cscache(requestPdu->fd, pCState);		DBPRT("Obtained cached response : %p", pCache);		if (pCache != NULL) {			pResponse = pCache->data;			bytesSent = btmin(maxResponseSize, 					(pCache->length - pCState->value.maxBytesSent));			memcpy(pdu->data, (pResponse + pCState->value.maxBytesSent), 					bytesSent);			pdu->length += bytesSent;			pCState->value.maxBytesSent += bytesSent;			DBPRT("Response size : %d sending now : %d bytes sent so far : %d", 					pCache->length, bytesSent, pCState->value.maxBytesSent);			if (pCState->value.maxBytesSent == pCache->length) {				/* remove from cache */				continuationStateSize = sdp_set_cstate(pdu, NULL);				sdp_del_rsp_cscache(requestPdu->fd, pCState);			} else				continuationStateSize = sdp_set_cstate(pdu, pCState);		} else {			status = -1;			BTERROR("NULL cache buffer and non-NULL continuation state");		}	} else {		svcRec = sdp_find_svc(svcRecHandle);		//SDPXXX: is pdata correct ?????		status = sdp_gen_svc_pdu_by_attrs(svcRec, attrSeq, attrDataType, pdu, pdu->size);		//BTINFO("length: %d, max: %d\n", pdu->length, maxResponseSize);		if (pdu->length > maxResponseSize) {			sdp_cstate_t newState;			memset((char *)&newState, 0, sizeof(sdp_cstate_t));			newState.timestamp = sdp_add_rsp_cscache(requestPdu->fd, pdu);			/*			 ** Reset the buffer size to the maximum expected and			 ** set the sdp_cstate_t			 */			DBPRT("Creating continuation state of size : %d", pdu->length);			pdu->length = maxResponseSize;			newState.value.maxBytesSent = maxResponseSize;			continuationStateSize = sdp_set_cstate(pdu, &newState);		} else			continuationStateSize = sdp_set_cstate(pdu, NULL);	}	// push header	pdu->data -= sizeof(uint16_t);	pdu->size += sizeof(uint16_t);	if (status != 0) {		__put_u16(pdu->data, htons(status));		pdu->length = sizeof(uint16_t);	} else {		/*		 * set attribute list byte count		 */		__put_u16(pdu->data, htons(pdu->length - continuationStateSize));		pdu->length += sizeof(uint16_t);	}exit:	if (attrSeq)		s_list_destroy(&attrSeq);	return status;}/* ** The single request for a combined "service search" and ** "attribute extraction" */int _sdp_search_attr_req(sdp_request_t *requestPdu, sdppdu_t *pdu){	int		status = 0;	char		*pdata;	int		bytesScanned = 0, bytesScanned2 = 0;	slist_t		*searchPattern = NULL;	int		maxExpectedAttrSize;	uint8_t		dataType;	sdp_cstate_t	*pCState = NULL;	char		*pResponse = NULL;	short		continuationStateSize = 0;	slist_t		*attrSeq = NULL;	uint8_t		attrDataType = 0;	int		index = 0;	int		responseCount = 0;	sdppdu_t	localPDUForm;	DBPRT("In svc srch attr request");	pdata = requestPdu->data + sizeof(sdp_hdr_t);	bytesScanned = sdp_extr_data_seq(pdata, &searchPattern, &dataType);	DBPRT("Bytes scanned : %d", bytesScanned);	if ((bytesScanned < 0) || ((sizeof(sdp_hdr_t) + bytesScanned + sizeof(uint16_t) + sizeof(uint8_t)) > requestPdu->len)){ 		status = SDP_ERR_REQUEST_SYNTAX;		goto exit;	}		pdata += bytesScanned;	maxExpectedAttrSize = ntohs(__get_u16(pdata));	pdata += sizeof(uint16_t);	DBPRT("Max Attr expected : %d", maxExpectedAttrSize);	/*	 ** Extract the attribute list	 */	bytesScanned2 = sdp_extr_data_seq(pdata, &attrSeq, &attrDataType);	if ((bytesScanned2 < 0) || ((sizeof(sdp_hdr_t) + bytesScanned + sizeof(uint16_t) + bytesScanned2 + sizeof(uint8_t)) > requestPdu->len)){ 		status = SDP_ERR_REQUEST_SYNTAX;		goto exit;	}	pdata += bytesScanned2;		/*	 ** Check if continuation state exists, if yes attempt	 ** to get response remainder from cache, else send error	 */	pCState = sdp_get_cstate(pdata);	//this is my Continuation Information	if ((pCState) && ((pCState->length + bytesScanned + bytesScanned2 + sizeof(sdp_hdr_t) + sizeof(uint16_t)) > requestPdu->len)){		status = SDP_ERR_REQUEST_SYNTAX;		goto exit;	}		localPDUForm.data = malloc(USHRT_MAX);	if (!localPDUForm.data){		status = -1;		goto exit;	}	localPDUForm.length = 0;	localPDUForm.size = USHRT_MAX;	maxExpectedAttrSize = btmin(maxExpectedAttrSize,			(requestPdu->mtu-sizeof(sdp_hdr_t)-sizeof(sdp_cstate_t)-sizeof(uint16_t)));	/*	 * pull header for AttributeList byte count	 */	pdu->data += sizeof(uint16_t);	pdu->size -= sizeof(uint16_t);	if (pCState == NULL) {		/*		 * No Continuation State -> Create New Response		 */		// Litos Fix		int currentlength = pdu->length;		// End litos fix		for (;;) {			void * data;			sdpsvc_t *svcRec;			localPDUForm.length = 0;			memset(localPDUForm.data, 0, USHRT_MAX);			data = s_list_nth_data(serviceList, index);			if (!data)				break;			svcRec = (sdpsvc_t *)data;			if (sdp_match_uuid(searchPattern, svcRec->targetPattern)) {				responseCount++;				status = sdp_gen_svc_pdu_by_attrs(svcRec, attrSeq, attrDataType, 									&localPDUForm, localPDUForm.size);				DBPRT("Response count : %d", responseCount);				DBPRT("Local PDU size : %d", localPDUForm.length);				if (status == -1) {					DBPRT("Extract attr from svc rec returns err");					break;				}				if (pdu->length + localPDUForm.length < pdu->size) {					// to be sure no relocations					sdp_append_pdu(pdu, &localPDUForm);				} else {					BTERROR("Relocation needed");					break;				}				DBPRT("Net PDU size : %d", pdu->length);			}			index++;		}		// Litos fix		if (currentlength == pdu->length){			// Check if the response is empty. If it is then we must return an empty DataSequence !

⌨️ 快捷键说明

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