📄 request.c
字号:
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 + -