📄 des.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: des.c,v 1.39 2003/05/13 19:11:32 jscrane Exp $ */#include <stdio.h>#include <malloc.h>#include "sdp.h"#include "sdp_internal.h"#include "sdp_lib.h"int sdp_attrid_comp_func(const void *key1, const void *key2){ const sdp_data_t *d1 = (const sdp_data_t *)key1; const sdp_data_t *d2 = (const sdp_data_t *)key2; if (d1 && d2) return d1->attrId - d2->attrId; return 0;}static void data_seq_free(sdp_data_t *seq){ sdp_data_t *d = seq->val.dataseq; while (d) { sdp_data_t *next = d->next; sdp_data_free(d); d = next; }}void sdp_data_free(sdp_data_t *d){ switch (d->dtd) { case SDP_SEQ8: case SDP_SEQ16: case SDP_SEQ32: data_seq_free(d); break; case SDP_URL_STR8: case SDP_URL_STR16: case SDP_URL_STR32: case SDP_TEXT_STR8: case SDP_TEXT_STR16: case SDP_TEXT_STR32: free(d->val.str); break; } free(d);}static sdp_data_t *extract_int(const void *p, int *len){ sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); SDPDBG("Extracting integer\n"); memset(d, 0, sizeof(sdp_data_t)); d->dtd = *(uint8_t *)p; p += sizeof(uint8_t); *len += sizeof(uint8_t); switch (d->dtd) { case SDP_DATA_NIL: break; case SDP_BOOL: case SDP_INT8: case SDP_UINT8: *len += sizeof(uint8_t); d->val.uint8 = *(uint8_t *)p; break; case SDP_INT16: case SDP_UINT16: *len += sizeof(uint16_t); d->val.uint16 = ntohs(sdp_get_unaligned((uint16_t *)p)); break; case SDP_INT32: case SDP_UINT32: *len += sizeof(uint32_t); d->val.uint32 = ntohl(sdp_get_unaligned((uint32_t *)p)); break; case SDP_INT64: case SDP_UINT64: *len += sizeof(uint64_t); d->val.uint64 = ntoh64(sdp_get_unaligned((uint64_t *)p)); break; case SDP_INT128: case SDP_UINT128: *len += sizeof(uint128_t); ntoh128((uint128_t *)p, &d->val.uint128); break; default: free(d); d = NULL; } return d;}static sdp_data_t *extract_uuid(const void *p, int *len, sdp_record_t *rec){ sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); SDPDBG("Extracting UUID"); memset(d, 0, sizeof(sdp_data_t)); if (0 > sdp_uuid_extract(p, &d->val.uuid, len)) { free(d); return NULL; } d->dtd = *(uint8_t *)p; sdp_pattern_add_uuid(rec, &d->val.uuid); return d;}/* * Extract strings from the PDU (could be service description and similar info) */static sdp_data_t *extract_str(const void *p, int *len){ char *s; int n; sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); memset(d, 0, sizeof(sdp_data_t)); d->dtd = *(uint8_t *)p; p += sizeof(uint8_t); *len += sizeof(uint8_t); switch (d->dtd) { case SDP_TEXT_STR8: case SDP_URL_STR8: n = *(uint8_t *)p; p += sizeof(uint8_t); *len += sizeof(uint8_t) + n; break; case SDP_TEXT_STR16: case SDP_URL_STR16: n = ntohs(sdp_get_unaligned((uint16_t *)p)); p += sizeof(uint16_t); *len += sizeof(uint16_t) + n; break; default: SDPERR("Sizeof text string > UINT16_MAX\n"); free(d); return 0; } s = (char *)malloc(n + 1); memset(s, 0, n + 1); strncpy(s, p, n); SDPDBG("Len : %d\n", n); SDPDBG("Str : %s\n", s); d->val.str = s; return d;}static sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec){ int seqlen, n = 0; sdp_data_t *curr, *prev; sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); SDPDBG("Extracting SEQ"); memset(d, 0, sizeof(sdp_data_t)); *len = sdp_extract_seqtype(p, &d->dtd, &seqlen); SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen); if (*len == 0) return d; p += *len; curr = prev = NULL; while (n < seqlen) { int attrlen = 0; curr = sdp_extract_attr(p, &attrlen, rec); if (curr == NULL) break; if (prev) prev->next = curr; else d->val.dataseq = curr; prev = curr; p += attrlen; n += attrlen; SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen); } *len += n; return d;}sdp_data_t *sdp_extract_attr(const char *p, int *size, sdp_record_t *rec){ sdp_data_t *elem; int n = 0; uint8_t dtd = *(const uint8_t *)p; SDPDBG("extract_attr: dtd=0x%x", dtd); switch (dtd) { case SDP_DATA_NIL: case SDP_BOOL: case SDP_UINT8: case SDP_UINT16: case SDP_UINT32: case SDP_UINT64: case SDP_UINT128: case SDP_INT8: case SDP_INT16: case SDP_INT32: case SDP_INT64: case SDP_INT128: elem = extract_int(p, &n); break; case SDP_UUID16: case SDP_UUID32: case SDP_UUID128: elem = extract_uuid(p, &n, rec); break; case SDP_TEXT_STR8: case SDP_TEXT_STR16: case SDP_TEXT_STR32: case SDP_URL_STR8: case SDP_URL_STR16: case SDP_URL_STR32: elem = extract_str(p, &n); break; case SDP_SEQ8: case SDP_SEQ16: case SDP_SEQ32: case SDP_ALT8: case SDP_ALT16: case SDP_ALT32: elem = extract_seq(p, &n, rec); break; default: SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd); return NULL; } *size += n; return elem;}#ifdef SDP_DEBUGstatic void attr_print_func(void *value, void *userData){ sdp_data_t *d = (sdp_data_t *)value; SDPDBG("=====================================\n"); SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x\n", d->attrId); SDPDBG("ATTRIBUTE VALUE PTR : 0x%x\n", (uint32_t)value); if (d) sdp_data_print(d); else SDPDBG("NULL value\n"); SDPDBG("=====================================\n");}void sdp_print_service_attr(sdp_list_t *svcAttrList){ sdp_list_foreach(svcAttrList, attr_print_func, NULL);}#endifsdp_record_t *sdp_extract_pdu(const char *buf, int *scanned){ int extracted = 0, seqlen = 0; uint8_t dtd; uint16_t attr; sdp_record_t *rec = sdp_record_alloc(); const char *p = buf; *scanned = sdp_extract_seqtype(buf, &dtd, &seqlen); p += *scanned; rec->attrlist = NULL; while (extracted < seqlen) { int n = sizeof(uint8_t), attrlen = 0; sdp_data_t *data = NULL; SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, extracted); dtd = *(uint8_t *)p; attr = ntohs(sdp_get_unaligned((uint16_t *)(p+n))); n += sizeof(uint16_t); SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr); data = sdp_extract_attr(p+n, &attrlen, rec); SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen); n += attrlen; if (data == NULL) { SDPDBG("Terminating extraction of attributes"); break; } if (attr == SDP_ATTR_RECORD_HANDLE) rec->handle = data->val.uint32; extracted += n; p += n; sdp_attr_replace(rec, attr, data); SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d", seqlen, extracted); }#ifdef SDP_DEBUG SDPDBG("Successful extracting of Svc Rec attributes\n"); sdp_print_service_attr(rec->attrlist);#endif *scanned += seqlen; return rec;}#ifdef SDP_DEBUGstatic void print_dataseq(sdp_data_t *p){ sdp_data_t *d; for (d = p; d; d = d->next) sdp_data_print(d);}#endifvoid sdp_record_print(const sdp_record_t *rec){ sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); if (d) printf("Service Name: %s\n", d->val.str); d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY); if (d) printf("Service Description: %s\n", d->val.str); d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY); if (d) printf("Service Provider: %s\n", d->val.str);}#ifdef SDP_DEBUGvoid sdp_data_print(sdp_data_t *d){ switch (d->dtd) { case SDP_DATA_NIL: SDPDBG("NIL\n"); break; case SDP_BOOL: case SDP_UINT8: case SDP_UINT16: case SDP_UINT32: case SDP_UINT64: case SDP_UINT128: case SDP_INT8: case SDP_INT16: case SDP_INT32: case SDP_INT64: case SDP_INT128: SDPDBG("Integer : 0x%x\n", d->val.uint32); break; case SDP_UUID16: case SDP_UUID32: case SDP_UUID128: SDPDBG("UUID\n"); sdp_uuid_print(&d->val.uuid); break; case SDP_TEXT_STR8: case SDP_TEXT_STR16: case SDP_TEXT_STR32: SDPDBG("Text : %s\n", d->val.str); break; case SDP_URL_STR8: case SDP_URL_STR16: case SDP_URL_STR32: SDPDBG("URL : %s\n", d->val.str); break; case SDP_SEQ8: case SDP_SEQ16: case SDP_SEQ32: print_dataseq(d->val.dataseq); break; case SDP_ALT8: case SDP_ALT16: case SDP_ALT32: SDPDBG("Data Sequence Alternates\n"); print_dataseq(d->val.dataseq); break; }}#endifsdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId){ if (rec->attrlist) { sdp_data_t sdpTemplate; sdp_list_t *p; sdpTemplate.attrId = attrId; p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func); if (p) return (sdp_data_t *)p->data; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -