From 57724fbcd3afc76acd2c9bc295164b51f865daa8 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 17 Oct 2001 21:22:09 +0000 Subject: [PATCH] hcidump: SDP parser by Ricky Yuen. --- tools/parser/l2cap.c | 4 + tools/parser/parser.h | 1 + tools/parser/sdp.c | 594 ++++++++++++++++++++++++++++++++++++++++++ tools/parser/sdp.h | 158 +++++++++++ 4 files changed, 757 insertions(+) create mode 100644 tools/parser/sdp.c create mode 100644 tools/parser/sdp.h diff --git a/tools/parser/l2cap.c b/tools/parser/l2cap.c index b13990dc1..5a971e846 100644 --- a/tools/parser/l2cap.c +++ b/tools/parser/l2cap.c @@ -345,6 +345,10 @@ static void l2cap_parse(int level, struct frame *frm) printf("L2CAP(d): cid 0x%x len %d [psm %d]\n", cid, dlen, psm); switch (psm) { + case 0x01: + sdp_dump(level+1, frm); + break; + case 0x03: rfcomm_dump(level+1, frm); break; diff --git a/tools/parser/parser.h b/tools/parser/parser.h index 4e1058900..88b5f70c1 100644 --- a/tools/parser/parser.h +++ b/tools/parser/parser.h @@ -52,6 +52,7 @@ void raw_dump(int level, struct frame *frm); void hci_dump(int level, struct frame *frm); void l2cap_dump(int level, struct frame *frm); void rfcomm_dump(int level, struct frame *frm); +void sdp_dump(int level, struct frame *frm); static inline void indent(int level) { diff --git a/tools/parser/sdp.c b/tools/parser/sdp.c new file mode 100644 index 000000000..2268159f0 --- /dev/null +++ b/tools/parser/sdp.c @@ -0,0 +1,594 @@ +/* + HCIDump - HCI packet analyzer + Copyright (C) 2000-2001 Maxim Krasnyansky + + 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. +*/ + +/* + SDP parser. + Copyright (C) 2001 Ricky Yuen +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "parser.h" +#include "sdp.h" + +static inline void print_de(int, struct frame*); + +sdp_siz_idx_lookup_table_t sdp_siz_idx_lookup_table[] = { + { 0, 1 }, /* Size index = 0 */ + { 0, 2 }, /* 1 */ + { 0, 4 }, /* 2 */ + { 0, 8 }, /* 3 */ + { 0, 16 }, /* 4 */ + { 1, 1 }, /* 5 */ + { 1, 2 }, /* 6 */ + { 1, 4 }, /* 7 */ +}; + +sdp_uuid_nam_lookup_table_t sdp_uuid_nam_lookup_table[] = { + { SDP_UUID_SDP, "SDP" }, + { SDP_UUID_UDP, "UDP" }, + { SDP_UUID_RFCOMM, "RFCOMM" }, + { SDP_UUID_TCP, "TCP" }, + { SDP_UUID_TCS_BIN, "TCS-BIN" }, + { SDP_UUID_TCS_AT, "TCS-AT" }, + { SDP_UUID_OBEX, "OBEX" }, + { SDP_UUID_IP, "IP" }, + { SDP_UUID_FTP, "FTP" }, + { SDP_UUID_HTTP, "HTTP" }, + { SDP_UUID_WSP, "WSP" }, + { SDP_UUID_L2CAP, "L2CAP" }, + { SDP_UUID_SERVICE_DISCOVERY_SERVER, "SDServer" }, + { SDP_UUID_BROWSE_GROUP_DESCRIPTOR, "BrwsGrpDesc" }, + { SDP_UUID_PUBLIC_BROWSE_GROUP, "PubBrwsGrp" }, + { SDP_UUID_SERIAL_PORT, "SP" }, + { SDP_UUID_LAN_ACCESS_PPP, "LAN" }, + { SDP_UUID_DIALUP_NETWORKING, "DUN" }, + { SDP_UUID_IR_MC_SYNC, "IRMCSync" }, + { SDP_UUID_OBEX_OBJECT_PUSH, "OBEXObjPush" }, + { SDP_UUID_OBEX_FILE_TRANSFER, "OBEXObjTrnsf" }, + { SDP_UUID_IR_MC_SYNC_COMMAND, "IRMCSyncCmd" }, + { SDP_UUID_HEADSET, "Headset" }, + { SDP_UUID_CORDLESS_TELEPHONY, "CordlessTel" }, + { SDP_UUID_INTERCOM, "Intercom" }, + { SDP_UUID_FAX, "Fax" }, + { SDP_UUID_HEADSET_AUDIO_GATEWAY, "AG" }, + { SDP_UUID_PNP_INFORMATION, "PNPInfo" }, + { SDP_UUID_GENERIC_NETWORKING, "Networking" }, + { SDP_UUID_GENERIC_FILE_TRANSFER, "FileTrnsf" }, + { SDP_UUID_GENERIC_AUDIO, "Audio" }, + { SDP_UUID_GENERIC_TELEPHONY, "Telephony" } +}; + +sdp_attr_id_nam_lookup_table_t sdp_attr_id_nam_lookup_table[] = { + { SDP_ATTR_ID_SERVICE_RECORD_HANDLE, "SrvRecHndl" }, + { SDP_ATTR_ID_SERVICE_CLASS_ID_LIST, "SrvClassIDList" }, + { SDP_ATTR_ID_SERVICE_RECORD_STATE, "SrvRecState" }, + { SDP_ATTR_ID_SERVICE_SERVICE_ID, "SrvID" }, + { SDP_ATTR_ID_PROTOCOL_DESCRIPTOR_LIST, "ProtocolDescList" }, + { SDP_ATTR_ID_BROWSE_GROUP_LIST, "BrwGrpList" }, + { SDP_ATTR_ID_LANGUAGE_BASE_ATTRIBUTE_ID_LIST, "LangBaseAttrIDList" }, + { SDP_ATTR_ID_SERVICE_INFO_TIME_TO_LIVE, "SrvInfoTimeToLive" }, + { SDP_ATTR_ID_SERVICE_AVAILABILITY, "SrvAvail" }, + { SDP_ATTR_ID_BLUETOOTH_PROFILE_DESCRIPTOR_LIST, "BTProfileDescList" }, + { SDP_ATTR_ID_DOCUMENTATION_URL, "DocURL" }, + { SDP_ATTR_ID_CLIENT_EXECUTABLE_URL, "ClientExeURL" }, + { SDP_ATTR_ID_ICON_10, "Icon10" }, + { SDP_ATTR_ID_ICON_URL, "IconURL" }, + { SDP_ATTR_ID_SERVICE_NAME, "SrvName" }, + { SDP_ATTR_ID_SERVICE_DESCRIPTION, "SrvDesc" }, + { SDP_ATTR_ID_PROVIDER_NAME, "ProviderName" }, + { SDP_ATTR_ID_VERSION_NUMBER_LIST, "VersionNumList" }, + { SDP_ATTR_ID_GROUP_ID, "GrpID" }, + { SDP_ATTR_ID_SERVICE_DATABASE_STATE, "SrvDBState" }, + { SDP_ATTR_ID_SERVICE_VERSION, "SrvVersion" } +}; + +static inline __u8 get_u8(struct frame *frm) +{ + __u8 *u8_ptr = frm->ptr; + frm->ptr += 1; + frm->len -= 1; + return *u8_ptr; +} + +static inline __u16 get_u16(struct frame *frm) +{ + __u16 *u16_ptr = frm->ptr; + frm->ptr += 2; + frm->len -= 2; + return ntohs(*u16_ptr); +} + +static inline __u32 get_u32(struct frame *frm) +{ + __u32 *u32_ptr = frm->ptr; + frm->ptr += 4; + frm->len -= 4; + return ntohl(*u32_ptr); +} + + +static inline char* get_uuid_name(int uuid) +{ + int i; + + for (i = 0; i < SDP_UUID_NAM_LOOKUP_TABLE_SIZE; i++) + { + if (sdp_uuid_nam_lookup_table[i].uuid == uuid) + { + return sdp_uuid_nam_lookup_table[i].name; + } + } + + return 0; +} + +static inline char* get_attr_id_name(int attr_id) +{ + int i; + + for (i = 0; i < SDP_ATTR_ID_NAM_LOOKUP_TABLE_SIZE; i++) + { + if (sdp_attr_id_nam_lookup_table[i].attr_id == attr_id) + { + return sdp_attr_id_nam_lookup_table[i].name; + } + } + + return 0; +} + +static inline __u8 parse_de_hdr(struct frame *frm, int* n) +{ + __u8 de_hdr = get_u8(frm); + __u8 de_type = de_hdr >> 3; + __u8 siz_idx = de_hdr & 0x07; + + /* Get the number of bytes */ + if (sdp_siz_idx_lookup_table[siz_idx].addl_bits) { + switch(sdp_siz_idx_lookup_table[siz_idx].num_bytes) { + case 1: + *n = get_u8(frm); break; + case 2: + *n = get_u16(frm); break; + case 4: + *n = get_u32(frm); break; + } + } else { + *n = sdp_siz_idx_lookup_table[siz_idx].num_bytes; + } + + return de_type; +} + +static inline void print_des(__u8 de_type, int level, int n, struct frame *frm) +{ + int len = frm->len; + + while (len - frm->len < n ) { + print_de(level, frm); + } +} + +static inline void print_int(__u8 de_type, int level, int n, struct frame *frm) +{ + __u64 val; + + switch(de_type) { + case SDP_DE_UINT: + printf(" uint"); + break; + case SDP_DE_INT: + printf(" int"); + break; + case SDP_DE_BOOL: + printf(" bool"); + break; + } + + switch(n) { + case 1: /* 8-bit */ + val = get_u8(frm); + break; + case 2: /* 16-bit */ + val = get_u16(frm); + break; + case 4: /* 32-bit */ + val = get_u32(frm); + break; + case 8: /* 64-bit */ + /* Not supported yet */ + val = 0; + break; + default: /* syntax error */ + printf(" err"); + frm->ptr += n; + frm->len -= n; + return; + } + + printf(" 0x%llx", val); +} + +static inline void print_uuid(int n, struct frame *frm) +{ + __u32 uuid = 0; + char* s; + + switch(n) { + case 2: /* 16-bit UUID */ + uuid = get_u16(frm); + break; + case 4: /* 32_bit UUID */ + uuid = get_u32(frm); + break; + case 16: /* 128-bit UUID */ + uuid = get_u32(frm); + frm->ptr += 12; + frm->len -= 12; + break; + default: /* syntax error */ + printf(" *err*"); + frm->ptr += n; + frm->len -= n; + return; + } + + printf(" 0x%x", uuid); + if ((s = get_uuid_name(uuid)) != 0) + { + printf(" (%s)", s); + } +} + +static inline void print_string(int n, struct frame *frm) +{ + char *s; + + printf(" str"); + if ((s = malloc(n + 1))) { + s = frm->ptr; + s[n] = '\0'; + printf(" \"%s\"", s); + } else { + perror("Can't allocate string buffer"); + } + + frm->ptr += n; + frm->len -= n; +} + +static inline void print_de(int level, struct frame *frm) +{ + int n; + __u8 de_type = parse_de_hdr(frm, &n); + + switch(de_type) { + case SDP_DE_NULL: + printf("null"); + break; + case SDP_DE_UINT: + case SDP_DE_INT: + case SDP_DE_BOOL: + print_int(de_type, level, n, frm); + break; + case SDP_DE_UUID: + print_uuid(n, frm); + break; + case SDP_DE_STRING: + print_string(n, frm); + break; + case SDP_DE_SEQ: + case SDP_DE_ALT: + print_des(de_type, ++level, n, frm); + break; + case SDP_DE_URL: + break; + } +} + + +static inline void print_srv_srch_pat(int level, struct frame *frm) +{ + int len = frm->len; + int n1; + int n2; + + indent(level); + printf("pat"); + + if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) { + while (len - frm->len < n1 ) { + if (parse_de_hdr(frm,&n2) == SDP_DE_UUID) { + print_uuid(n2, frm); + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + } + } + printf("\n"); + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + } +} + + +static inline void print_attr_id_list(int level, struct frame *frm) +{ + __u16 attr_id; + __u32 attr_id_range; + int n1; + int n2; + int len = frm->len; + + indent(level); + printf("aid(s)"); + + if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) { + while (len - frm->len < n1 ) { + /* Print AttributeID */ + if (parse_de_hdr(frm, &n2) == SDP_DE_UINT) { + switch(n2) { + case 2: + attr_id = get_u16(frm); + printf(" 0x%x (%s)", attr_id, get_attr_id_name(attr_id)); + break; + case 4: + attr_id_range = get_u32(frm); + printf(" 0x%x--0x%x", + (attr_id_range >> 16), + (attr_id_range & 0x00FF)); + break; + } + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + } + } + printf("\n"); + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + } +} + + +static inline void print_attr_list(int level, struct frame *frm) +{ + __u16 attr_id; + int n1; + int n2; + int len = frm->len; + + if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) { + while (len - frm->len < n1 ) { + /* Print AttributeID */ + if ((parse_de_hdr(frm, &n2) == SDP_DE_UINT) && + (n2 == sizeof(attr_id))) { + attr_id = get_u16(frm); + indent(level); + printf("aid 0x%x (%s)\n", attr_id, get_attr_id_name(attr_id)); + + /* Print AttributeValue */ + indent(++level); + print_de(level, frm); + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + break; + } + } + printf("\n"); + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + } +} + + +static inline void print_attr_lists(int level, struct frame *frm) +{ + int n; + int cnt = 0; + int len = frm->len; + + if (parse_de_hdr(frm, &n) == SDP_DE_SEQ) { + while (len - frm->len < n ) { + indent(level); + printf("srv rec #%d\n", cnt++); + print_attr_list(level+1, frm); + } + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + } +} + + +static inline void err_rsp(int level, __u16 tid, __u16 len, struct frame *frm) +{ + printf("SDP Error Rsp: tid 0x%x len 0x%x\n", tid, len); + + indent(++level); + printf("ec 0x%x info ", get_u16(frm)); + if (frm->len > 0) { + raw_dump(0, frm); + } else { + printf("none\n"); + } +} + + +static inline void ss_req(int level, __u16 tid, __u16 len, struct frame *frm) +{ + printf("SDP SS Req: tid 0x%x len 0x%x\n", tid, len); + + /* Parse ServiceSearchPattern */ + print_srv_srch_pat(++level, frm); + + /* Parse MaximumServiceRecordCount */ + indent(level); + printf("max 0x%x\n", get_u16(frm)); +} + +static inline void ss_rsp(int level, __u16 tid, __u16 len, struct frame *frm) +{ + register int i; + __u16 cur_srv_rec_cnt = get_u16(frm); /* Parse CurrentServiceRecordCount */ + __u16 tot_srv_rec_cnt = get_u16(frm); /* Parse TotalServiceRecordCount */ + + printf("SDP SS Rsp: tid 0x%x len 0x%x\n", tid, len); + + indent(++level); + printf("cur 0x%x tot 0x%x", cur_srv_rec_cnt, tot_srv_rec_cnt); + + /* Parse service record handle(s) */ + if (cur_srv_rec_cnt > 0) { + printf(" hndl"); + for (i = 0; i < cur_srv_rec_cnt; i++) { + printf(" 0x%x", get_u32(frm)); + } + } + printf("\n"); +} + +static inline void sa_req(int level, __u16 tid, __u16 len, struct frame *frm) +{ + printf("SDP SA Req: tid 0x%x len 0x%x\n", tid, len); + + /* Parse ServiceRecordHandle */ + indent(++level); + printf("hndl 0x%x\n", get_u32(frm)); + + /* Parse MaximumAttributeByteCount */ + indent(level); + printf("max 0x%x\n", get_u16(frm)); + + /* Parse ServiceSearchPattern */ + print_attr_id_list(level, frm); +} + +static inline void sa_rsp(int level, __u16 tid, __u16 len, struct frame *frm) +{ + printf("SDP SA Rsp: tid 0x%x len 0x%x\n", tid, len); + + /* Parse AttributeByteCount */ + indent(++level); + printf("cnt 0x%x\n", get_u16(frm)); + + /* Parse AttributeList */ + print_attr_list(level, frm); +} + +static inline void ssa_req(int level, __u16 tid, __u16 len, struct frame *frm) +{ + printf("SDP SSA Req: tid 0x%x len 0x%x\n", tid, len); + + /* Parse ServiceSearchPattern */ + print_srv_srch_pat(++level, frm); + + /* Parse MaximumAttributeByteCount */ + indent(level); + printf("max 0x%x\n", get_u16(frm)); + + /* Parse AttributeList */ + print_attr_id_list(level, frm); +} + +static inline void ssa_rsp(int level, __u16 tid, __u16 len, struct frame *frm) +{ + printf("SDP SSA Rsp: tid 0x%x len 0x%x\n", tid, len); + + /* Parse AttributeByteCount */ + indent(++level); + printf("cnt 0x%x\n", get_u16(frm)); + + /* Parse AttributeLists */ + print_attr_lists(level, frm); +} + +void sdp_dump(int level, struct frame *frm) +{ + sdp_pdu_hdr *hdr = frm->ptr; + __u16 tid = ntohs(hdr->tid); + __u16 len = ntohs(hdr->len); + + frm->ptr += SDP_PDU_HDR_SIZE; + frm->len -= SDP_PDU_HDR_SIZE; + + indent(++level); + + switch(hdr->pid) { + case SDP_ERROR_RSP: + err_rsp(level, tid, len, frm); + break; + case SDP_SERVICE_SEARCH_REQ: + ss_req(level, tid, len, frm); + break; + case SDP_SERVICE_SEARCH_RSP: + ss_rsp(level, tid, len, frm); + break; + case SDP_SERVICE_ATTR_REQ: + sa_req(level, tid, len, frm); + break; + case SDP_SERVICE_ATTR_RSP: + sa_rsp(level, tid, len, frm); + break; + case SDP_SERVICE_SEARCH_ATTR_REQ: + ssa_req(level, tid, len, frm); + break; + case SDP_SERVICE_SEARCH_ATTR_RSP: + ssa_rsp(level, tid, len, frm); + break; + default: + printf("ERROR: Unknown PDU ID: 0x%x\n", hdr->pid); + raw_dump(++level, frm); + return; + } + + if (hdr->pid != SDP_ERROR_RSP) + { + /* Parse ContinuationState */ + if (*(__u8*) frm->ptr) { + indent(++level); + printf("cont "); + raw_dump(0, frm); + } + } +} diff --git a/tools/parser/sdp.h b/tools/parser/sdp.h new file mode 100644 index 000000000..b24011078 --- /dev/null +++ b/tools/parser/sdp.h @@ -0,0 +1,158 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + 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. +*/ + +/* + SDP parser. + Copyright (C) 2001 Ricky Yuen +*/ + +/* + * $Id$ + */ + +#ifndef __SDP_H +#define __SDP_H + +#define SDP_ERROR_RSP 0x01 +#define SDP_SERVICE_SEARCH_REQ 0x02 +#define SDP_SERVICE_SEARCH_RSP 0x03 +#define SDP_SERVICE_ATTR_REQ 0x04 +#define SDP_SERVICE_ATTR_RSP 0x05 +#define SDP_SERVICE_SEARCH_ATTR_REQ 0x06 +#define SDP_SERVICE_SEARCH_ATTR_RSP 0x07 + +/* Bluetooth assigned UUIDs for protocols */ +#define SDP_UUID_SDP 0x0001 +#define SDP_UUID_UDP 0x0002 +#define SDP_UUID_RFCOMM 0x0003 +#define SDP_UUID_TCP 0x0004 +#define SDP_UUID_TCS_BIN 0x0005 +#define SDP_UUID_TCS_AT 0x0006 +#define SDP_UUID_OBEX 0x0008 +#define SDP_UUID_IP 0x0009 +#define SDP_UUID_FTP 0x000A +#define SDP_UUID_HTTP 0x000C +#define SDP_UUID_WSP 0x000E +#define SDP_UUID_L2CAP 0x0100 + +/* Bluetooth assigned UUIDs for Service Classes */ +#define SDP_UUID_SERVICE_DISCOVERY_SERVER 0x1000 +#define SDP_UUID_BROWSE_GROUP_DESCRIPTOR 0x1001 +#define SDP_UUID_PUBLIC_BROWSE_GROUP 0x1002 +#define SDP_UUID_SERIAL_PORT 0x1101 +#define SDP_UUID_LAN_ACCESS_PPP 0x1102 +#define SDP_UUID_DIALUP_NETWORKING 0x1103 +#define SDP_UUID_IR_MC_SYNC 0x1104 +#define SDP_UUID_OBEX_OBJECT_PUSH 0x1105 +#define SDP_UUID_OBEX_FILE_TRANSFER 0x1106 +#define SDP_UUID_IR_MC_SYNC_COMMAND 0x1107 +#define SDP_UUID_HEADSET 0x1108 +#define SDP_UUID_CORDLESS_TELEPHONY 0x1109 +#define SDP_UUID_INTERCOM 0x1110 +#define SDP_UUID_FAX 0x1111 +#define SDP_UUID_HEADSET_AUDIO_GATEWAY 0x1112 +#define SDP_UUID_PNP_INFORMATION 0x1200 +#define SDP_UUID_GENERIC_NETWORKING 0x1201 +#define SDP_UUID_GENERIC_FILE_TRANSFER 0x1202 +#define SDP_UUID_GENERIC_AUDIO 0x1203 +#define SDP_UUID_GENERIC_TELEPHONY 0x1204 + +/* Bluetooth assigned numbers for Attribute IDs */ +#define SDP_ATTR_ID_SERVICE_RECORD_HANDLE 0x0000 +#define SDP_ATTR_ID_SERVICE_CLASS_ID_LIST 0x0001 +#define SDP_ATTR_ID_SERVICE_RECORD_STATE 0x0002 +#define SDP_ATTR_ID_SERVICE_SERVICE_ID 0x0003 +#define SDP_ATTR_ID_PROTOCOL_DESCRIPTOR_LIST 0x0004 +#define SDP_ATTR_ID_BROWSE_GROUP_LIST 0x0005 +#define SDP_ATTR_ID_LANGUAGE_BASE_ATTRIBUTE_ID_LIST 0x0006 +#define SDP_ATTR_ID_SERVICE_INFO_TIME_TO_LIVE 0x0007 +#define SDP_ATTR_ID_SERVICE_AVAILABILITY 0x0008 +#define SDP_ATTR_ID_BLUETOOTH_PROFILE_DESCRIPTOR_LIST 0x0009 +#define SDP_ATTR_ID_DOCUMENTATION_URL 0x000A +#define SDP_ATTR_ID_CLIENT_EXECUTABLE_URL 0x000B +#define SDP_ATTR_ID_ICON_10 0x000C +#define SDP_ATTR_ID_ICON_URL 0x000D +#define SDP_ATTR_ID_SERVICE_NAME 0x0100 +#define SDP_ATTR_ID_SERVICE_DESCRIPTION 0x0101 +#define SDP_ATTR_ID_PROVIDER_NAME 0x0102 +#define SDP_ATTR_ID_VERSION_NUMBER_LIST 0x0200 +#define SDP_ATTR_ID_GROUP_ID 0x0200 +#define SDP_ATTR_ID_SERVICE_DATABASE_STATE 0x0201 +#define SDP_ATTR_ID_SERVICE_VERSION 0x0300 + +#define SDP_ATTR_ID_EXTERNAL_NETWORK 0x0301 /* Cordless Telephony */ +#define SDP_ATTR_ID_SUPPORTED_DATA_STORES_LIST 0x0301 /* Synchronization */ +#define SDP_ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL 0x0302 /* GAP */ +#define SDP_ATTR_ID_SUPPORTED_FORMATS_LIST 0x0303 /* OBEX Object Push */ +#define SDP_ATTR_ID_FAX_CLASS_1_SUPPORT 0x0302 /* Fax */ +#define SDP_ATTR_ID_FAX_CLASS_2_0_SUPPORT 0x0303 +#define SDP_ATTR_ID_FAX_CLASS_2_SUPPORT 0x0304 +#define SDP_ATTR_ID_AUDIO_FEEDBACK_SUPPORT 0x0305 + +/* Data element type descriptor */ +#define SDP_DE_NULL 0 +#define SDP_DE_UINT 1 +#define SDP_DE_INT 2 +#define SDP_DE_UUID 3 +#define SDP_DE_STRING 4 +#define SDP_DE_BOOL 5 +#define SDP_DE_SEQ 6 +#define SDP_DE_ALT 7 +#define SDP_DE_URL 8 + +/* SDP structures */ + +typedef struct { + __u8 pid; + __u16 tid; + __u16 len; +} __attribute__ ((packed)) sdp_pdu_hdr; +#define SDP_PDU_HDR_SIZE 5 + +/* Data element size index lookup table */ +typedef struct { + int addl_bits; + int num_bytes; +} sdp_siz_idx_lookup_table_t; +extern sdp_siz_idx_lookup_table_t sdp_siz_idx_lookup_table[]; + +/* UUID name lookup table */ +typedef struct { + int uuid; + char* name; +} sdp_uuid_nam_lookup_table_t; +extern sdp_uuid_nam_lookup_table_t sdp_uuid_nam_lookup_table[]; +#define SDP_UUID_NAM_LOOKUP_TABLE_SIZE \ + (sizeof(sdp_uuid_nam_lookup_table)/sizeof(sdp_uuid_nam_lookup_table_t)) + +/* AttrID name lookup table */ +typedef struct { + int attr_id; + char* name; +} sdp_attr_id_nam_lookup_table_t; +extern sdp_attr_id_nam_lookup_table_t sdp_attr_id_nam_lookup_table[]; +#define SDP_ATTR_ID_NAM_LOOKUP_TABLE_SIZE \ + (sizeof(sdp_attr_id_nam_lookup_table)/sizeof(sdp_attr_id_nam_lookup_table_t)) + +#endif /* __SDP_H */ -- 2.47.3