1/*
2 * sdp.h
3 *
4 * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $Id: sdp.h,v 1.3 2003/09/05 00:33:59 max Exp $
29 * $FreeBSD: stable/11/lib/libsdp/sdp.h 343901 2019-02-08 10:27:02Z hselasky $
30 */
31
32#ifndef _SDP_H_
33#define _SDP_H_
34
35__BEGIN_DECLS
36
37/*
38 * Data representation (page 349)
39 */
40
41/* Nil, the null type */
42#define SDP_DATA_NIL					0x00
43
44/* Unsigned integer */
45#define SDP_DATA_UINT8					0x08
46#define SDP_DATA_UINT16					0x09
47#define SDP_DATA_UINT32					0x0A
48#define SDP_DATA_UINT64					0x0B
49#define SDP_DATA_UINT128				0x0C
50
51/* Signed two's-complement integer */
52#define SDP_DATA_INT8					0x10
53#define SDP_DATA_INT16					0x11
54#define SDP_DATA_INT32					0x12
55#define SDP_DATA_INT64					0x13
56#define SDP_DATA_INT128					0x14
57
58/* UUID, a universally unique identifier */
59#define SDP_DATA_UUID16					0x19
60#define SDP_DATA_UUID32					0x1A
61#define SDP_DATA_UUID128				0x1C
62
63/* Text string */
64#define SDP_DATA_STR8					0x25
65#define SDP_DATA_STR16					0x26
66#define SDP_DATA_STR32					0x27
67
68/* Boolean */
69#define SDP_DATA_BOOL					0x28
70
71/*
72 * Data element sequence.
73 * A data element whose data field is a sequence of data elements
74 */
75#define SDP_DATA_SEQ8					0x35
76#define SDP_DATA_SEQ16					0x36
77#define SDP_DATA_SEQ32					0x37
78
79/*
80 * Data element alternative.
81 * A data element whose data field is a sequence of data elements from
82 * which one data element is to be selected.
83 */
84#define SDP_DATA_ALT8					0x3D
85#define SDP_DATA_ALT16					0x3E
86#define SDP_DATA_ALT32					0x3F
87
88/* URL, a uniform resource locator */
89#define SDP_DATA_URL8					0x45
90#define SDP_DATA_URL16					0x46
91#define SDP_DATA_URL32					0x47
92
93/*
94 * Protocols UUID (short) https://www.bluetooth.org/assigned-numbers/service_discovery.php
95 * BASE UUID 00000000-0000-1000-8000-00805F9B34FB
96 */
97
98#define SDP_UUID_PROTOCOL_SDP				0x0001
99#define SDP_UUID_PROTOCOL_UDP				0x0002
100#define SDP_UUID_PROTOCOL_RFCOMM			0x0003
101#define SDP_UUID_PROTOCOL_TCP				0x0004
102#define SDP_UUID_PROTOCOL_TCS_BIN			0x0005
103#define SDP_UUID_PROTOCOL_TCS_AT			0x0006
104#define SDP_UUID_PROTOCOL_OBEX				0x0008
105#define SDP_UUID_PROTOCOL_IP				0x0009
106#define SDP_UUID_PROTOCOL_FTP				0x000A
107#define SDP_UUID_PROTOCOL_HTTP				0x000C
108#define SDP_UUID_PROTOCOL_WSP				0x000E
109#define SDP_UUID_PROTOCOL_BNEP				0x000F
110#define SDP_UUID_PROTOCOL_UPNP				0x0010
111#define SDP_UUID_PROTOCOL_HIDP				0x0011
112#define SDP_UUID_PROTOCOL_HARDCOPY_CONTROL_CHANNEL	0x0012
113#define SDP_UUID_PROTOCOL_HARDCOPY_DATA_CHANNEL		0x0014
114#define SDP_UUID_PROTOCOL_HARDCOPY_NOTIFICATION		0x0016
115#define SDP_UUID_PROTOCOL_AVCTP				0x0017
116#define SDP_UUID_PROTOCOL_AVDTP				0x0019
117#define SDP_UUID_PROTOCOL_CMPT				0x001B
118#define SDP_UUID_PROTOCOL_UDI_C_PLANE			0x001D
119#define SDP_UUID_PROTOCOL_L2CAP				0x0100
120
121/*
122 * Service class IDs https://www.bluetooth.org/assigned-numbers/service_discovery.php
123 */
124
125#define SDP_SERVICE_CLASS_SERVICE_DISCOVERY_SERVER	0x1000
126#define SDP_SERVICE_CLASS_BROWSE_GROUP_DESCRIPTOR	0x1001
127#define SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP		0x1002
128#define SDP_SERVICE_CLASS_SERIAL_PORT			0x1101
129#define SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP		0x1102
130#define SDP_SERVICE_CLASS_DIALUP_NETWORKING		0x1103
131#define SDP_SERVICE_CLASS_IR_MC_SYNC			0x1104
132#define SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH		0x1105
133#define SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER		0x1106
134#define SDP_SERVICE_CLASS_IR_MC_SYNC_COMMAND		0x1107
135#define SDP_SERVICE_CLASS_HEADSET			0x1108
136#define SDP_SERVICE_CLASS_CORDLESS_TELEPHONY		0x1109
137#define SDP_SERVICE_CLASS_AUDIO_SOURCE			0x110A
138#define SDP_SERVICE_CLASS_AUDIO_SINK			0x110B
139#define SDP_SERVICE_CLASS_AV_REMOTE_CONTROL_TARGET	0x110C
140#define SDP_SERVICE_CLASS_ADVANCED_AUDIO_DISTRIBUTION	0x110D
141#define SDP_SERVICE_CLASS_AV_REMOTE_CONTROL		0x110E
142#define SDP_SERVICE_CLASS_VIDEO_CONFERENCING		0x110F
143#define SDP_SERVICE_CLASS_INTERCOM			0x1110
144#define SDP_SERVICE_CLASS_FAX				0x1111
145#define SDP_SERVICE_CLASS_HEADSET_AUDIO_GATEWAY		0x1112
146#define SDP_SERVICE_CLASS_WAP				0x1113
147#define SDP_SERVICE_CLASS_WAP_CLIENT			0x1114
148#define SDP_SERVICE_CLASS_PANU				0x1115
149#define SDP_SERVICE_CLASS_NAP				0x1116
150#define SDP_SERVICE_CLASS_GN				0x1117
151#define SDP_SERVICE_CLASS_DIRECT_PRINTING		0x1118
152#define SDP_SERVICE_CLASS_REFERENCE_PRINTING		0x1119
153#define SDP_SERVICE_CLASS_IMAGING			0x111A
154#define SDP_SERVICE_CLASS_IMAGING_RESPONDER		0x111B
155#define SDP_SERVICE_CLASS_IMAGING_AUTOMATIC_ARCHIVE	0x111C
156#define SDP_SERVICE_CLASS_IMAGING_REFERENCED_OBJECTS	0x111D
157#define SDP_SERVICE_CLASS_HANDSFREE			0x111E
158#define SDP_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY	0x111F
159#define SDP_SERVICE_CLASS_DIRECT_PRINTING_REFERENCE_OBJECTS	0x1120
160#define SDP_SERVICE_CLASS_REFLECTED_UI			0x1121
161#define SDP_SERVICE_CLASS_BASIC_PRINTING		0x1122
162#define SDP_SERVICE_CLASS_PRINTING_STATUS		0x1123
163#define SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE	0x1124
164#define SDP_SERVICE_CLASS_HARDCOPY_CABLE_REPLACEMENT	0x1125
165#define SDP_SERVICE_CLASS_HCR_PRINT			0x1126
166#define SDP_SERVICE_CLASS_HCR_SCAN			0x1127
167#define SDP_SERVICE_CLASS_COMMON_ISDN_ACCESS		0x1128
168#define SDP_SERVICE_CLASS_VIDEO_CONFERENCING_GW		0x1129
169#define SDP_SERVICE_CLASS_UDI_MT			0x112A
170#define SDP_SERVICE_CLASS_UDI_TA			0x112B
171#define SDP_SERVICE_CLASS_AUDIO_VIDEO			0x112C
172#define SDP_SERVICE_CLASS_SIM_ACCESS			0x112D
173#define SDP_SERVICE_CLASS_PHONEBOOK_ACCESS_PCE		0x112E
174#define SDP_SERVICE_CLASS_PHONEBOOK_ACCESS_PSE		0x112F
175#define SDP_SERVICE_CLASS_PHONEBOOK_ACCESS		0x1130
176#define SDP_SERVICE_CLASS_PNP_INFORMATION		0x1200
177#define SDP_SERVICE_CLASS_GENERIC_NETWORKING		0x1201
178#define SDP_SERVICE_CLASS_GENERIC_FILE_TRANSFER		0x1202
179#define SDP_SERVICE_CLASS_GENERIC_AUDIO			0x1203
180#define SDP_SERVICE_CLASS_GENERIC_TELEPHONY		0x1204
181#define SDP_SERVICE_CLASS_UPNP				0x1205
182#define SDP_SERVICE_CLASS_UPNP_IP			0x1206
183#define SDP_SERVICE_CLASS_ESDP_UPNP_IP_PAN		0x1300
184#define SDP_SERVICE_CLASS_ESDP_UPNP_IP_LAP		0x1301
185#define SDP_SERVICE_CLASS_ESDP_UPNP_L2CAP		0x1302
186#define SDP_SERVICE_CLASS_VIDEO_SOURCE			0x1303
187#define SDP_SERVICE_CLASS_VIDEO_SINK			0x1304
188#define SDP_SERVICE_CLASS_VIDEO_DISTRIBUTION		0x1305
189
190/*
191 * Universal attribute definitions (page 366) and
192 * https://www.bluetooth.org/assigned-numbers/service_discovery.php
193 */
194
195#define SDP_ATTR_RANGE(lo, hi) \
196	(uint32_t)(((uint16_t)(lo) << 16) | ((uint16_t)(hi)))
197
198#define SDP_ATTR_SERVICE_RECORD_HANDLE			0x0000
199#define SDP_ATTR_SERVICE_CLASS_ID_LIST			0x0001
200#define SDP_ATTR_SERVICE_RECORD_STATE			0x0002
201#define SDP_ATTR_SERVICE_ID				0x0003
202#define SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST		0x0004
203#define SDP_ATTR_BROWSE_GROUP_LIST			0x0005
204#define SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST	0x0006
205#define SDP_ATTR_SERVICE_INFO_TIME_TO_LIVE		0x0007
206#define SDP_ATTR_SERVICE_AVAILABILITY			0x0008
207#define SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST	0x0009
208#define SDP_ATTR_DOCUMENTATION_URL			0x000A
209#define SDP_ATTR_CLIENT_EXECUTABLE_URL			0x000B
210#define SDP_ATTR_ICON_URL				0x000C
211#define SDP_ATTR_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS	0x000D
212#define SDP_ATTR_GROUP_ID				0x0200
213#define SDP_ATTR_IP_SUBNET				0x0200
214#define SDP_ATTR_VERSION_NUMBER_LIST			0x0200
215#define SDP_ATTR_SERVICE_DATABASE_STATE			0x0201
216#define SDP_ATTR_SERVICE_VERSION			0x0300
217#define SDP_ATTR_EXTERNAL_NETWORK			0x0301
218#define SDP_ATTR_NETWORK				0x0301
219#define SDP_ATTR_SUPPORTED_DATA_STORES_LIST		0x0301
220#define SDP_ATTR_FAX_CLASS1_SUPPORT			0x0302
221#define SDP_ATTR_REMOTE_AUDIO_VOLUME_CONTROL		0x0302
222#define SDP_ATTR_FAX_CLASS20_SUPPORT			0x0303
223#define SDP_ATTR_SUPPORTED_FORMATS_LIST			0x0303
224#define SDP_ATTR_FAX_CLASS2_SUPPORT			0x0304
225#define SDP_ATTR_AUDIO_FEEDBACK_SUPPORT			0x0305
226#define SDP_ATTR_NETWORK_ADDRESS			0x0306
227#define SDP_ATTR_WAP_GATEWAY				0x0307
228#define SDP_ATTR_HOME_PAGE_URL				0x0308
229#define SDP_ATTR_WAP_STACK_TYPE				0x0309
230#define SDP_ATTR_SECURITY_DESCRIPTION			0x030A
231#define SDP_ATTR_NET_ACCESS_TYPE			0x030B
232#define SDP_ATTR_MAX_NET_ACCESS_RATE			0x030C
233#define SDP_ATTR_IPV4_SUBNET				0x030D
234#define SDP_ATTR_IPV6_SUBNET				0x030E
235#define SDP_ATTR_SUPPORTED_CAPABALITIES			0x0310
236#define SDP_ATTR_SUPPORTED_FEATURES			0x0311
237#define SDP_ATTR_SUPPORTED_FUNCTIONS			0x0312
238#define SDP_ATTR_TOTAL_IMAGING_DATA_CAPACITY		0x0313
239#define SDP_ATTR_SUPPORTED_REPOSITORIES			0x0314
240
241/*
242 * The offset must be added to the attribute ID base (contained in the
243 * LANGUAGE_BASE_ATTRIBUTE_ID_LIST attribute) in order to compute the
244 * attribute ID for these attributes.
245 */
246
247#define SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID		0x0100
248#define SDP_ATTR_SERVICE_NAME_OFFSET			0x0000
249#define SDP_ATTR_SERVICE_DESCRIPTION_OFFSET		0x0001
250#define SDP_ATTR_PROVIDER_NAME_OFFSET			0x0002
251
252/*
253 * Protocol data unit (PDU) format (page 352)
254 */
255
256#define SDP_PDU_ERROR_RESPONSE				0x01
257#define SDP_PDU_SERVICE_SEARCH_REQUEST			0x02
258#define SDP_PDU_SERVICE_SEARCH_RESPONSE			0x03
259#define SDP_PDU_SERVICE_ATTRIBUTE_REQUEST		0x04
260#define SDP_PDU_SERVICE_ATTRIBUTE_RESPONSE		0x05
261#define SDP_PDU_SERVICE_SEARCH_ATTRIBUTE_REQUEST	0x06
262#define SDP_PDU_SERVICE_SEARCH_ATTRIBUTE_RESPONSE	0x07
263
264struct sdp_pdu {
265	uint8_t		pid;	/* PDU ID - SDP_PDU_xxx */
266	uint16_t	tid;	/* transaction ID */
267	uint16_t	len;	/* parameters length (in bytes) */
268} __attribute__ ((packed));
269typedef struct sdp_pdu		sdp_pdu_t;
270typedef struct sdp_pdu *	sdp_pdu_p;
271
272/*
273 * Error codes for SDP_PDU_ERROR_RESPONSE
274 */
275
276#define SDP_ERROR_CODE_INVALID_SDP_VERSION		0x0001
277#define SDP_ERROR_CODE_INVALID_SERVICE_RECORD_HANDLE	0x0002
278#define SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX		0x0003
279#define SDP_ERROR_CODE_INVALID_PDU_SIZE			0x0004
280#define SDP_ERROR_CODE_INVALID_CONTINUATION_STATE	0x0005
281#define SDP_ERROR_CODE_INSUFFICIENT_RESOURCES		0x0006
282
283/*
284 * SDP int128/uint128 parameter
285 */
286
287struct int128 {
288	int8_t	b[16];
289};
290typedef struct int128	int128_t;
291typedef struct int128	uint128_t;
292
293/*
294 * SDP attribute
295 */
296
297struct sdp_attr {
298	uint16_t	 flags;
299#define SDP_ATTR_OK		(0 << 0)
300#define SDP_ATTR_INVALID	(1 << 0)
301#define SDP_ATTR_TRUNCATED	(1 << 1)
302	uint16_t	 attr;  /* SDP_ATTR_xxx */
303	uint32_t	 vlen;	/* length of the value[] in bytes */
304	uint8_t		*value;	/* base pointer */
305};
306typedef struct sdp_attr		sdp_attr_t;
307typedef struct sdp_attr *	sdp_attr_p;
308
309/******************************************************************************
310 * User interface
311 *****************************************************************************/
312
313/* Inline versions of get/put byte/short/long. Pointer is advanced */
314#define SDP_GET8(b, cp) { \
315	const uint8_t *t_cp = (const uint8_t *)(cp); \
316	(b) = *t_cp; \
317	(cp) ++; \
318}
319
320#define SDP_GET16(s, cp) { \
321	const uint8_t *t_cp = (const uint8_t *)(cp); \
322	(s) = ((uint16_t)t_cp[0] << 8) \
323	    | ((uint16_t)t_cp[1]) \
324	    ; \
325	(cp) += 2; \
326}
327
328#define SDP_GET32(l, cp) { \
329	const uint8_t *t_cp = (const uint8_t *)(cp); \
330	(l) = ((uint32_t)t_cp[0] << 24) \
331	    | ((uint32_t)t_cp[1] << 16) \
332	    | ((uint32_t)t_cp[2] << 8) \
333	    | ((uint32_t)t_cp[3]) \
334	    ; \
335	(cp) += 4; \
336}
337
338#define SDP_GET64(l, cp) { \
339	register uint8_t *t_cp = (uint8_t *)(cp); \
340	(l) = ((uint64_t)t_cp[0] << 56) \
341	    | ((uint64_t)t_cp[1] << 48) \
342	    | ((uint64_t)t_cp[2] << 40) \
343	    | ((uint64_t)t_cp[3] << 32) \
344	    | ((uint64_t)t_cp[4] << 24) \
345	    | ((uint64_t)t_cp[5] << 16) \
346	    | ((uint64_t)t_cp[6] << 8) \
347	    | ((uint64_t)t_cp[7]) \
348	    ; \
349	(cp) += 8; \
350}
351
352#if BYTE_ORDER == LITTLE_ENDIAN
353#define SDP_GET128(l, cp) { \
354	register uint8_t *t_cp = (uint8_t *)(cp); \
355	(l)->b[15] = *t_cp++; \
356	(l)->b[14] = *t_cp++; \
357	(l)->b[13] = *t_cp++; \
358	(l)->b[12] = *t_cp++; \
359	(l)->b[11] = *t_cp++; \
360	(l)->b[10] = *t_cp++; \
361	(l)->b[9]  = *t_cp++; \
362	(l)->b[8]  = *t_cp++; \
363	(l)->b[7]  = *t_cp++; \
364	(l)->b[6]  = *t_cp++; \
365	(l)->b[5]  = *t_cp++; \
366	(l)->b[4]  = *t_cp++; \
367	(l)->b[3]  = *t_cp++; \
368	(l)->b[2]  = *t_cp++; \
369	(l)->b[1]  = *t_cp++; \
370	(l)->b[0]  = *t_cp++; \
371	(cp) += 16; \
372}
373
374#define SDP_GET_UUID128(l, cp) { \
375	register uint8_t *t_cp = (uint8_t *)(cp); \
376	(l)->b[0]  = *t_cp++; \
377	(l)->b[1]  = *t_cp++; \
378	(l)->b[2]  = *t_cp++; \
379	(l)->b[3]  = *t_cp++; \
380	(l)->b[4]  = *t_cp++; \
381	(l)->b[5]  = *t_cp++; \
382	(l)->b[6]  = *t_cp++; \
383	(l)->b[7]  = *t_cp++; \
384	(l)->b[8]  = *t_cp++; \
385	(l)->b[9]  = *t_cp++; \
386	(l)->b[10] = *t_cp++; \
387	(l)->b[11] = *t_cp++; \
388	(l)->b[12] = *t_cp++; \
389	(l)->b[13] = *t_cp++; \
390	(l)->b[14] = *t_cp++; \
391	(l)->b[15] = *t_cp++; \
392	(cp) += 16; \
393}
394#elif BYTE_ORDER == BIG_ENDIAN
395#define SDP_GET128(l, cp) { \
396	register uint8_t *t_cp = (uint8_t *)(cp); \
397	(l)->b[0]  = *t_cp++; \
398	(l)->b[1]  = *t_cp++; \
399	(l)->b[2]  = *t_cp++; \
400	(l)->b[3]  = *t_cp++; \
401	(l)->b[4]  = *t_cp++; \
402	(l)->b[5]  = *t_cp++; \
403	(l)->b[6]  = *t_cp++; \
404	(l)->b[7]  = *t_cp++; \
405	(l)->b[8]  = *t_cp++; \
406	(l)->b[9]  = *t_cp++; \
407	(l)->b[10] = *t_cp++; \
408	(l)->b[11] = *t_cp++; \
409	(l)->b[12] = *t_cp++; \
410	(l)->b[13] = *t_cp++; \
411	(l)->b[14] = *t_cp++; \
412	(l)->b[15] = *t_cp++; \
413	(cp) += 16; \
414}
415
416#define	SDP_GET_UUID128(l, cp)	SDP_GET128(l, cp)
417#else
418#error	"Unsupported BYTE_ORDER"
419#endif /* BYTE_ORDER */
420
421#define SDP_PUT8(b, cp) { \
422	register uint8_t t_b = (uint8_t)(b); \
423	register uint8_t *t_cp = (uint8_t *)(cp); \
424	*t_cp = t_b; \
425	(cp) ++; \
426}
427
428#define SDP_PUT16(s, cp) { \
429	register uint16_t t_s = (uint16_t)(s); \
430	register uint8_t *t_cp = (uint8_t *)(cp); \
431	*t_cp++ = t_s >> 8; \
432	*t_cp   = t_s; \
433	(cp) += 2; \
434}
435
436#define SDP_PUT32(l, cp) { \
437	register uint32_t t_l = (uint32_t)(l); \
438	register uint8_t *t_cp = (uint8_t *)(cp); \
439	*t_cp++ = t_l >> 24; \
440	*t_cp++ = t_l >> 16; \
441	*t_cp++ = t_l >> 8; \
442	*t_cp   = t_l; \
443	(cp) += 4; \
444}
445
446#define SDP_PUT64(l, cp) { \
447	register uint64_t t_l = (uint64_t)(l); \
448	register uint8_t *t_cp = (uint8_t *)(cp); \
449	*t_cp++ = t_l >> 56; \
450	*t_cp++ = t_l >> 48; \
451	*t_cp++ = t_l >> 40; \
452	*t_cp++ = t_l >> 32; \
453	*t_cp++ = t_l >> 24; \
454	*t_cp++ = t_l >> 16; \
455	*t_cp++ = t_l >> 8; \
456	*t_cp   = t_l; \
457	(cp) += 8; \
458}
459
460#if BYTE_ORDER == LITTLE_ENDIAN
461#define SDP_PUT128(l, cp) { \
462	register uint8_t *t_cp = (uint8_t *)(cp); \
463	*t_cp++ = (l)->b[15]; \
464	*t_cp++ = (l)->b[14]; \
465	*t_cp++ = (l)->b[13]; \
466	*t_cp++ = (l)->b[12]; \
467	*t_cp++ = (l)->b[11]; \
468	*t_cp++ = (l)->b[10]; \
469	*t_cp++ = (l)->b[9];  \
470	*t_cp++ = (l)->b[8];  \
471	*t_cp++ = (l)->b[7];  \
472	*t_cp++ = (l)->b[6];  \
473	*t_cp++ = (l)->b[5];  \
474	*t_cp++ = (l)->b[4];  \
475	*t_cp++ = (l)->b[3];  \
476	*t_cp++ = (l)->b[2];  \
477	*t_cp++ = (l)->b[1];  \
478	*t_cp   = (l)->b[0];  \
479	(cp) += 16; \
480}
481
482#define SDP_PUT_UUID128(l, cp) { \
483	register uint8_t *t_cp = (uint8_t *)(cp); \
484	*t_cp++ = (l)->b[0];  \
485	*t_cp++ = (l)->b[1];  \
486	*t_cp++ = (l)->b[2];  \
487	*t_cp++ = (l)->b[3];  \
488	*t_cp++ = (l)->b[4];  \
489	*t_cp++ = (l)->b[5];  \
490	*t_cp++ = (l)->b[6];  \
491	*t_cp++ = (l)->b[7];  \
492	*t_cp++ = (l)->b[8];  \
493	*t_cp++ = (l)->b[9];  \
494	*t_cp++ = (l)->b[10]; \
495	*t_cp++ = (l)->b[11]; \
496	*t_cp++ = (l)->b[12]; \
497	*t_cp++ = (l)->b[13]; \
498	*t_cp++ = (l)->b[14]; \
499	*t_cp   = (l)->b[15]; \
500	(cp) += 16; \
501}
502#elif BYTE_ORDER == BIG_ENDIAN
503#define SDP_PUT128(l, cp) { \
504	register uint8_t *t_cp = (uint8_t *)(cp); \
505	*t_cp++ = (l)->b[0];  \
506	*t_cp++ = (l)->b[1];  \
507	*t_cp++ = (l)->b[2];  \
508	*t_cp++ = (l)->b[3];  \
509	*t_cp++ = (l)->b[4];  \
510	*t_cp++ = (l)->b[5];  \
511	*t_cp++ = (l)->b[6];  \
512	*t_cp++ = (l)->b[7];  \
513	*t_cp++ = (l)->b[8];  \
514	*t_cp++ = (l)->b[9];  \
515	*t_cp++ = (l)->b[10]; \
516	*t_cp++ = (l)->b[11]; \
517	*t_cp++ = (l)->b[12]; \
518	*t_cp++ = (l)->b[13]; \
519	*t_cp++ = (l)->b[14]; \
520	*t_cp   = (l)->b[15]; \
521	(cp) += 16; \
522}
523
524#define SDP_PUT_UUID128(l, cp)	SDP_PUT128(l, cp)
525#else
526#error	"Unsupported BYTE_ORDER"
527#endif /* BYTE_ORDER */
528
529void *             sdp_open       (bdaddr_t const *l, bdaddr_t const *r);
530void *             sdp_open_local (char const *control);
531int32_t            sdp_close      (void *xs);
532int32_t            sdp_error      (void *xs);
533
534int32_t            sdp_search     (void *xs,
535                                   uint32_t plen, uint16_t const *pp,
536                                   uint32_t alen, uint32_t const *ap,
537                                   uint32_t vlen, sdp_attr_t *vp);
538
539char const *	   sdp_attr2desc  (uint16_t attr);
540char const *	   sdp_uuid2desc  (uint16_t uuid);
541void               sdp_print      (uint32_t level, uint8_t const *start,
542                                   uint8_t const *end);
543
544/******************************************************************************
545 * sdpd interface and Bluetooth profiles data
546 *****************************************************************************/
547
548#define SDP_LOCAL_PATH	"/var/run/sdp"
549#define SDP_LOCAL_MTU	4096
550
551/*
552 * These are NOT defined in spec and only accepted on control sockets.
553 * The response to these request always will be SDP_PDU_ERROR_RESPONSE.
554 * The first 2 bytes (after PDU header) is an error code (in network
555 * byte order). The rest of the data (pdu->len - 2) is a response data
556 * and depend on the request.
557 *
558 * SDP_PDU_SERVICE_REGISTER_REQUEST
559 * 	pdu_header_t	hdr;
560 *	u_int16_t	uuid;	service class UUID (network byte order)
561 *	bdaddr_t	bdaddr;	local BD_ADDR (or ANY)
562 *	profile data[pdu->len - sizeof(uuid) - sizeof(bdaddr)]
563 *
564 * in successful response additional data will contain 4 bytes record handle
565 *
566 *
567 * SDP_PDU_SERVICE_UNREGISTER_REQUEST
568 *	pdu_header_t	hdr;
569 *	u_int32_t	record_handle;	(network byte order)
570 *
571 * no additional data in response.
572 *
573 *
574 * SDP_PDU_SERVICE_CHANGE_REQUEST
575 * 	pdu_header_t	hdr;
576 *	u_int32_t	record_handle;	(network byte order)
577 *	profile data[pdu->len - sizeof(record_handle)]
578 *
579 * no additional data in response.
580 */
581
582#define SDP_PDU_SERVICE_REGISTER_REQUEST	0x81
583#define SDP_PDU_SERVICE_UNREGISTER_REQUEST	0x82
584#define SDP_PDU_SERVICE_CHANGE_REQUEST		0x83
585
586struct sdp_audio_sink_profile
587{
588	uint16_t psm;
589	uint16_t protover;
590	uint16_t features;
591};
592typedef struct sdp_audio_sink_profile	sdp_audio_sink_profile_t;
593typedef struct sdp_audio_sink_profile	*sdp_audio_sink_profile_p;
594
595struct sdp_audio_source_profile
596{
597	uint16_t psm;
598	uint16_t protover;
599	uint16_t features;
600};
601typedef struct sdp_audio_source_profile	sdp_audio_source_profile_t;
602typedef struct sdp_audio_source_profile *sdp_audio_source_profile_p;
603
604struct sdp_dun_profile
605{
606	uint8_t	server_channel;
607	uint8_t	audio_feedback_support;
608	uint8_t	reserved[2];
609};
610typedef struct sdp_dun_profile		sdp_dun_profile_t;
611typedef struct sdp_dun_profile *	sdp_dun_profile_p;
612
613struct sdp_ftrn_profile
614{
615	uint8_t	server_channel;
616	uint8_t	reserved[3];
617};
618typedef struct sdp_ftrn_profile		sdp_ftrn_profile_t;
619typedef struct sdp_ftrn_profile *	sdp_ftrn_profile_p;
620
621/* Keep this in sync with sdp_opush_profile */
622struct sdp_irmc_profile
623{
624	uint8_t	server_channel;
625	uint8_t	supported_formats_size;
626	uint8_t	supported_formats[30];
627};
628typedef struct sdp_irmc_profile		sdp_irmc_profile_t;
629typedef struct sdp_irmc_profile *	sdp_irmc_profile_p;
630
631struct sdp_irmc_command_profile
632{
633	uint8_t	server_channel;
634	uint8_t	reserved[3];
635};
636typedef struct sdp_irmc_command_profile		sdp_irmc_command_profile_t;
637typedef struct sdp_irmc_command_profile *	sdp_irmc_command_profile_p;
638
639struct sdp_lan_profile
640{
641	uint8_t		server_channel;
642	uint8_t		load_factor;
643	uint8_t		reserved;
644	uint8_t		ip_subnet_radius;
645	uint32_t	ip_subnet;
646};
647typedef struct sdp_lan_profile		sdp_lan_profile_t;
648typedef struct sdp_lan_profile *	sdp_lan_profile_p;
649
650/* Keep this in sync with sdp_irmc_profile */
651struct sdp_opush_profile
652{
653	uint8_t	server_channel;
654	uint8_t	supported_formats_size;
655	uint8_t	supported_formats[30];
656};
657typedef struct sdp_opush_profile	sdp_opush_profile_t;
658typedef struct sdp_opush_profile *	sdp_opush_profile_p;
659
660struct sdp_sp_profile
661{
662	uint8_t	server_channel;
663	uint8_t	reserved[3];
664};
665typedef struct sdp_sp_profile	sdp_sp_profile_t;
666typedef struct sdp_sp_profile *	sdp_sp_profile_p;
667
668struct sdp_nap_profile
669{
670	uint8_t		reserved;
671	uint8_t		load_factor;
672	uint16_t	psm;			/* HBO */
673	uint16_t	security_description;	/* HBO */
674	uint16_t	net_access_type;	/* HBO */
675	uint32_t	max_net_access_rate;	/* HBO */
676};
677typedef struct sdp_nap_profile		sdp_nap_profile_t;
678typedef struct sdp_nap_profile *	sdp_nap_profile_p;
679
680struct sdp_gn_profile
681{
682	uint8_t		reserved;
683	uint8_t		load_factor;
684	uint16_t	psm;			/* HBO */
685	uint16_t	security_description;	/* HBO */
686	uint16_t	reserved2;
687};
688typedef struct sdp_gn_profile		sdp_gn_profile_t;
689typedef struct sdp_gn_profile *		sdp_gn_profile_p;
690
691struct sdp_panu_profile
692{
693	uint8_t		reserved;
694	uint8_t		load_factor;
695	uint16_t	psm;			/* HBO */
696	uint16_t	security_description;	/* HBO */
697	uint16_t	reserved2;
698};
699typedef struct sdp_panu_profile		sdp_panu_profile_t;
700typedef struct sdp_panu_profile *	sdp_panu_profile_p;
701
702int32_t	sdp_register_service	(void *xss, uint16_t uuid,
703				 bdaddr_p const bdaddr, uint8_t const *data,
704				 uint32_t datalen, uint32_t *handle);
705int32_t	sdp_unregister_service	(void *xss, uint32_t handle);
706int32_t	sdp_change_service	(void *xss, uint32_t handle,
707				 uint8_t const *data, uint32_t datalen);
708
709__END_DECLS
710
711#endif /* ndef _SDP_H_ */
712
713