sdp.h revision 146691
11590Srgrimes/*
21590Srgrimes * sdp.h
31590Srgrimes *
41590Srgrimes * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
51590Srgrimes * All rights reserved.
61590Srgrimes *
71590Srgrimes * Redistribution and use in source and binary forms, with or without
81590Srgrimes * modification, are permitted provided that the following conditions
91590Srgrimes * are met:
101590Srgrimes * 1. Redistributions of source code must retain the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer.
121590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
131590Srgrimes *    notice, this list of conditions and the following disclaimer in the
141590Srgrimes *    documentation and/or other materials provided with the distribution.
151590Srgrimes *
161590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
171590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
181590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
191590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
201590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
211590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
221590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
231590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
241590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
251590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
261590Srgrimes * SUCH DAMAGE.
271590Srgrimes *
281590Srgrimes * $Id: sdp.h,v 1.3 2003/09/05 00:33:59 max Exp $
291590Srgrimes * $FreeBSD: head/lib/libsdp/sdp.h 146691 2005-05-27 19:11:33Z emax $
301590Srgrimes */
311590Srgrimes
321590Srgrimes#ifndef _SDP_H_
331590Srgrimes#define _SDP_H_
341590Srgrimes
3527273Scharnier__BEGIN_DECLS
361590Srgrimes
371590Srgrimes/*
381590Srgrimes * Data representation (page 349)
391590Srgrimes */
4099130Sobrien
411590Srgrimes/* Nil, the null type */
421590Srgrimes#define SDP_DATA_NIL					0x00
4399130Sobrien
4427273Scharnier/* Unsigned integer */
4594560Scharnier#define SDP_DATA_UINT8					0x08
4694560Scharnier#define SDP_DATA_UINT16					0x09
4794560Scharnier#define SDP_DATA_UINT32					0x0A
481590Srgrimes#define SDP_DATA_UINT64					0x0B
491590Srgrimes#define SDP_DATA_UINT128				0x0C
501590Srgrimes
511590Srgrimes/* Signed two's-complement integer */
521590Srgrimes#define SDP_DATA_INT8					0x10
531590Srgrimes#define SDP_DATA_INT16					0x11
541590Srgrimes#define SDP_DATA_INT32					0x12
551590Srgrimes#define SDP_DATA_INT64					0x13
561590Srgrimes#define SDP_DATA_INT128					0x14
571590Srgrimes
581590Srgrimes/* UUID, a universally unique identifier */
5994560Scharnier#define SDP_DATA_UUID16					0x19
601590Srgrimes#define SDP_DATA_UUID32					0x1A
611590Srgrimes#define SDP_DATA_UUID128				0x1C
621590Srgrimes
63103299Speter/* Text string */
64199805Sattilio#define SDP_DATA_STR8					0x25
6576228Sobrien#define SDP_DATA_STR16					0x26
6627273Scharnier#define SDP_DATA_STR32					0x27
671590Srgrimes
681590Srgrimes/* Boolean */
691590Srgrimes#define SDP_DATA_BOOL					0x28
701590Srgrimes
71200462Sdelphij/*
721590Srgrimes * Data element sequence.
731590Srgrimes * A data element whose data field is a sequence of data elements
741590Srgrimes */
751590Srgrimes#define SDP_DATA_SEQ8					0x35
7692920Simp#define SDP_DATA_SEQ16					0x36
7792920Simp#define SDP_DATA_SEQ32					0x37
7892920Simp
791590Srgrimes/*
8040562Sjdp * Data element alternative.
811590Srgrimes * A data element whose data field is a sequence of data elements from
82103299Speter * which one data element is to be selected.
83103299Speter */
841590Srgrimes#define SDP_DATA_ALT8					0x3D
85103299Speter#define SDP_DATA_ALT16					0x3E
861590Srgrimes#define SDP_DATA_ALT32					0x3F
87199805Sattilio
8839164Sdes/* URL, a uniform resource locator */
89199805Sattilio#define SDP_DATA_URL8					0x45
90103299Speter#define SDP_DATA_URL16					0x46
91199805Sattilio#define SDP_DATA_URL32					0x47
921590Srgrimes
931590Srgrimes/*
941590Srgrimes * Protocols UUID (short) http://www.bluetoothsig.org/assigned-numbers/sdp.htm
9524360Simp * BASE UUID 00000000-0000-1000-8000-00805F9B34FB
961590Srgrimes */
971590Srgrimes
981590Srgrimes#define SDP_UUID_PROTOCOL_SDP				0x0001
991590Srgrimes#define SDP_UUID_PROTOCOL_UDP				0x0002
1001590Srgrimes#define SDP_UUID_PROTOCOL_RFCOMM			0x0003
1011590Srgrimes#define SDP_UUID_PROTOCOL_TCP				0x0004
1021590Srgrimes#define SDP_UUID_PROTOCOL_TCS_BIN			0x0005
1031590Srgrimes#define SDP_UUID_PROTOCOL_TCS_AT			0x0006
1041590Srgrimes#define SDP_UUID_PROTOCOL_OBEX				0x0008
1051590Srgrimes#define SDP_UUID_PROTOCOL_IP				0x0009
1061590Srgrimes#define SDP_UUID_PROTOCOL_FTP				0x000A
1071590Srgrimes#define SDP_UUID_PROTOCOL_HTTP				0x000C
1081590Srgrimes#define SDP_UUID_PROTOCOL_WSP				0x000E
1091590Srgrimes#define SDP_UUID_PROTOCOL_BNEP				0x000F
11039164Sdes#define SDP_UUID_PROTOCOL_UPNP				0x0010
11139164Sdes#define SDP_UUID_PROTOCOL_HIDP				0x0011
11239164Sdes#define SDP_UUID_PROTOCOL_HARDCOPY_CONTROL_CHANNEL	0x0012
11339164Sdes#define SDP_UUID_PROTOCOL_HARDCOPY_DATA_CHANNEL		0x0014
114199805Sattilio#define SDP_UUID_PROTOCOL_HARDCOPY_NOTIFICATION		0x0016
115199805Sattilio#define SDP_UUID_PROTOCOL_AVCTP				0x0017
116199805Sattilio#define SDP_UUID_PROTOCOL_AVDTP				0x0019
117199805Sattilio#define SDP_UUID_PROTOCOL_CMPT				0x001B
118199805Sattilio#define SDP_UUID_PROTOCOL_UDI_C_PLANE			0x001D
119199805Sattilio#define SDP_UUID_PROTOCOL_L2CAP				0x0100
120199805Sattilio
121199805Sattilio/*
12239164Sdes * Service class IDs http://www.bluetoothsig.org/assigned-numbers/sdp.htm
12339164Sdes */
12439164Sdes
12539164Sdes#define SDP_SERVICE_CLASS_SERVICE_DISCOVERY_SERVER	0x1000
12639164Sdes#define SDP_SERVICE_CLASS_BROWSE_GROUP_DESCRIPTOR	0x1001
12739164Sdes#define SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP		0x1002
1281590Srgrimes#define SDP_SERVICE_CLASS_SERIAL_PORT			0x1101
12939164Sdes#define SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP		0x1102
13040525Sjdp#define SDP_SERVICE_CLASS_DIALUP_NETWORKING		0x1103
13140525Sjdp#define SDP_SERVICE_CLASS_IR_MC_SYNC			0x1104
13240525Sjdp#define SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH		0x1105
133103299Speter#define SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER		0x1106
134103299Speter#define SDP_SERVICE_CLASS_IR_MC_SYNC_COMMAND		0x1107
135103299Speter#define SDP_SERVICE_CLASS_HEADSET			0x1108
136103299Speter#define SDP_SERVICE_CLASS_CORDLESS_TELEPHONY		0x1109
137103299Speter#define SDP_SERVICE_CLASS_AUDIO_SOURCE			0x110A
138103299Speter#define SDP_SERVICE_CLASS_AUDIO_SINK			0x110B
139103299Speter#define SDP_SERVICE_CLASS_AV_REMOTE_CONTROL_TARGET	0x110C
140103299Speter#define SDP_SERVICE_CLASS_ADVANCED_AUDIO_DISTRIBUTION	0x110D
141103299Speter#define SDP_SERVICE_CLASS_AV_REMOTE_CONTROL		0x110E
142103299Speter#define SDP_SERVICE_CLASS_VIDEO_CONFERENCING		0x110F
14340525Sjdp#define SDP_SERVICE_CLASS_INTERCOM			0x1110
1441590Srgrimes#define SDP_SERVICE_CLASS_FAX				0x1111
1451590Srgrimes#define SDP_SERVICE_CLASS_HEADSET_AUDIO_GATEWAY		0x1112
1461590Srgrimes#define SDP_SERVICE_CLASS_WAP				0x1113
1471590Srgrimes#define SDP_SERVICE_CLASS_WAP_CLIENT			0x1114
1481590Srgrimes#define SDP_SERVICE_CLASS_PANU				0x1115
1491590Srgrimes#define SDP_SERVICE_CLASS_NAP				0x1116
15027273Scharnier#define SDP_SERVICE_CLASS_GN				0x1117
15140562Sjdp#define SDP_SERVICE_CLASS_DIRECT_PRINTING		0x1118
15240562Sjdp#define SDP_SERVICE_CLASS_REFERENCE_PRINTING		0x1119
15340562Sjdp#define SDP_SERVICE_CLASS_IMAGING			0x111A
15440562Sjdp#define SDP_SERVICE_CLASS_IMAGING_RESPONDER		0x111B
15540562Sjdp#define SDP_SERVICE_CLASS_IMAGING_AUTOMATIC_ARCHIVE	0x111C
15640562Sjdp#define SDP_SERVICE_CLASS_IMAGING_REFERENCED_OBJECTS	0x111D
15740562Sjdp#define SDP_SERVICE_CLASS_HANDSFREE			0x111E
15840562Sjdp#define SDP_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY	0x111F
159103299Speter#define SDP_SERVICE_CLASS_DIRECT_PRINTING_REFERENCE_OBJECTS	0x1120
1601590Srgrimes#define SDP_SERVICE_CLASS_REFLECTED_UI			0x1121
161103299Speter#define SDP_SERVICE_CLASS_BASIC_PRINTING		0x1122
1621590Srgrimes#define SDP_SERVICE_CLASS_PRINTING_STATUS		0x1123
1631590Srgrimes#define SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE	0x1124
1641590Srgrimes#define SDP_SERVICE_CLASS_HARDCOPY_CABLE_REPLACEMENT	0x1125
165103299Speter#define SDP_SERVICE_CLASS_HCR_PRINT			0x1126
166103299Speter#define SDP_SERVICE_CLASS_HCR_SCAN			0x1127
1671590Srgrimes#define SDP_SERVICE_CLASS_COMMON_ISDN_ACCESS		0x1128
1681590Srgrimes#define SDP_SERVICE_CLASS_VIDEO_CONFERENCING_GW		0x1129
16940562Sjdp#define SDP_SERVICE_CLASS_UDI_MT			0x112A
17040562Sjdp#define SDP_SERVICE_CLASS_UDI_TA			0x112B
17140562Sjdp#define SDP_SERVICE_CLASS_AUDIO_VIDEO			0x112C
17240562Sjdp#define SDP_SERVICE_CLASS_SIM_ACCESS			0x112D
17340562Sjdp#define SDP_SERVICE_CLASS_PNP_INFORMATION		0x1200
17440562Sjdp#define SDP_SERVICE_CLASS_GENERIC_NETWORKING		0x1201
175103299Speter#define SDP_SERVICE_CLASS_GENERIC_FILE_TRANSFER		0x1202
17640562Sjdp#define SDP_SERVICE_CLASS_GENERIC_AUDIO			0x1203
177103299Speter#define SDP_SERVICE_CLASS_GENERIC_TELEPHONY		0x1204
17840562Sjdp#define SDP_SERVICE_CLASS_UPNP				0x1205
17940562Sjdp#define SDP_SERVICE_CLASS_UPNP_IP			0x1206
18040562Sjdp#define SDP_SERVICE_CLASS_ESDP_UPNP_IP_PAN		0x1300
1811590Srgrimes#define SDP_SERVICE_CLASS_ESDP_UPNP_IP_LAP		0x1301
182103299Speter#define SDP_SERVICE_CLASS_ESDP_UPNP_L2CAP		0x1302
1831590Srgrimes
1841590Srgrimes/*
18581735Smikeh * Universal attribute definitions (page 366) and
1861590Srgrimes * http://www.bluetoothsig.org/assigned-numbers/sdp.htm
1871590Srgrimes */
188
189#define SDP_ATTR_RANGE(lo, hi) \
190	(uint32_t)(((uint16_t)(lo) << 16) | ((uint16_t)(hi)))
191
192#define SDP_ATTR_SERVICE_RECORD_HANDLE			0x0000
193#define SDP_ATTR_SERVICE_CLASS_ID_LIST			0x0001
194#define SDP_ATTR_SERVICE_RECORD_STATE			0x0002
195#define SDP_ATTR_SERVICE_ID				0x0003
196#define SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST		0x0004
197#define SDP_ATTR_BROWSE_GROUP_LIST			0x0005
198#define SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST	0x0006
199#define SDP_ATTR_SERVICE_INFO_TIME_TO_LIVE		0x0007
200#define SDP_ATTR_SERVICE_AVAILABILITY			0x0008
201#define SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST	0x0009
202#define SDP_ATTR_DOCUMENTATION_URL			0x000A
203#define SDP_ATTR_CLIENT_EXECUTABLE_URL			0x000B
204#define SDP_ATTR_ICON_URL				0x000C
205#define SDP_ATTR_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS	0x000D
206#define SDP_ATTR_GROUP_ID				0x0200
207#define SDP_ATTR_IP_SUBNET				0x0200
208#define SDP_ATTR_VERSION_NUMBER_LIST			0x0200
209#define SDP_ATTR_SERVICE_DATABASE_STATE			0x0201
210#define SDP_ATTR_SERVICE_VERSION			0x0300
211#define SDP_ATTR_EXTERNAL_NETWORK			0x0301
212#define SDP_ATTR_NETWORK				0x0301
213#define SDP_ATTR_SUPPORTED_DATA_STORES_LIST		0x0301
214#define SDP_ATTR_FAX_CLASS1_SUPPORT			0x0302
215#define SDP_ATTR_REMOTE_AUDIO_VOLUME_CONTROL		0x0302
216#define SDP_ATTR_FAX_CLASS20_SUPPORT			0x0303
217#define SDP_ATTR_SUPPORTED_FORMATS_LIST			0x0303
218#define SDP_ATTR_FAX_CLASS2_SUPPORT			0x0304
219#define SDP_ATTR_AUDIO_FEEDBACK_SUPPORT			0x0305
220#define SDP_ATTR_NETWORK_ADDRESS			0x0306
221#define SDP_ATTR_WAP_GATEWAY				0x0307
222#define SDP_ATTR_HOME_PAGE_URL				0x0308
223#define SDP_ATTR_WAP_STACK_TYPE				0x0309
224#define SDP_ATTR_SECURITY_DESCRIPTION			0x030A
225#define SDP_ATTR_NET_ACCESS_TYPE			0x030B
226#define SDP_ATTR_MAX_NET_ACCESS_RATE			0x030C
227#define SDP_ATTR_IPV4_SUBNET				0x030D
228#define SDP_ATTR_IPV6_SUBNET				0x030E
229#define SDP_ATTR_SUPPORTED_CAPABALITIES			0x0310
230#define SDP_ATTR_SUPPORTED_FEATURES			0x0311
231#define SDP_ATTR_SUPPORTED_FUNCTIONS			0x0312
232#define SDP_ATTR_TOTAL_IMAGING_DATA_CAPACITY		0x0313
233
234/*
235 * The offset must be added to the attribute ID base (contained in the
236 * LANGUAGE_BASE_ATTRIBUTE_ID_LIST attribute) in order to compute the
237 * attribute ID for these attributes.
238 */
239
240#define SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID		0x0100
241#define SDP_ATTR_SERVICE_NAME_OFFSET			0x0000
242#define SDP_ATTR_SERVICE_DESCRIPTION_OFFSET		0x0001
243#define SDP_ATTR_PROVIDER_NAME_OFFSET			0x0002
244
245/*
246 * Protocol data unit (PDU) format (page 352)
247 */
248
249#define SDP_PDU_ERROR_RESPONSE				0x01
250#define SDP_PDU_SERVICE_SEARCH_REQUEST			0x02
251#define SDP_PDU_SERVICE_SEARCH_RESPONSE			0x03
252#define SDP_PDU_SERVICE_ATTRIBUTE_REQUEST		0x04
253#define SDP_PDU_SERVICE_ATTRIBUTE_RESPONSE		0x05
254#define SDP_PDU_SERVICE_SEARCH_ATTRIBUTE_REQUEST	0x06
255#define SDP_PDU_SERVICE_SEARCH_ATTRIBUTE_RESPONSE	0x07
256
257struct sdp_pdu {
258	uint8_t		pid;	/* PDU ID - SDP_PDU_xxx */
259	uint16_t	tid;	/* transaction ID */
260	uint16_t	len;	/* parameters length (in bytes) */
261} __attribute__ ((packed));
262typedef struct sdp_pdu		sdp_pdu_t;
263typedef struct sdp_pdu *	sdp_pdu_p;
264
265/*
266 * Error codes for SDP_PDU_ERROR_RESPONSE
267 */
268
269#define SDP_ERROR_CODE_INVALID_SDP_VERSION		0x0001
270#define SDP_ERROR_CODE_INVALID_SERVICE_RECORD_HANDLE	0x0002
271#define SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX		0x0003
272#define SDP_ERROR_CODE_INVALID_PDU_SIZE			0x0004
273#define SDP_ERROR_CODE_INVALID_CONTINUATION_STATE	0x0005
274#define SDP_ERROR_CODE_INSUFFICIENT_RESOURCES		0x0006
275
276/*
277 * SDP int128/uint128 parameter
278 */
279
280struct int128 {
281	int8_t	b[16];
282};
283typedef struct int128	int128_t;
284typedef struct int128	uint128_t;
285
286/*
287 * SDP attribute
288 */
289
290struct sdp_attr {
291	uint16_t	 flags;
292#define SDP_ATTR_OK		(0 << 0)
293#define SDP_ATTR_INVALID	(1 << 0)
294#define SDP_ATTR_TRUNCATED	(1 << 1)
295	uint16_t	 attr;  /* SDP_ATTR_xxx */
296	uint32_t	 vlen;	/* length of the value[] in bytes */
297	uint8_t		*value;	/* base pointer */
298};
299typedef struct sdp_attr		sdp_attr_t;
300typedef struct sdp_attr *	sdp_attr_p;
301
302/******************************************************************************
303 * User interface
304 *****************************************************************************/
305
306/* Inline versions of get/put byte/short/long. Pointer is advanced */
307#define SDP_GET8(b, cp) { \
308	register uint8_t *t_cp = (uint8_t *)(cp); \
309	(b) = *t_cp; \
310	(cp) ++; \
311}
312
313#define SDP_GET16(s, cp) { \
314	register uint8_t *t_cp = (uint8_t *)(cp); \
315	(s) = ((uint16_t)t_cp[0] << 8) \
316	    | ((uint16_t)t_cp[1]) \
317	    ; \
318	(cp) += 2; \
319}
320
321#define SDP_GET32(l, cp) { \
322	register uint8_t *t_cp = (uint8_t *)(cp); \
323	(l) = ((uint32_t)t_cp[0] << 24) \
324	    | ((uint32_t)t_cp[1] << 16) \
325	    | ((uint32_t)t_cp[2] << 8) \
326	    | ((uint32_t)t_cp[3]) \
327	    ; \
328	(cp) += 4; \
329}
330
331#define SDP_GET64(l, cp) { \
332	register uint8_t *t_cp = (uint8_t *)(cp); \
333	(l) = ((uint64_t)t_cp[0] << 56) \
334	    | ((uint64_t)t_cp[1] << 48) \
335	    | ((uint64_t)t_cp[2] << 40) \
336	    | ((uint64_t)t_cp[3] << 32) \
337	    | ((uint64_t)t_cp[4] << 24) \
338	    | ((uint64_t)t_cp[5] << 16) \
339	    | ((uint64_t)t_cp[6] << 8) \
340	    | ((uint64_t)t_cp[7]) \
341	    ; \
342	(cp) += 8; \
343}
344
345#if BYTE_ORDER == LITTLE_ENDIAN
346#define SDP_GET128(l, cp) { \
347	register uint8_t *t_cp = (uint8_t *)(cp); \
348	(l)->b[15] = *t_cp++; \
349	(l)->b[14] = *t_cp++; \
350	(l)->b[13] = *t_cp++; \
351	(l)->b[12] = *t_cp++; \
352	(l)->b[11] = *t_cp++; \
353	(l)->b[10] = *t_cp++; \
354	(l)->b[9]  = *t_cp++; \
355	(l)->b[8]  = *t_cp++; \
356	(l)->b[7]  = *t_cp++; \
357	(l)->b[6]  = *t_cp++; \
358	(l)->b[5]  = *t_cp++; \
359	(l)->b[4]  = *t_cp++; \
360	(l)->b[3]  = *t_cp++; \
361	(l)->b[2]  = *t_cp++; \
362	(l)->b[1]  = *t_cp++; \
363	(l)->b[0]  = *t_cp++; \
364	(cp) += 16; \
365}
366
367#define SDP_GET_UUID128(l, cp) { \
368	register uint8_t *t_cp = (uint8_t *)(cp); \
369	(l)->b[0]  = *t_cp++; \
370	(l)->b[1]  = *t_cp++; \
371	(l)->b[2]  = *t_cp++; \
372	(l)->b[3]  = *t_cp++; \
373	(l)->b[4]  = *t_cp++; \
374	(l)->b[5]  = *t_cp++; \
375	(l)->b[6]  = *t_cp++; \
376	(l)->b[7]  = *t_cp++; \
377	(l)->b[8]  = *t_cp++; \
378	(l)->b[9]  = *t_cp++; \
379	(l)->b[10] = *t_cp++; \
380	(l)->b[11] = *t_cp++; \
381	(l)->b[12] = *t_cp++; \
382	(l)->b[13] = *t_cp++; \
383	(l)->b[14] = *t_cp++; \
384	(l)->b[15] = *t_cp++; \
385	(cp) += 16; \
386}
387#elif BYTE_ORDER == BIG_ENDIAN
388#define SDP_GET128(l, cp) { \
389	register uint8_t *t_cp = (uint8_t *)(cp); \
390	(l)->b[0]  = *t_cp++; \
391	(l)->b[1]  = *t_cp++; \
392	(l)->b[2]  = *t_cp++; \
393	(l)->b[3]  = *t_cp++; \
394	(l)->b[4]  = *t_cp++; \
395	(l)->b[5]  = *t_cp++; \
396	(l)->b[6]  = *t_cp++; \
397	(l)->b[7]  = *t_cp++; \
398	(l)->b[8]  = *t_cp++; \
399	(l)->b[9]  = *t_cp++; \
400	(l)->b[10] = *t_cp++; \
401	(l)->b[11] = *t_cp++; \
402	(l)->b[12] = *t_cp++; \
403	(l)->b[13] = *t_cp++; \
404	(l)->b[14] = *t_cp++; \
405	(l)->b[15] = *t_cp++; \
406	(cp) += 16; \
407}
408
409#define	SDP_GET_UUID128(l, cp)	SDP_GET128(l, cp)
410#else
411#error	"Unsupported BYTE_ORDER"
412#endif /* BYTE_ORDER */
413
414#define SDP_PUT8(b, cp) { \
415	register uint8_t t_b = (uint8_t)(b); \
416	register uint8_t *t_cp = (uint8_t *)(cp); \
417	*t_cp = t_b; \
418	(cp) ++; \
419}
420
421#define SDP_PUT16(s, cp) { \
422	register uint16_t t_s = (uint16_t)(s); \
423	register uint8_t *t_cp = (uint8_t *)(cp); \
424	*t_cp++ = t_s >> 8; \
425	*t_cp   = t_s; \
426	(cp) += 2; \
427}
428
429#define SDP_PUT32(l, cp) { \
430	register uint32_t t_l = (uint32_t)(l); \
431	register uint8_t *t_cp = (uint8_t *)(cp); \
432	*t_cp++ = t_l >> 24; \
433	*t_cp++ = t_l >> 16; \
434	*t_cp++ = t_l >> 8; \
435	*t_cp   = t_l; \
436	(cp) += 4; \
437}
438
439#define SDP_PUT64(l, cp) { \
440	register uint64_t t_l = (uint64_t)(l); \
441	register uint8_t *t_cp = (uint8_t *)(cp); \
442	*t_cp++ = t_l >> 56; \
443	*t_cp++ = t_l >> 48; \
444	*t_cp++ = t_l >> 40; \
445	*t_cp++ = t_l >> 32; \
446	*t_cp++ = t_l >> 24; \
447	*t_cp++ = t_l >> 16; \
448	*t_cp++ = t_l >> 8; \
449	*t_cp   = t_l; \
450	(cp) += 8; \
451}
452
453#if BYTE_ORDER == LITTLE_ENDIAN
454#define SDP_PUT128(l, cp) { \
455	register uint8_t *t_cp = (uint8_t *)(cp); \
456	*t_cp++ = (l)->b[15]; \
457	*t_cp++ = (l)->b[14]; \
458	*t_cp++ = (l)->b[13]; \
459	*t_cp++ = (l)->b[12]; \
460	*t_cp++ = (l)->b[11]; \
461	*t_cp++ = (l)->b[10]; \
462	*t_cp++ = (l)->b[9];  \
463	*t_cp++ = (l)->b[8];  \
464	*t_cp++ = (l)->b[7];  \
465	*t_cp++ = (l)->b[6];  \
466	*t_cp++ = (l)->b[5];  \
467	*t_cp++ = (l)->b[4];  \
468	*t_cp++ = (l)->b[3];  \
469	*t_cp++ = (l)->b[2];  \
470	*t_cp++ = (l)->b[1];  \
471	*t_cp   = (l)->b[0];  \
472	(cp) += 16; \
473}
474
475#define SDP_PUT_UUID128(l, cp) { \
476	register uint8_t *t_cp = (uint8_t *)(cp); \
477	*t_cp++ = (l)->b[0];  \
478	*t_cp++ = (l)->b[1];  \
479	*t_cp++ = (l)->b[2];  \
480	*t_cp++ = (l)->b[3];  \
481	*t_cp++ = (l)->b[4];  \
482	*t_cp++ = (l)->b[5];  \
483	*t_cp++ = (l)->b[6];  \
484	*t_cp++ = (l)->b[7];  \
485	*t_cp++ = (l)->b[8];  \
486	*t_cp++ = (l)->b[9];  \
487	*t_cp++ = (l)->b[10]; \
488	*t_cp++ = (l)->b[11]; \
489	*t_cp++ = (l)->b[12]; \
490	*t_cp++ = (l)->b[13]; \
491	*t_cp++ = (l)->b[14]; \
492	*t_cp   = (l)->b[15]; \
493	(cp) += 16; \
494}
495#elif BYTE_ORDER == BIG_ENDIAN
496#define SDP_PUT128(l, cp) { \
497	register uint8_t *t_cp = (uint8_t *)(cp); \
498	*t_cp++ = (l)->b[0];  \
499	*t_cp++ = (l)->b[1];  \
500	*t_cp++ = (l)->b[2];  \
501	*t_cp++ = (l)->b[3];  \
502	*t_cp++ = (l)->b[4];  \
503	*t_cp++ = (l)->b[5];  \
504	*t_cp++ = (l)->b[6];  \
505	*t_cp++ = (l)->b[7];  \
506	*t_cp++ = (l)->b[8];  \
507	*t_cp++ = (l)->b[9];  \
508	*t_cp++ = (l)->b[10]; \
509	*t_cp++ = (l)->b[11]; \
510	*t_cp++ = (l)->b[12]; \
511	*t_cp++ = (l)->b[13]; \
512	*t_cp++ = (l)->b[14]; \
513	*t_cp   = (l)->b[15]; \
514	(cp) += 16; \
515}
516
517#define SDP_PUT_UUID128(l, cp)	SDP_PUT128(l, cp)
518#else
519#error	"Unsupported BYTE_ORDER"
520#endif /* BYTE_ORDER */
521
522void *             sdp_open       (bdaddr_t const *l, bdaddr_t const *r);
523void *             sdp_open_local (char const *control);
524int32_t            sdp_close      (void *xs);
525int32_t            sdp_error      (void *xs);
526
527int32_t            sdp_search     (void *xs,
528                                   uint32_t plen, uint16_t const *pp,
529                                   uint32_t alen, uint32_t const *ap,
530                                   uint32_t vlen, sdp_attr_t *vp);
531
532char const * const sdp_attr2desc  (uint16_t attr);
533char const * const sdp_uuid2desc  (uint16_t uuid);
534void               sdp_print      (uint32_t level, uint8_t const *start,
535                                   uint8_t const *end);
536
537/******************************************************************************
538 * sdpd interface and Bluetooth profiles data
539 *****************************************************************************/
540
541#define SDP_LOCAL_PATH	"/var/run/sdp"
542#define SDP_LOCAL_MTU	4096
543
544/*
545 * These are NOT defined in spec and only accepted on control sockets.
546 * The response to these request always will be SDP_PDU_ERROR_RESPONSE.
547 * The first 2 bytes (after PDU header) is an error code (in network
548 * byte order). The rest of the data (pdu->len - 2) is a response data
549 * and depend on the request.
550 *
551 * SDP_PDU_SERVICE_REGISTER_REQUEST
552 * 	pdu_header_t	hdr;
553 *	u_int16_t	uuid;	service class UUID (network byte order)
554 *	bdaddr_t	bdaddr;	local BD_ADDR (or ANY)
555 *	profile data[pdu->len - sizeof(uuid) - sizeof(bdaddr)]
556 *
557 * in successful reponse additional data will contain 4 bytes record handle
558 *
559 *
560 * SDP_PDU_SERVICE_UNREGISTER_REQUEST
561 *	pdu_header_t	hdr;
562 *	u_int32_t	record_handle;	(network byte order)
563 *
564 * no additional data in response.
565 *
566 *
567 * SDP_PDU_SERVICE_CHANGE_REQUEST
568 * 	pdu_header_t	hdr;
569 *	u_int32_t	record_handle;	(network byte order)
570 *	profile data[pdu->len - sizeof(record_handle)]
571 *
572 * no additional data in response.
573 */
574
575#define SDP_PDU_SERVICE_REGISTER_REQUEST	0x81
576#define SDP_PDU_SERVICE_UNREGISTER_REQUEST	0x82
577#define SDP_PDU_SERVICE_CHANGE_REQUEST		0x83
578
579struct sdp_dun_profile
580{
581	uint8_t	server_channel;
582	uint8_t	audio_feedback_support;
583	uint8_t	reserved[2];
584};
585typedef struct sdp_dun_profile		sdp_dun_profile_t;
586typedef struct sdp_dun_profile *	sdp_dun_profile_p;
587
588struct sdp_ftrn_profile
589{
590	uint8_t	server_channel;
591	uint8_t	reserved[3];
592};
593typedef struct sdp_ftrn_profile		sdp_ftrn_profile_t;
594typedef struct sdp_ftrn_profile *	sdp_ftrn_profile_p;
595
596/* Keep this in sync with sdp_opush_profile */
597struct sdp_irmc_profile
598{
599	uint8_t	server_channel;
600	uint8_t	supported_formats_size;
601	uint8_t	supported_formats[30];
602};
603typedef struct sdp_irmc_profile		sdp_irmc_profile_t;
604typedef struct sdp_irmc_profile *	sdp_irmc_profile_p;
605
606struct sdp_irmc_command_profile
607{
608	uint8_t	server_channel;
609	uint8_t	reserved[3];
610};
611typedef struct sdp_irmc_command_profile		sdp_irmc_command_profile_t;
612typedef struct sdp_irmc_command_profile *	sdp_irmc_command_profile_p;
613
614struct sdp_lan_profile
615{
616	uint8_t		server_channel;
617	uint8_t		load_factor;
618	uint8_t		reserved;
619	uint8_t		ip_subnet_radius;
620	uint32_t	ip_subnet;
621};
622typedef struct sdp_lan_profile		sdp_lan_profile_t;
623typedef struct sdp_lan_profile *	sdp_lan_profile_p;
624
625/* Keep this in sync with sdp_irmc_profile */
626struct sdp_opush_profile
627{
628	uint8_t	server_channel;
629	uint8_t	supported_formats_size;
630	uint8_t	supported_formats[30];
631};
632typedef struct sdp_opush_profile	sdp_opush_profile_t;
633typedef struct sdp_opush_profile *	sdp_opush_profile_p;
634
635struct sdp_sp_profile
636{
637	uint8_t	server_channel;
638	uint8_t	reserved[3];
639};
640typedef struct sdp_sp_profile	sdp_sp_profile_t;
641typedef struct sdp_sp_profile *	sdp_sp_profile_p;
642
643int32_t	sdp_register_service	(void *xss, uint16_t uuid,
644				 bdaddr_p const bdaddr, uint8_t const *data,
645				 uint32_t datalen, uint32_t *handle);
646int32_t	sdp_unregister_service	(void *xss, uint32_t handle);
647int32_t	sdp_change_service	(void *xss, uint32_t handle,
648				 uint8_t const *data, uint32_t datalen);
649
650__END_DECLS
651
652#endif /* ndef _SDP_H_ */
653
654