📄 sdpclt.c
字号:
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; } for (list = sdp_get_seq(attr); list; list = s_list_next(list)) {get: *seq = s_list_data(list); /* seq data element */ if (state) *state = s_list_next(list); return 0; } if (state) *state = NULL; return -1;}int sdp_get_proto_attr(sdpsvc_t *svcRec, void *alt, uuid_t **uuid, void **param, void **state){ sdpdata_t *attr; slist_t *list; if (state && *state) { list = *state; goto get; } if (!alt) { attr = sdp_get_attr(svcRec, SDP_ATTR_PROTO_DESC_LIST); if (!attr) return SDP_ERR_NOT_EXIST; } else { attr = alt; } for (list = sdp_get_seq(attr); list; list = s_list_next(list)) {get: /* * first element - protocol UUID */ *param = sdp_get_seq(s_list_data(list)); if (!*param) continue; *uuid = sdp_get_uuid(s_list_data(*param)); /* next parameters */ *param = s_list_next(*param); if (state) *state = s_list_next(list); return 0; } if (state) *state = NULL; return -1;}int sdp_get_uuid_attr(sdpsvc_t *svcRec, uint16_t attrID, uuid_t **uuid, void **state){ sdpdata_t *data; slist_t *list; if (state && *state) { list = *state; goto get; } data = sdp_get_attr(svcRec, attrID); if (!data) return SDP_ERR_NOT_EXIST; for (list = sdp_get_seq(data); list; list = s_list_next(list)) {get: *uuid = sdp_get_uuid(s_list_data(list)); if (state) *state = s_list_next(list); return 0; } if (state) *state = NULL; return -1;}uuid_t *sdp_get_service_attr(sdpsvc_t *svcRec){ sdpdata_t *data; data = sdp_get_attr(svcRec, SDP_ATTR_SERVICEID); if (!data) return NULL; return sdp_get_uuid(data);}uuid_t *sdp_get_group_attr(sdpsvc_t *svcRec){ sdpdata_t *data; data = sdp_get_attr(svcRec, SDP_ATTR_GROUPID); if (!data) return NULL; return sdp_get_uuid(data);}int sdp_is_group(sdpsvc_t *svcRec){ sdpdata_t *data = sdp_get_attr(svcRec, SDP_ATTR_GROUPID); if (data && (svcRec->serviceRecordHandle != SDP_ATTR_SERVICE_RECORD_HANDLE)) return 1; return 0;}int sdp_get_state_attr(sdpsvc_t *svcRec, uint32_t *state){ sdpdata_t *data; data = sdp_get_attr(svcRec, SDP_ATTR_SERVICE_RECORD_STATE); if (!data) return SDP_ERR_NOT_EXIST; *state = sdp_get_u32(data); return 0;}int sdp_get_availability_attr(sdpsvc_t *svcRec, uint8_t *avail){ sdpdata_t *data; data = sdp_get_attr(svcRec, SDP_ATTR_SERVICE_AVAILABILITY); if (!data) return SDP_ERR_NOT_EXIST; *avail = sdp_get_u8(data); return 0;}int sdp_get_ttl_attr(sdpsvc_t *svcRec, uint32_t *ttl){ sdpdata_t *data; data = sdp_get_attr(svcRec, SDP_ATTR_SERVICE_INFO_TTL); if (!data) return SDP_ERR_NOT_EXIST; *ttl = sdp_get_u32(data); return 0;}int sdp_get_lang_attr(sdpsvc_t *svcRec, slist_t **langSeq){ return 0; }/* * get profile descriptor * * state - store next descriptor ptr */int sdp_get_profile_attr(sdpsvc_t *svcRec, uuid_t **uuid, uint16_t *ver, void **state){ sdpdata_t *attr; slist_t *list, *param; if (state && *state) { list = *state; goto get_desc; } attr = sdp_get_attr(svcRec, SDP_ATTR_PROFILE_DESC_LIST); if (!attr) return SDP_ERR_NOT_EXIST; for (list = sdp_get_seq(attr); list; list = s_list_next(list)) { /* get parameters */get_desc: /* first param - UUID */ param = sdp_get_seq(s_list_data(list)); if (!param) continue; *uuid = sdp_get_uuid(s_list_data(param)); /* next - version */ param = s_list_next(param); if (!param) continue; *ver = sdp_get_u16(s_list_data(param)); if (state) *state = s_list_next(list); return 0; } if (state) *state = NULL; return -1;}int sdp_get_info_attr(sdpsvc_t *svcRec, char **name, char **prov, char **desc){ sdpdata_t *data; if (name) { data = sdp_get_attr(svcRec, SDP_ATTR_SERVICE_NAME_PRIM); if (data) *name = sdp_get_str(data); else *name = NULL; } if (prov) { data = sdp_get_attr(svcRec, SDP_ATTR_PROVIDER_NAME_PRIM); if (data) *prov = sdp_get_str(data); else *prov = NULL; } if (name) { data = sdp_get_attr(svcRec, SDP_ATTR_SERVICE_DESC_PRIM); if (data) *desc = sdp_get_str(data); else *desc = NULL; } return 0;}int sdp_get_url_attr(sdpsvc_t *svcRec, char **doc, char **exec, char **icon){ sdpdata_t *data; if (doc) { data = sdp_get_attr(svcRec, SDP_ATTR_DOC_URL); if (data) *doc = sdp_get_str(data); else *doc = NULL; } if (exec) { data = sdp_get_attr(svcRec, SDP_ATTR_EXEC_URL); if (data) *exec = sdp_get_str(data); else *exec = NULL; } if (icon) { data = sdp_get_attr(svcRec, SDP_ATTR_ICON_URL); if (data) *icon = sdp_get_str(data); else *icon = NULL; } return 0;}/* * SDP server attributes */int sdp_get_dbstate_attr(sdpsvc_t *svcRec, uint32_t *state){ sdpdata_t *data; data = sdp_get_attr(svcRec, SDP_ATTR_SERVICE_DB_STATE); if (!data) return SDP_ERR_NOT_EXIST; *state = sdp_get_u32(data); return 0;}int sdp_get_version_attr(sdpsvc_t *svcRec, uint16_t *ver, void **state){ sdpdata_t *data; slist_t *list; if (state && *state) { list = *state; goto get; } data = sdp_get_attr(svcRec, SDP_ATTR_VERSION_NUMBER_LIST); if (!data) return SDP_ERR_NOT_EXIST; for (list = sdp_get_seq(data); list; list = s_list_next(list)) {get: *ver = sdp_get_u16(s_list_data(list)); if (state) *state = s_list_next(list); return 0; } if (state) *state = NULL; return -1;}/* ------------------------------- new ------------------------ */int sdp_get_rfcomm_port(sdpsvc_t *svcRec){ sdpdata_t *attr, *data; slist_t *alt, *list, *param; uuid_t *uuid; attr = sdp_get_attr(svcRec, SDP_ATTR_PROTO_DESC_LIST); if (!attr) return SDP_ERR_NOT_EXIST; if (sdp_is_seq(attr)) { /* no alt */ alt = NULL; data = attr; goto dlist; } else { /* cycle around alternatives */ for (alt = sdp_get_seq(attr); alt; alt = s_list_next(alt)) { data = s_list_data(alt);dlist: /* cycle around descriptors */ for (list = sdp_get_seq(data); list; list = s_list_next(list)) { /* * first element - protocol UUID */ param = sdp_get_seq(s_list_data(list)); if (!param) continue; uuid = sdp_get_uuid(s_list_data(param)); if (sdp_uuidcmp32(uuid, SDP_UUID_RFCOMM) != 0) continue; /* next param - port */ param = s_list_next(param); if (!param) return -1; return sdp_get_u8(s_list_data(param)); } if (!alt) break; } } return -1;}int sdp_find_uuid(sdpsvc_t *svcRec, uint32_t uuid32){ int status = 0; slist_t *searchPattern = NULL; uuid_t uuid; sdp_val2uuid32(&uuid, uuid32); s_list_append(&searchPattern, &uuid); if (!sdp_match_uuid(searchPattern, svcRec->targetPattern)) status = -1; s_list_free(&searchPattern); return status;}/* some new service functions */uuid_t *s_list_append_uuid16(slist_t **list, uint16_t uuid16){ uuid_t *uuid; uuid = malloc(sizeof(uuid_t)); if (!uuid) return NULL; sdp_val2uuid16(uuid, uuid16); s_list_append(list, uuid); return uuid;}uuid_t *s_list_append_uuid32(slist_t **list, uint32_t uuid32){ uuid_t *uuid; uuid = malloc(sizeof(uuid_t)); if (!uuid) return NULL; sdp_val2uuid32(uuid, uuid32); s_list_append(list, uuid); return uuid;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -