sdp.c revision e37a3738f92e103e053fe09e48affd25600cc233
1d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky/*
2e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *
3e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  Bluetooth packet analyzer - SDP parser
4e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *
5e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  Copyright (C) 2001-2002  Ricky Yuen <ryuen@qualcomm.com>
6e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  Copyright (C) 2003-2004  Marcel Holtmann <marcel@holtmann.org>
7e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *
8e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *
9e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  This program is free software; you can redistribute it and/or modify
10e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  it under the terms of the GNU General Public License as published by
11e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  the Free Software Foundation; either version 2 of the License, or
12e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  (at your option) any later version.
13e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *
14e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  This program is distributed in the hope that it will be useful,
15e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  GNU General Public License for more details.
18e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *
19e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  You should have received a copy of the GNU General Public License
20e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  along with this program; if not, write to the Free Software
21e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *
23e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *
24e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann *  $Id$
25d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky */
26d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
27d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky#include <stdio.h>
28e918e1383e6e80ba4e4808404999521f984f0b5cMarcel Holtmann#include <errno.h>
29d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky#include <stdlib.h>
30d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky#include <unistd.h>
31d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky#include <string.h>
32d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
33d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky#include <sys/types.h>
34d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky#include <netinet/in.h>
35d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
36d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky#include "parser.h"
37d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky#include "sdp.h"
38d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
39bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmannstatic sdp_siz_idx_lookup_table_t sdp_siz_idx_lookup_table[] = {
40d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ 0, 1  }, /* Size index = 0 */
41d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ 0, 2  }, /*              1 */
42d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ 0, 4  }, /*              2 */
43d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ 0, 8  }, /*              3 */
44d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ 0, 16 }, /*              4 */
45d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ 1, 1  }, /*              5 */
46d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ 1, 2  }, /*              6 */
47d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ 1, 4  }, /*              7 */
48d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky};
49d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
50bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmannstatic sdp_uuid_nam_lookup_table_t sdp_uuid_nam_lookup_table[] = {
51d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_SDP,                      "SDP"          },
52d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_UDP,                      "UDP"          },
53d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_RFCOMM,                   "RFCOMM"       },
54d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_TCP,                      "TCP"          },
55d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_TCS_BIN,                  "TCS-BIN"      },
56d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_TCS_AT,                   "TCS-AT"       },
57d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_OBEX,                     "OBEX"         },
58d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_IP,                       "IP"           },
59d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_FTP,                      "FTP"          },
60d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_HTTP,                     "HTTP"         },
61d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_WSP,                      "WSP"          },
62d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_L2CAP,                    "L2CAP"        },
63fcfd5f0ba79cf3f45cf076bbce92590cab5c043cMarcel Holtmann	{ SDP_UUID_BNEP,                     "BNEP"         }, /* PAN */
64f2bde694d03053d212266485254a1a1c62706667Marcel Holtmann	{ SDP_UUID_HIDP,                     "HIDP"         }, /* HID */
6519688cc886a18e183a2b40f492f3b05497bd9af3Marcel Holtmann	{ SDP_UUID_AVDTP,                    "AVDTP"        }, /* AVDTP */
66f2bde694d03053d212266485254a1a1c62706667Marcel Holtmann	{ SDP_UUID_CMTP,                     "CMTP"         }, /* CIP */
67d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_SERVICE_DISCOVERY_SERVER, "SDServer"     },
68d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_BROWSE_GROUP_DESCRIPTOR,  "BrwsGrpDesc"  },
69d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_PUBLIC_BROWSE_GROUP,      "PubBrwsGrp"   },
70d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_SERIAL_PORT,              "SP"           },
71d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_LAN_ACCESS_PPP,           "LAN"          },
72d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_DIALUP_NETWORKING,        "DUN"          },
73d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_IR_MC_SYNC,               "IRMCSync"     },
74d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_OBEX_OBJECT_PUSH,         "OBEXObjPush"  },
75d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_OBEX_FILE_TRANSFER,       "OBEXObjTrnsf" },
76d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_IR_MC_SYNC_COMMAND,       "IRMCSyncCmd"  },
77d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_HEADSET,                  "Headset"      },
78d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_CORDLESS_TELEPHONY,       "CordlessTel"  },
7919688cc886a18e183a2b40f492f3b05497bd9af3Marcel Holtmann	{ SDP_UUID_AUDIO_SOURCE,             "AudioSource"  }, /* A2DP */
8019688cc886a18e183a2b40f492f3b05497bd9af3Marcel Holtmann	{ SDP_UUID_AUDIO_SINK,               "AudioSink"    }, /* A2DP */
8119688cc886a18e183a2b40f492f3b05497bd9af3Marcel Holtmann	{ SDP_UUID_ADVANCED_AUDIO,           "AdvAudio"     }, /* A2DP */
82d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_INTERCOM,                 "Intercom"     },
83d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_FAX,                      "Fax"          },
84a5bcb10a662048170e72ee8aba8d69a9d70b2618Marcel Holtmann	{ SDP_UUID_HEADSET_AUDIO_GATEWAY,    "Headset AG"   },
854f9e927a637144034294199939f530f269f178e1Marcel Holtmann	{ SDP_UUID_WAP,                      "WAP"          },
864f9e927a637144034294199939f530f269f178e1Marcel Holtmann	{ SDP_UUID_WAP_CLIENT,               "WAP Client"   },
87fcfd5f0ba79cf3f45cf076bbce92590cab5c043cMarcel Holtmann	{ SDP_UUID_PANU,                     "PANU"         }, /* PAN */
88fcfd5f0ba79cf3f45cf076bbce92590cab5c043cMarcel Holtmann	{ SDP_UUID_NAP,                      "NAP"          }, /* PAN */
89fcfd5f0ba79cf3f45cf076bbce92590cab5c043cMarcel Holtmann	{ SDP_UUID_GN,                       "GN"           }, /* PAN */
90e1dbe962b2620b26d9a5ce7f276d801f589fccb1Marcel Holtmann	{ SDP_UUID_IMAGING,                  "Imaging"      }, /* BIP */
91e1dbe962b2620b26d9a5ce7f276d801f589fccb1Marcel Holtmann	{ SDP_UUID_IMAGING_RESPONDER,        "ImagingResp"  }, /* BIP */
92a5bcb10a662048170e72ee8aba8d69a9d70b2618Marcel Holtmann	{ SDP_UUID_HANDSFREE,                "Handsfree"    },
93a5bcb10a662048170e72ee8aba8d69a9d70b2618Marcel Holtmann	{ SDP_UUID_HANDSFREE_AUDIO_GATEWAY,  "Handsfree AG" },
94f2bde694d03053d212266485254a1a1c62706667Marcel Holtmann	{ SDP_UUID_HUMAN_INTERFACE_DEVICE,   "HID"          }, /* HID */
954ffb5baaae429817651ee8a4956272b6b64874ccMarcel Holtmann	{ SDP_UUID_HARDCOPY_CABLE_REPLACE,   "HCRP",        }, /* HCRP */
964ffb5baaae429817651ee8a4956272b6b64874ccMarcel Holtmann	{ SDP_UUID_HCR_PRINT,                "HCRPrint",    }, /* HCRP */
974ffb5baaae429817651ee8a4956272b6b64874ccMarcel Holtmann	{ SDP_UUID_HCR_SCAN,                 "HCRScan",     }, /* HCRP */
98f2bde694d03053d212266485254a1a1c62706667Marcel Holtmann	{ SDP_UUID_COMMON_ISDN_ACCESS,       "CIP"          }, /* CIP */
99a5bcb10a662048170e72ee8aba8d69a9d70b2618Marcel Holtmann	{ SDP_UUID_SIM_ACCESS,               "SAP"          }, /* SAP */
100d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_PNP_INFORMATION,          "PNPInfo"      },
101d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_GENERIC_NETWORKING,       "Networking"   },
102d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_GENERIC_FILE_TRANSFER,    "FileTrnsf"    },
103d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_UUID_GENERIC_AUDIO,            "Audio"        },
10419688cc886a18e183a2b40f492f3b05497bd9af3Marcel Holtmann	{ SDP_UUID_GENERIC_TELEPHONY,        "Telephony"    },
10519688cc886a18e183a2b40f492f3b05497bd9af3Marcel Holtmann	{ SDP_UUID_VIDEO_SOURCE,             "VideoSource"  }, /* VDP */
10619688cc886a18e183a2b40f492f3b05497bd9af3Marcel Holtmann	{ SDP_UUID_VIDEO_SINK,               "VideoSink"    }  /* VDP */
107d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky};
108d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
109bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmannstatic sdp_attr_id_nam_lookup_table_t sdp_attr_id_nam_lookup_table[] = {
110d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_SERVICE_RECORD_HANDLE,             "SrvRecHndl"         },
111d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_SERVICE_CLASS_ID_LIST,             "SrvClassIDList"     },
112d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_SERVICE_RECORD_STATE,              "SrvRecState"        },
113d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_SERVICE_SERVICE_ID,                "SrvID"              },
114d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_PROTOCOL_DESCRIPTOR_LIST,          "ProtocolDescList"   },
115d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_BROWSE_GROUP_LIST,                 "BrwGrpList"         },
116d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_LANGUAGE_BASE_ATTRIBUTE_ID_LIST,   "LangBaseAttrIDList" },
117d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_SERVICE_INFO_TIME_TO_LIVE,         "SrvInfoTimeToLive"  },
118d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_SERVICE_AVAILABILITY,              "SrvAvail"           },
119d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_BLUETOOTH_PROFILE_DESCRIPTOR_LIST, "BTProfileDescList"  },
120d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_DOCUMENTATION_URL,                 "DocURL"             },
121d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_CLIENT_EXECUTABLE_URL,             "ClientExeURL"       },
122d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_ICON_10,                           "Icon10"             },
123d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_ICON_URL,                          "IconURL"            },
124d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_SERVICE_NAME,                      "SrvName"            },
125d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_SERVICE_DESCRIPTION,               "SrvDesc"            },
126d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_PROVIDER_NAME,                     "ProviderName"       },
127d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_VERSION_NUMBER_LIST,               "VersionNumList"     },
128d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_GROUP_ID,                          "GrpID"              },
129d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	{ SDP_ATTR_ID_SERVICE_DATABASE_STATE,            "SrvDBState"         },
1300a7b156a76a997be7f4093f2f16943b5d7ae2bc5Max Krasnyansky	{ SDP_ATTR_ID_SERVICE_VERSION,                   "SrvVersion"         },
131fcfd5f0ba79cf3f45cf076bbce92590cab5c043cMarcel Holtmann	{ SDP_ATTR_ID_SECURITY_DESCRIPTION,              "SecurityDescription"}, /* PAN */
132803752117135528b1adebf0fa045596e188a996dMarcel Holtmann	{ SDP_ATTR_ID_SUPPORTED_DATA_STORES_LIST,        "SuppDataStoresList" }, /* Synchronization */
133803752117135528b1adebf0fa045596e188a996dMarcel Holtmann	{ SDP_ATTR_ID_SUPPORTED_FORMATS_LIST,            "SuppFormatsList"    }, /* OBEX Object Push */
134fcfd5f0ba79cf3f45cf076bbce92590cab5c043cMarcel Holtmann	{ SDP_ATTR_ID_NET_ACCESS_TYPE,                   "NetAccessType"      }, /* PAN */
135fcfd5f0ba79cf3f45cf076bbce92590cab5c043cMarcel Holtmann	{ SDP_ATTR_ID_MAX_NET_ACCESS_RATE,               "MaxNetAccessRate"   }, /* PAN */
136fcfd5f0ba79cf3f45cf076bbce92590cab5c043cMarcel Holtmann	{ SDP_ATTR_ID_IPV4_SUBNET,                       "IPv4Subnet"         }, /* PAN */
137fcfd5f0ba79cf3f45cf076bbce92590cab5c043cMarcel Holtmann	{ SDP_ATTR_ID_IPV6_SUBNET,                       "IPv6Subnet"         }  /* PAN */
138d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky};
139d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
1403f4bfd3f26aafca84ea9eb31f0128846f7e44c71Max Krasnyanskychar* get_uuid_name(int uuid)
141d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
142d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	int i;
143d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
1443f4bfd3f26aafca84ea9eb31f0128846f7e44c71Max Krasnyansky	for (i = 0; i < SDP_UUID_NAM_LOOKUP_TABLE_SIZE; i++) {
145d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		if (sdp_uuid_nam_lookup_table[i].uuid == uuid)
146d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			return sdp_uuid_nam_lookup_table[i].name;
147d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	}
148d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
149d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	return 0;
150d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
151d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
152d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyanskystatic inline char* get_attr_id_name(int attr_id)
153d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
154d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	int i;
155d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
156d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	for (i = 0; i < SDP_ATTR_ID_NAM_LOOKUP_TABLE_SIZE; i++)
157d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		if (sdp_attr_id_nam_lookup_table[i].attr_id == attr_id)
158d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			return sdp_attr_id_nam_lookup_table[i].name;
159d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	return 0;
160d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
161d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
162bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmannstatic inline uint8_t parse_de_hdr(struct frame *frm, int *n)
163d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
164bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann	uint8_t de_hdr = get_u8(frm);
165bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann	uint8_t de_type = de_hdr >> 3;
166bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann	uint8_t siz_idx = de_hdr & 0x07;
167d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
168d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	/* Get the number of bytes */
169d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	if (sdp_siz_idx_lookup_table[siz_idx].addl_bits) {
170d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		switch(sdp_siz_idx_lookup_table[siz_idx].num_bytes) {
171d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		case 1:
172d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			*n = get_u8(frm); break;
173d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		case 2:
174d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			*n = get_u16(frm); break;
175d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		case 4:
176d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			*n = get_u32(frm); break;
17764e42538f1acba75c4a8bae67ee1a39e2c854134Stephen Crane		case 8:
17864e42538f1acba75c4a8bae67ee1a39e2c854134Stephen Crane			*n = get_u64(frm); break;
179d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		}
180e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	} else
181d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		*n = sdp_siz_idx_lookup_table[siz_idx].num_bytes;
182d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
183d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	return de_type;
184d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
185d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
1860149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmannstatic inline void print_int(uint8_t de_type, int level, int n, struct frame *frm, uint16_t *psm, uint8_t *channel)
187d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
1880d93444945039e6acf74a874053d07fb0114fee7Marcel Holtmann	uint64_t val, val2;
189d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
190d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	switch(de_type) {
191d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_DE_UINT:
192d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf(" uint");
193d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
194d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_DE_INT:
195d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf(" int");
196d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
197d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_DE_BOOL:
198d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf(" bool");
199d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
200d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	}
201d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
202d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	switch(n) {
203d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case 1: /* 8-bit */
204d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		val = get_u8(frm);
2050149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann		if (channel && de_type == SDP_DE_UINT)
2060149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann			if (*channel == 0)
2070149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann				*channel = val;
208d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
209d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case 2: /* 16-bit */
210d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		val = get_u16(frm);
211bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann		if (psm && de_type == SDP_DE_UINT)
212bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann			if (*psm == 0)
213bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann				*psm = val;
214d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
215d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case 4: /* 32-bit */
216d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		val = get_u32(frm);
217d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
218d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case 8: /* 64-bit */
21964e42538f1acba75c4a8bae67ee1a39e2c854134Stephen Crane		val = get_u64(frm);
220d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
22164e42538f1acba75c4a8bae67ee1a39e2c854134Stephen Crane	case 16:/* 128-bit */
22264e42538f1acba75c4a8bae67ee1a39e2c854134Stephen Crane		get_u128(frm, &val, &val2);
2231a4905db6e78b27cdb341691c9b30112b2b5056eStephen Crane		printf(" 0x%llx", val2);
224fab8d4bbda673187de603df5ed39cdf0c9635a9dMarcel Holtmann		if (val < 0x1000000000000000LL)
2251a4905db6e78b27cdb341691c9b30112b2b5056eStephen Crane			printf("0");
2261a4905db6e78b27cdb341691c9b30112b2b5056eStephen Crane		printf("%llx", val);
22764e42538f1acba75c4a8bae67ee1a39e2c854134Stephen Crane		return;
228d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	default: /* syntax error */
229d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf(" err");
230d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		frm->ptr += n;
231d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		frm->len -= n;
232d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		return;
233d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	}
234d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
235d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	printf(" 0x%llx", val);
236d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
237d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
2380149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmannstatic inline void print_uuid(int n, struct frame *frm, uint16_t *psm, uint8_t *channel)
239d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
2400d93444945039e6acf74a874053d07fb0114fee7Marcel Holtmann	uint32_t uuid = 0;
241d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	char* s;
24284d27e7d443952fee20f86ab528c1aa9d6aaff87Marcel Holtmann	int i;
243d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
244d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	switch(n) {
245d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case 2: /* 16-bit UUID */
246d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		uuid = get_u16(frm);
247b17b30c75d9615835074d28c1072a1f694df51dfStephen Crane		s = "uuid-16";
248d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
249d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case 4: /* 32_bit UUID */
250d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		uuid = get_u32(frm);
251b17b30c75d9615835074d28c1072a1f694df51dfStephen Crane		s = "uuid-32";
252d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
253d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case 16: /* 128-bit UUID */
25484d27e7d443952fee20f86ab528c1aa9d6aaff87Marcel Holtmann		printf(" uuid-128 ");
25584d27e7d443952fee20f86ab528c1aa9d6aaff87Marcel Holtmann		for (i = 0; i < 16; i++) {
25684d27e7d443952fee20f86ab528c1aa9d6aaff87Marcel Holtmann			printf("%02x", ((unsigned char *) frm->ptr)[i]);
25784d27e7d443952fee20f86ab528c1aa9d6aaff87Marcel Holtmann			if (i == 3 || i == 5 || i == 7 || i == 9)
25884d27e7d443952fee20f86ab528c1aa9d6aaff87Marcel Holtmann				printf("-");
25984d27e7d443952fee20f86ab528c1aa9d6aaff87Marcel Holtmann		}
26084d27e7d443952fee20f86ab528c1aa9d6aaff87Marcel Holtmann		frm->ptr += 16;
26184d27e7d443952fee20f86ab528c1aa9d6aaff87Marcel Holtmann		frm->len -= 16;
26284d27e7d443952fee20f86ab528c1aa9d6aaff87Marcel Holtmann		return;
263d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	default: /* syntax error */
264d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf(" *err*");
265d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		frm->ptr += n;
266d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		frm->len -= n;
267d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		return;
268d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	}
269d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
270bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann	if (psm && *psm > 0 && *psm != 0xffff) {
2710149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann		set_proto(frm->handle, *psm, 0, uuid);
272bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann		*psm = 0xffff;
273bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann	}
274bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann
2750149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann	if (channel && *channel > 0 && *channel != 0xff) {
2760149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann		set_proto(frm->handle, *psm, *channel, uuid);
2770149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann		*channel = 0xff;
2780149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann	}
2790149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann
280b17b30c75d9615835074d28c1072a1f694df51dfStephen Crane	printf(" %s 0x%04x", s, uuid);
281b17b30c75d9615835074d28c1072a1f694df51dfStephen Crane	if ((s = get_uuid_name(uuid)))
282d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf(" (%s)", s);
283d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
284d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
28564e42538f1acba75c4a8bae67ee1a39e2c854134Stephen Cranestatic inline void print_string(int n, struct frame *frm, const char *name)
286d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
287e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky	char *s;
288d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
28964e42538f1acba75c4a8bae67ee1a39e2c854134Stephen Crane	printf(" %s", name);
290d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	if ((s = malloc(n + 1))) {
291bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann		strncpy(s, frm->ptr, n);
292d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		s[n] = '\0';
293d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf(" \"%s\"", s);
2940a7b156a76a997be7f4093f2f16943b5d7ae2bc5Max Krasnyansky		free(s);
295e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	} else
296d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		perror("Can't allocate string buffer");
297e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
298d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	frm->ptr += n;
299d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	frm->len -= n;
300d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
301d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
3020149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmannstatic inline void print_de(int, struct frame *frm, int *split, uint16_t *psm, uint8_t *channel);
303bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann
3040149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmannstatic inline void print_des(uint8_t de_type, int level, int n, struct frame *frm, int *split, uint16_t *psm, uint8_t *channel)
305e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky{
306e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky	int len = frm->len;
307bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann	while (len - frm->len < n && frm->len > 0)
3080149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann		print_de(level, frm, split, psm, channel);
309e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky}
310e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky
3110149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmannstatic inline void print_de(int level, struct frame *frm, int *split, uint16_t *psm, uint8_t *channel)
312d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
313bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann	int n;
3140d93444945039e6acf74a874053d07fb0114fee7Marcel Holtmann	uint8_t de_type = parse_de_hdr(frm, &n);
315d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
316bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann	switch (de_type) {
317d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_DE_NULL:
31883c0a2aa92e9e419cd952006f891afb4cd79f43eStephen Crane		printf(" null");
319d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
320d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_DE_UINT:
321d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_DE_INT:
322d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_DE_BOOL:
3230149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann		print_int(de_type, level, n, frm, psm, channel);
324d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
325d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_DE_UUID:
326e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky		if (split) {
327e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky			/* Split output by uuids.
328e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky			 * Used for printing Protocol Desc List */
329bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann			if (*split) {
330e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky				printf("\n");
331e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky				p_indent(level, NULL);
332e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky			}
333e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky			++*split;
334e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky		}
3350149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann		print_uuid(n, frm, psm, channel);
336d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
33764e42538f1acba75c4a8bae67ee1a39e2c854134Stephen Crane	case SDP_DE_URL:
338d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_DE_STRING:
33964e42538f1acba75c4a8bae67ee1a39e2c854134Stephen Crane		print_string(n, frm, de_type == SDP_DE_URL? "url": "str");
340d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
341d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_DE_SEQ:
34283c0a2aa92e9e419cd952006f891afb4cd79f43eStephen Crane		printf(" <");
3430149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann		print_des(de_type, level, n, frm, split, psm, channel);
34483c0a2aa92e9e419cd952006f891afb4cd79f43eStephen Crane		printf(" >");
34583c0a2aa92e9e419cd952006f891afb4cd79f43eStephen Crane		break;
346d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_DE_ALT:
34783c0a2aa92e9e419cd952006f891afb4cd79f43eStephen Crane		printf(" [");
3480149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann		print_des(de_type, level, n, frm, split, psm, channel);
34983c0a2aa92e9e419cd952006f891afb4cd79f43eStephen Crane		printf(" ]");
350d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
351d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	}
352d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
353d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
354d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyanskystatic inline void print_srv_srch_pat(int level, struct frame *frm)
355d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
356eb7774e40e1e137b31b8f4cb1b6e17ccd64fad8aMarcel Holtmann	int len, n1, n2;
357d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
358ac107582bff10f3b4c80b2f158ec4281476c2b2fMax Krasnyansky	p_indent(level, frm);
359d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	printf("pat");
360d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
361d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) {
362bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann		len = frm->len;
363eb7774e40e1e137b31b8f4cb1b6e17ccd64fad8aMarcel Holtmann		while (len - frm->len < n1 && frm->len > 0) {
364d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			if (parse_de_hdr(frm,&n2) == SDP_DE_UUID) {
3650149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann				print_uuid(n2, frm, NULL, NULL);
366d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			} else {
3671362b7f4b6b7c3e61e9b7f084d52c98da4f7f227Max Krasnyansky				printf("\nERROR: Unexpected syntax (UUID)\n");
368d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				raw_dump(level, frm);
369d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			}
370d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		}
371d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf("\n");
372d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	} else {
3731362b7f4b6b7c3e61e9b7f084d52c98da4f7f227Max Krasnyansky		printf("\nERROR: Unexpected syntax (SEQ)\n");
374d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		raw_dump(level, frm);
375d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	}
376d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
377d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
378d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyanskystatic inline void print_attr_id_list(int level, struct frame *frm)
379d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
3800d93444945039e6acf74a874053d07fb0114fee7Marcel Holtmann	uint16_t attr_id;
3810d93444945039e6acf74a874053d07fb0114fee7Marcel Holtmann	uint32_t attr_id_range;
382eb7774e40e1e137b31b8f4cb1b6e17ccd64fad8aMarcel Holtmann	int len, n1, n2;
383d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
384ac107582bff10f3b4c80b2f158ec4281476c2b2fMax Krasnyansky	p_indent(level, frm);
385d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	printf("aid(s)");
386d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
387d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) {
388bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann		len = frm->len;
389eb7774e40e1e137b31b8f4cb1b6e17ccd64fad8aMarcel Holtmann		while (len - frm->len < n1 && frm->len > 0) {
390d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			/* Print AttributeID */
391d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			if (parse_de_hdr(frm, &n2) == SDP_DE_UINT) {
3929bb66ea99724230c43776d960ebcf634aea42e61Stephen Crane				char *name;
393d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				switch(n2) {
394d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				case 2:
395d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky					attr_id = get_u16(frm);
3969bb66ea99724230c43776d960ebcf634aea42e61Stephen Crane					name = get_attr_id_name(attr_id);
3979bb66ea99724230c43776d960ebcf634aea42e61Stephen Crane					if (!name)
3989bb66ea99724230c43776d960ebcf634aea42e61Stephen Crane						name = "unknown";
3999bb66ea99724230c43776d960ebcf634aea42e61Stephen Crane					printf(" 0x%04x (%s)", attr_id, name);
400d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky					break;
401d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				case 4:
402d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky					attr_id_range = get_u32(frm);
403c166a7a08bf511a0eec4712811f8342a17d6ccc3Takashi Sasai					printf(" 0x%04x - 0x%04x",
404d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky							(attr_id_range >> 16),
405d467427f3634db7678a6d8e9ff1aecd1b76f66c3Max Krasnyansky							(attr_id_range & 0xFFFF));
406d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky					break;
407d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				}
408d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			} else {
409d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				printf("\nERROR: Unexpected syntax\n");
410d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				raw_dump(level, frm);
411d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			}
412d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		}
413d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf("\n");
414d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	} else {
415d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf("\nERROR: Unexpected syntax\n");
416d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		raw_dump(level, frm);
417d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	}
418d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
419d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
420d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyanskystatic inline void print_attr_list(int level, struct frame *frm)
421d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
422bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann	uint16_t attr_id, psm;
4230149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann	uint8_t channel;
424eb7774e40e1e137b31b8f4cb1b6e17ccd64fad8aMarcel Holtmann	int len, n1, n2, split;
425d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
426d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) {
427bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann		len = frm->len;
428eb7774e40e1e137b31b8f4cb1b6e17ccd64fad8aMarcel Holtmann		while (len - frm->len < n1 && frm->len > 0) {
429d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			/* Print AttributeID */
4309bb66ea99724230c43776d960ebcf634aea42e61Stephen Crane			if (parse_de_hdr(frm, &n2) == SDP_DE_UINT && n2 == sizeof(attr_id)) {
431b17b30c75d9615835074d28c1072a1f694df51dfStephen Crane				char *name;
432d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				attr_id = get_u16(frm);
43365eccecf5c288b7b1bc8bf985fa59d3dd4ce0cfbMax Krasnyansky				p_indent(level, 0);
434b17b30c75d9615835074d28c1072a1f694df51dfStephen Crane				name = get_attr_id_name(attr_id);
435b17b30c75d9615835074d28c1072a1f694df51dfStephen Crane				if (!name)
436b17b30c75d9615835074d28c1072a1f694df51dfStephen Crane					name = "unknown";
437b17b30c75d9615835074d28c1072a1f694df51dfStephen Crane				printf("aid 0x%04x (%s)\n", attr_id, name);
4389bb66ea99724230c43776d960ebcf634aea42e61Stephen Crane				split = (attr_id != SDP_ATTR_ID_PROTOCOL_DESCRIPTOR_LIST);
439bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann				psm = 0;
4400149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann				channel = 0;
441bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann
442d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				/* Print AttributeValue */
443e2ecd2340182074db66ad360283ce0fd609e6a3eMax Krasnyansky				p_indent(level + 1, 0);
444bf336caaf4d6f967474d46cb768e6edc17cc5777Marcel Holtmann				print_de(level + 1, frm, split ? NULL: &split,
4450149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann					attr_id == SDP_ATTR_ID_PROTOCOL_DESCRIPTOR_LIST ? &psm : NULL,
4460149ab32c9391faed284ec6214950ccf70d699cbMarcel Holtmann					attr_id == SDP_ATTR_ID_PROTOCOL_DESCRIPTOR_LIST ? &channel : NULL);
4470a7b156a76a997be7f4093f2f16943b5d7ae2bc5Max Krasnyansky				printf("\n");
448d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			} else {
449d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				printf("\nERROR: Unexpected syntax\n");
450d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				raw_dump(level, frm);
451d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky				break;
452d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky			}
453d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		}
454d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	} else {
455d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf("\nERROR: Unexpected syntax\n");
456d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		raw_dump(level, frm);
457d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	}
458d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
459d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
460e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmannstatic inline void print_attr_lists(int level, struct frame *frm)
461d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
462eb7774e40e1e137b31b8f4cb1b6e17ccd64fad8aMarcel Holtmann	int n, cnt = 0;
463e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	int count = frm->len;
464d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
465d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	if (parse_de_hdr(frm, &n) == SDP_DE_SEQ) {
466e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		while (count - frm->len < n && frm->len > 0) {
46765eccecf5c288b7b1bc8bf985fa59d3dd4ce0cfbMax Krasnyansky			p_indent(level, 0);
468e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			printf("record #%d\n", cnt++);
469e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			print_attr_list(level + 2, frm);
470d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		}
471d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	} else {
472d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		printf("\nERROR: Unexpected syntax\n");
473d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		raw_dump(level, frm);
474d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	}
475d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
476d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
477e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmannstatic inline void print_cont_state(int level, unsigned char *buf)
478d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
479e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	uint8_t cont = buf[0];
480e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	int i;
481d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
48265eccecf5c288b7b1bc8bf985fa59d3dd4ce0cfbMax Krasnyansky	p_indent(level, 0);
483e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	printf("cont");
484e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	for (i = 0; i < cont + 1; i++)
485e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		printf(" %2.2X", buf[i]);
486e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	printf("\n");
487d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
488d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
489e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmannstatic char *pid2str(uint8_t pid)
490d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
491e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	switch (pid) {
492e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	case SDP_ERROR_RSP:
493e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		return "Error Rsp";
494e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	case SDP_SERVICE_SEARCH_REQ:
495e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		return "SS Req";
496e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	case SDP_SERVICE_SEARCH_RSP:
497e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		return "SS Rsp";
498e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	case SDP_SERVICE_ATTR_REQ:
499e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		return "SA Req";
500e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	case SDP_SERVICE_ATTR_RSP:
501e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		return "SA Rsp";
502e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	case SDP_SERVICE_SEARCH_ATTR_REQ:
503e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		return "SSA Req";
504e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	case SDP_SERVICE_SEARCH_ATTR_RSP:
505e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		return "SSA Rsp";
506e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	default:
507e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		return "Unknown";
508e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	}
509e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann}
510d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
511e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann#define FRAME_TABLE_SIZE 10
512d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
513e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmannstatic struct frame frame_table[FRAME_TABLE_SIZE];
514d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
515e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmannstatic int add_frame(struct frame *frm, int count)
516e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann{
517e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	register struct frame *fr;
518e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	register unsigned char *data;
519e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	register int i, len = 0, pos = -1;
520e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
521e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	for (i = 0; i < FRAME_TABLE_SIZE; i++) {
522e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		if (frame_table[i].handle == frm->handle &&
523e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann				frame_table[i].cid == frm->cid) {
524e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			pos = i;
525e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			len = frame_table[i].data_len;
526e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			break;
527d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		}
528e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		if (pos < 0 && !frame_table[i].handle)
529e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			pos = i;
530d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	}
531d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
532e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	if (pos < 0 || count <= 0)
533e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		return -EIO;
534d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
535e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	data = malloc(len + count);
536e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	if (!data)
537e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		return -ENOMEM;
538d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
539e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	fr = &frame_table[pos];
540d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
541e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	if (len > 0) {
542e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		memcpy(data, fr->data, len);
543e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		memcpy(data + len, frm->ptr, count);
544e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	} else
545e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		memcpy(data, frm->ptr, count);
546d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
547e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	if (fr->data)
548e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		free(fr->data);
549d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
550e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	fr->data = data;
551e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	fr->data_len = len + count;
552e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	fr->len = fr->data_len;
553e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	fr->ptr = fr->data;
554e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	fr->in  = frm->in;
555e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	fr->ts  = frm->ts;
556e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	fr->handle  = frm->handle;
557e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	fr->cid     = frm->cid;
558e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	fr->num     = frm->num;
559e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	fr->channel = frm->channel;
560d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
561e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	return pos;
562d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
563d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
564e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmannstatic struct frame *get_frame(struct frame *frm, int count)
565d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
566e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	register int pos;
567d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
568e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	pos = add_frame(frm, count);
569e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	if (pos < 0)
570e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		return frm;
571d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
572e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	frame_table[pos].handle = 0;
573d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
574e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	return &frame_table[pos];
575d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
576d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
577d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyanskyvoid sdp_dump(int level, struct frame *frm)
578d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky{
579d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	sdp_pdu_hdr *hdr = frm->ptr;
580e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	uint16_t tid = ntohs(hdr->tid);
5810d93444945039e6acf74a874053d07fb0114fee7Marcel Holtmann	uint16_t len = ntohs(hdr->len);
582e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	uint16_t total, count;
583e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	uint8_t cont;
584d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
585d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	frm->ptr += SDP_PDU_HDR_SIZE;
586d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	frm->len -= SDP_PDU_HDR_SIZE;
587d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
588ac107582bff10f3b4c80b2f158ec4281476c2b2fMax Krasnyansky	p_indent(level, frm);
589e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	printf("SDP %s: tid 0x%x len 0x%x\n", pid2str(hdr->pid), tid, len);
590d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
5911362b7f4b6b7c3e61e9b7f084d52c98da4f7f227Max Krasnyansky	switch (hdr->pid) {
592d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_ERROR_RSP:
593e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		p_indent(level + 1, frm);
594e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		printf("code 0x%x info ", get_u16(frm));
595e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		if (frm->len > 0)
596e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			hex_dump(0, frm, frm->len);
597e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		else
598e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			printf("none\n");
599d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
600e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
601d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_SERVICE_SEARCH_REQ:
602e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse ServiceSearchPattern */
603e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		print_srv_srch_pat(level + 1, frm);
604e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
605e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse MaximumServiceRecordCount */
606e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		p_indent(level + 1, frm);
607e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		printf("max %d\n", get_u16(frm));
608e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
609e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse ContinuationState */
610e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		print_cont_state(level + 1, frm->ptr);
611d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
612e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
613d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_SERVICE_SEARCH_RSP:
614e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse TotalServiceRecordCount */
615e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		total = get_u16(frm);
616e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
617e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse CurrentServiceRecordCount */
618e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		count = get_u16(frm);
619e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		p_indent(level + 1, frm);
620e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		if (count < total)
621e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			printf("count %d of %d\n", count, total);
622e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		else
623e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			printf("count %d\n", count);
624e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
625e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse service record handle(s) */
626e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		if (count > 0) {
627e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			int i;
628e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			p_indent(level + 1, frm);
629e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			printf("handle%s", count > 1 ? "s" : "");
630e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			for (i = 0; i < count; i++)
631e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann				printf(" 0x%x", get_u32(frm));
632e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			printf("\n");
633e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		}
634e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
635e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse ContinuationState */
636e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		print_cont_state(level + 1, frm->ptr);
637d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
638e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
639d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_SERVICE_ATTR_REQ:
640e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse ServiceRecordHandle */
641e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		p_indent(level + 1, frm);
642e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		printf("handle 0x%x\n", get_u32(frm));
643e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
644e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse MaximumAttributeByteCount */
645e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		p_indent(level + 1, frm);
646e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		printf("max %d\n", get_u16(frm));
647e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
648e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse ServiceSearchPattern */
649e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		print_attr_id_list(level + 1, frm);
650e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
651e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse ContinuationState */
652e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		print_cont_state(level + 1, frm->ptr);
653d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
654e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
655d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_SERVICE_ATTR_RSP:
656e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse AttributeByteCount */
657e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		count = get_u16(frm);
658e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		p_indent(level + 1, frm);
659e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		printf("count %d\n", count);
660e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
661e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse ContinuationState */
662e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		cont = *(unsigned char *)(frm->ptr + count);
663e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
664e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		if (cont == 0) {
665e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			/* Parse AttributeList */
666e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			print_attr_list(level + 1, get_frame(frm, count));
667e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		} else
668e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			add_frame(frm, count);
669e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
670e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		print_cont_state(level + 1, frm->ptr + count);
671d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
672e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
673d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_SERVICE_SEARCH_ATTR_REQ:
674e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse ServiceSearchPattern */
675e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		print_srv_srch_pat(level + 1, frm);
676e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
677e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse MaximumAttributeByteCount */
678e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		p_indent(level + 1, frm);
679e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		printf("max %d\n", get_u16(frm));
680e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
681e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse AttributeList */
682e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		print_attr_id_list(level + 1, frm);
683e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
684e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse ContinuationState */
685e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		print_cont_state(level + 1, frm->ptr);
686d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		break;
687e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
688d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	case SDP_SERVICE_SEARCH_ATTR_RSP:
689e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		/* Parse AttributeByteCount */
690e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		count = get_u16(frm);
691e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		p_indent(level + 1, frm);
692e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		printf("count %d\n", count);
693d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky
694d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky		/* Parse ContinuationState */
695e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		cont = *(unsigned char *)(frm->ptr + count);
696e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
697e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		if (cont == 0) {
698e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			/* Parse AttributeLists */
699e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			print_attr_lists(level + 1, get_frame(frm, count));
700e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		} else
701e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann			add_frame(frm, count);
702e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
703e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		print_cont_state(level + 1, frm->ptr + count);
704e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		break;
705e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann
706e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann	default:
707e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		raw_dump(level + 1, frm);
708e37a3738f92e103e053fe09e48affd25600cc233Marcel Holtmann		break;
709d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky	}
710d2214ceffa8f235a26ff0c6ab4b17f0a05f5d455Max Krasnyansky}
711