📄 client.c
字号:
/* Service Discovery Protocol (SDP) Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>, Stephen Crane <steve.crane@rococosoft.com> Based on original SDP implementation by Nokia Corporation. Copyright (C) 2001,2002 Nokia Corporation. Original author Guruprasad Krishnamurthy <guruprasad.krishnamurthy@nokia.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED.*//* Fixes: Guruprasad Krishnamurthy <guruprasad.krishnamurthy@nokia.com> Manel Guerrero Zapata <manel.guerrero-zapata@nokia.com>*//* * $Id: client.c,v 1.33 2003/05/13 19:11:29 jscrane Exp $ */#include <errno.h>#include <malloc.h>#include "sdp.h"#include "sdp_internal.h"#include "sdp_lib.h"static inline int __find_port(sdp_data_t *seq, int proto){ if (!seq || !seq->next) return 0; if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) { seq = seq->next; switch (seq->dtd) { case SDP_UINT8: return seq->val.uint8; case SDP_UINT16: return seq->val.uint16; } } return 0;}int sdp_get_proto_port(const sdp_list_t *list, int proto){ if (proto != L2CAP_UUID && proto != RFCOMM_UUID) { errno = EINVAL; return -1; } for (; list; list = list->next) { sdp_list_t *p; for (p = list->data; p; p = p->next) { sdp_data_t *seq = (sdp_data_t *) p->data; int port = __find_port(seq, proto); if (port) return port; } } return 0;}sdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto){ for (; list; list = list->next) { sdp_list_t *p; for (p = list->data; p; p = p->next) { sdp_data_t *seq = (sdp_data_t *) p->data; if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) return seq->next; } } return NULL;}int sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap){ sdp_data_t *pdlist, *curr; sdp_list_t *ap = 0; pdlist = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST); if (pdlist == NULL) { errno = ENODATA; return -1; } SDPDBG("AP type : 0%x\n", pdlist->dtd); for (; pdlist; pdlist = pdlist->next) { sdp_list_t *pds = 0; for (curr = pdlist->val.dataseq; curr; curr = curr->next) pds = sdp_list_append(pds, curr->val.dataseq); ap = sdp_list_append(ap, pds); } *pap = ap; return 0;}int sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, sdp_list_t **seqp){ sdp_data_t *sdpdata = sdp_data_get(rec, attr); *seqp = NULL; if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) { sdp_data_t *d; for (d = sdpdata->val.dataseq; d; d = d->next) { uuid_t *u = (uuid_t *)malloc(sizeof(uuid_t)); memset((char *)u, 0, sizeof(uuid_t)); if (d->dtd >= SDP_UUID16 && d->dtd <= SDP_UUID128) { *u = d->val.uuid; *seqp = sdp_list_append(*seqp, u); } else goto fail; } return 0; }fail: sdp_list_free(*seqp, free); errno = EINVAL; return -1;}int sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq){ int status = 0, i, len; void **dtds, **values; uint8_t uuid16 = SDP_UUID16; uint8_t uuid32 = SDP_UUID32; uint8_t uuid128 = SDP_UUID128; sdp_list_t *p; len = sdp_list_len(seq); if (!seq || len == 0) return -1; dtds = (void **)malloc(len * sizeof(void *)); values = (void **)malloc(len * sizeof(void *)); for (p = seq, i = 0; i < len; i++, p = p->next) { uuid_t *uuid = (uuid_t *)p->data; if (uuid) switch (uuid->type) { case SDP_UUID16: dtds[i] = &uuid16; values[i] = &uuid->value.uuid16; break; case SDP_UUID32: dtds[i] = &uuid32; values[i] = &uuid->value.uuid32; break; case SDP_UUID128: dtds[i] = &uuid128; values[i] = &uuid->value.uuid128; break; default: status = -1; break; } else { status = -1; break; } } if (status == 0) { sdp_data_t *data = sdp_seq_alloc(dtds, values, len); sdp_attr_replace(rec, aid, data); sdp_pattern_add_uuidseq(rec, seq); } free(dtds); free(values); return status;}int sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq){ sdp_lang_attr_t *lang; sdp_data_t *sdpdata, *curr_data; *langSeq = NULL; sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST); if (sdpdata == NULL) { errno = ENODATA; return -1; } curr_data = sdpdata->val.dataseq; while (curr_data) { sdp_data_t *pCode = curr_data; sdp_data_t *pEncoding = pCode->next; sdp_data_t *pOffset = pEncoding->next; if (pCode && pEncoding && pOffset) { lang = (sdp_lang_attr_t *)malloc(sizeof(sdp_lang_attr_t)); lang->code_ISO639 = pCode->val.uint16; lang->encoding = pEncoding->val.uint16; lang->base_offset = pOffset->val.uint16; SDPDBG("code_ISO639 : 0x%02x\n", lang->code_ISO639); SDPDBG("encoding : 0x%02x\n", lang->encoding); SDPDBG("base_offfset : 0x%02x\n", lang->base_offset); *langSeq = sdp_list_append(*langSeq, lang); } curr_data = pOffset->next; } return 0;}int sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq){ sdp_profile_desc_t *profDesc; sdp_data_t *sdpdata, *seq; *profDescSeq = NULL; sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST); if (!sdpdata || !sdpdata->val.dataseq) { errno = ENODATA; return -1; } for (seq = sdpdata->val.dataseq; seq && seq->val.dataseq; seq = seq->next) { sdp_data_t *uuid = seq->val.dataseq; sdp_data_t *pVnum = seq->val.dataseq->next; if (uuid && pVnum) { profDesc = (sdp_profile_desc_t *)malloc(sizeof(sdp_profile_desc_t)); profDesc->uuid = uuid->val.uuid; profDesc->version = pVnum->val.uint16;#ifdef SDP_DEBUG sdp_uuid_print(&profDesc->uuid); SDPDBG("Vnum : 0x%04x\n", profDesc->version);#endif *profDescSeq = sdp_list_append(*profDescSeq, profDesc); } } return 0;}int sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16){ sdp_data_t *d, *curr; *u16 = NULL; d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST); if (d == NULL) { errno = ENODATA; return -1; } for (curr = d->val.dataseq; curr; curr = curr->next) *u16 = sdp_list_append(*u16, &curr->val.uint16); return 0;}/* flexible extraction of basic attributes - Jean II *//* How do we expect caller to extract predefined data sequences? */int sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value){ sdp_data_t *sdpdata = sdp_data_get(rec, attrid); if (sdpdata) /* Verify that it is what the caller expects */ if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 || sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 || sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 || sdpdata->dtd == SDP_INT32) { *value = sdpdata->val.uint32; return 0; } errno = EINVAL; return -1;}int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value, int valuelen){ sdp_data_t *sdpdata = sdp_data_get(rec, attrid); if (sdpdata) /* Verify that it is what the caller expects */ if (sdpdata->dtd == SDP_TEXT_STR8 || sdpdata->dtd == SDP_TEXT_STR16 || sdpdata->dtd == SDP_TEXT_STR32) if (strlen(sdpdata->val.str) < valuelen) { strcpy(value, sdpdata->val.str); return 0; } errno = EINVAL; return -1;}#define get_basic_attr(attrID, pAttrValue, fieldName) \ sdp_data_t *data = sdp_data_get(rec, attrID); \ if (data) { \ *pAttrValue = data->val.fieldName; \ return 0; \ } \ errno = EINVAL; \ return -1;int sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid){ get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid);}int sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid){ get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid);}int sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState){ get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32);}int sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail){ get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8);}int sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo){ get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32);}int sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState){ get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -