📄 sdpclt.c
字号:
/* ** 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 + -