📄 sdp.c
字号:
static int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata){ sdp_data_t *d; int n = 0; for (d = sdpdata->val.dataseq; d; d = d->next) n += sdp_gen_pdu(buf, d); return n;}int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d){ int pdu_size = 0, data_size = 0; unsigned char *src = NULL, is_seq = 0, is_alt = 0; uint8_t dtd = d->dtd; uint16_t u16; uint32_t u32; uint64_t u64; uint128_t u128; char *seqp = buf->data + buf->data_size; pdu_size = sdp_set_data_type(buf, dtd); switch (dtd) { case SDP_DATA_NIL: break; case SDP_UINT8: src = &d->val.uint8; data_size = sizeof(uint8_t); break; case SDP_UINT16: u16 = htons(d->val.uint16); src = (unsigned char *)&u16; data_size = sizeof(uint16_t); break; case SDP_UINT32: u32 = htonl(d->val.uint32); src = (unsigned char *)&u32; data_size = sizeof(uint32_t); break; case SDP_UINT64: u64 = hton64(d->val.uint64); src = (unsigned char *)&u64; data_size = sizeof(uint64_t); break; case SDP_UINT128: hton128(&d->val.uint128, &u128); src = (unsigned char *)&u128; data_size = sizeof(uint128_t); break; case SDP_INT8: case SDP_BOOL: src = (unsigned char *)&d->val.int8; data_size = sizeof(int8_t); break; case SDP_INT16: u16 = htons(d->val.int16); src = (unsigned char *)&u16; data_size = sizeof(int16_t); break; case SDP_INT32: u32 = htonl(d->val.int32); src = (unsigned char *)&u32; data_size = sizeof(int32_t); break; case SDP_INT64: u64 = hton64(d->val.int64); src = (unsigned char *)&u64; data_size = sizeof(int64_t); break; case SDP_INT128: hton128(&d->val.int128, &u128); src = (unsigned char *)&u128; data_size = sizeof(uint128_t); break; case SDP_TEXT_STR8: case SDP_URL_STR8: case SDP_TEXT_STR16: case SDP_TEXT_STR32: case SDP_URL_STR16: case SDP_URL_STR32: src = (unsigned char *)d->val.str; data_size = strlen(d->val.str); sdp_set_seq_len(seqp, data_size); break; case SDP_SEQ8: case SDP_SEQ16: case SDP_SEQ32: is_seq = 1; data_size = get_data_size(buf, d); sdp_set_seq_len(seqp, data_size); break; case SDP_ALT8: case SDP_ALT16: case SDP_ALT32: is_alt = 1; data_size = get_data_size(buf, d); sdp_set_seq_len(seqp, data_size); break; case SDP_UUID16: u16 = htons(d->val.uuid.value.uuid16); src = (unsigned char *)&u16; data_size = sizeof(uint16_t); break; case SDP_UUID32: u32 = htonl(d->val.uuid.value.uuid32); src = (unsigned char *)&u32; data_size = sizeof(uint32_t); break; case SDP_UUID128: src = (unsigned char *)&d->val.uuid.value.uuid128; data_size = sizeof(uint128_t); break; default: break; } if (!is_seq && !is_alt) { if (src && buf) { memcpy(buf->data + buf->data_size, src, data_size); buf->data_size += data_size; } else if (dtd != SDP_DATA_NIL) SDPDBG("Gen PDU : Cant copy from NULL source or dest\n"); } pdu_size += data_size; return pdu_size;}static void sdp_attr_pdu(void *value, void *udata){ sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value);}int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf){ buf->data = (char *)malloc(SDP_PDU_CHUNK_SIZE); if (buf->data) { buf->buf_size = SDP_PDU_CHUNK_SIZE; buf->data_size = 0; memset(buf->data, 0, buf->buf_size); sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf); return 0; } return -1;}void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d){ sdp_data_t *p = sdp_data_get(rec, attr); if (p) { rec->attrlist = sdp_list_remove(rec->attrlist, p); sdp_data_free(p); } d->attrId = attr; rec->attrlist = sdp_list_insert_sorted(rec->attrlist, (void *)d, sdp_attrid_comp_func);}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 = malloc(n + 1); memset(s, 0, n + 1); memcpy(s, p, n); SDPDBG("Len : %d\n", n); SDPDBG("Str : %s\n", s); d->val.str = s; d->unitSize = n; 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -