Home | History | Annotate | Download | only in bluetooth
      1 /*
      2  *
      3  *  BlueZ - Bluetooth protocol stack for Linux
      4  *
      5  *  Copyright (C) 2001-2002  Nokia Corporation
      6  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk (at) qualcomm.com>
      7  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel (at) holtmann.org>
      8  *  Copyright (C) 2002-2003  Stephen Crane <steve.crane (at) rococosoft.com>
      9  *
     10  *
     11  *  This program is free software; you can redistribute it and/or modify
     12  *  it under the terms of the GNU General Public License as published by
     13  *  the Free Software Foundation; either version 2 of the License, or
     14  *  (at your option) any later version.
     15  *
     16  *  This program is distributed in the hope that it will be useful,
     17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19  *  GNU General Public License for more details.
     20  *
     21  *  You should have received a copy of the GNU General Public License
     22  *  along with this program; if not, write to the Free Software
     23  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     24  *
     25  */
     26 
     27 #ifndef __SDP_LIB_H
     28 #define __SDP_LIB_H
     29 
     30 #include <sys/socket.h>
     31 #include <bluetooth/bluetooth.h>
     32 #include <bluetooth/hci.h>
     33 
     34 #ifdef __cplusplus
     35 extern "C" {
     36 #endif
     37 
     38 /*
     39  * SDP lists
     40  */
     41 typedef void(*sdp_list_func_t)(void *, void *);
     42 typedef void(*sdp_free_func_t)(void *);
     43 typedef int (*sdp_comp_func_t)(const void *, const void *);
     44 
     45 sdp_list_t *sdp_list_append(sdp_list_t *list, void *d);
     46 sdp_list_t *sdp_list_remove(sdp_list_t *list, void *d);
     47 sdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *data, sdp_comp_func_t f);
     48 void        sdp_list_free(sdp_list_t *list, sdp_free_func_t f);
     49 
     50 static inline int sdp_list_len(const sdp_list_t *list)
     51 {
     52 	int n = 0;
     53 	for (; list; list = list->next)
     54 		n++;
     55 	return n;
     56 }
     57 
     58 static inline sdp_list_t *sdp_list_find(sdp_list_t *list, void *u, sdp_comp_func_t f)
     59 {
     60 	for (; list; list = list->next)
     61 		if (f(list->data, u) == 0)
     62 			return list;
     63 	return NULL;
     64 }
     65 
     66 static inline void sdp_list_foreach(sdp_list_t *list, sdp_list_func_t f, void *u)
     67 {
     68 	for (; list; list = list->next)
     69 		f(list->data, u);
     70 }
     71 
     72 /*
     73  * Values of the flags parameter to sdp_record_register
     74  */
     75 #define SDP_RECORD_PERSIST	0x01
     76 #define SDP_DEVICE_RECORD	0x02
     77 
     78 /*
     79  * Values of the flags parameter to sdp_connect
     80  */
     81 #define SDP_RETRY_IF_BUSY	0x01
     82 #define SDP_WAIT_ON_CLOSE	0x02
     83 #define SDP_NON_BLOCKING	0x04
     84 
     85 /*
     86  * a session with an SDP server
     87  */
     88 typedef struct {
     89 	int sock;
     90 	int state;
     91 	int local;
     92 	int flags;
     93 	uint16_t tid;	/* Current transaction ID */
     94 	void *priv;
     95 } sdp_session_t;
     96 
     97 typedef enum {
     98 	/*
     99 	 *  Attributes are specified as individual elements
    100 	 */
    101 	SDP_ATTR_REQ_INDIVIDUAL = 1,
    102 	/*
    103 	 *  Attributes are specified as a range
    104 	 */
    105 	SDP_ATTR_REQ_RANGE
    106 } sdp_attrreq_type_t;
    107 
    108 /*
    109  * 	When the pdu_id(type) is a sdp error response, check the status value
    110  * 	to figure out the error reason. For status values 0x0001-0x0006 check
    111  * 	Bluetooth SPEC. If the status is 0xffff, call sdp_get_error function
    112  * 	to get the real reason:
    113  * 	    - wrong transaction ID(EPROTO)
    114  * 	    - wrong PDU id or(EPROTO)
    115  * 	    - I/O error
    116  */
    117 typedef void sdp_callback_t(uint8_t type, uint16_t status, uint8_t *rsp, size_t size, void *udata);
    118 
    119 /*
    120  * create an L2CAP connection to a Bluetooth device
    121  *
    122  * INPUT:
    123  *
    124  *  bdaddr_t *src:
    125  *	Address of the local device to use to make the connection
    126  *	(or BDADDR_ANY)
    127  *
    128  *  bdaddr_t *dst:
    129  *    Address of the SDP server device
    130  */
    131 sdp_session_t *sdp_connect(const bdaddr_t *src, const bdaddr_t *dst, uint32_t flags);
    132 int sdp_close(sdp_session_t *session);
    133 int sdp_get_socket(const sdp_session_t *session);
    134 
    135 /*
    136  * SDP transaction: functions for asynchronous search.
    137  */
    138 sdp_session_t *sdp_create(int sk, uint32_t flags);
    139 int sdp_get_error(sdp_session_t *session);
    140 int sdp_process(sdp_session_t *session);
    141 int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata);
    142 
    143 int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num);
    144 int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list);
    145 int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list);
    146 
    147 uint16_t sdp_gen_tid(sdp_session_t *session);
    148 
    149 /*
    150  * find all devices in the piconet
    151  */
    152 int sdp_general_inquiry(inquiry_info *ii, int dev_num, int duration, uint8_t *found);
    153 
    154 /* flexible extraction of basic attributes - Jean II */
    155 int sdp_get_int_attr(const sdp_record_t *rec, uint16_t attr, int *value);
    156 int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attr, char *value, int valuelen);
    157 
    158 /*
    159  * Basic sdp data functions
    160  */
    161 sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value);
    162 sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value, uint32_t length);
    163 void sdp_data_free(sdp_data_t *data);
    164 sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attr_id);
    165 
    166 sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len);
    167 sdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length, int len);
    168 sdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *data);
    169 
    170 int sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *data);
    171 void sdp_attr_remove(sdp_record_t *rec, uint16_t attr);
    172 void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *data);
    173 int sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t attr, sdp_list_t *seq);
    174 int sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, sdp_list_t **seqp);
    175 
    176 /*
    177  * NOTE that none of the functions below will update the SDP server,
    178  * unless the {register, update}sdp_record_t() function is invoked.
    179  * All functions which return an integer value, return 0 on success
    180  * or -1 on failure.
    181  */
    182 
    183 /*
    184  * Create an attribute and add it to the service record's attribute list.
    185  * This consists of the data type descriptor of the attribute,
    186  * the value of the attribute and the attribute identifier.
    187  */
    188 int sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd, const void *p);
    189 
    190 /*
    191  * Set the information attributes of the service record.
    192  * The set of attributes comprises service name, description
    193  * and provider name
    194  */
    195 void sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov, const char *desc);
    196 
    197 /*
    198  * Set the ServiceClassID attribute to the sequence specified by seq.
    199  * Note that the identifiers need to be in sorted order from the most
    200  * specific to the most generic service class that this service
    201  * conforms to.
    202  */
    203 static inline int sdp_set_service_classes(sdp_record_t *rec, sdp_list_t *seq)
    204 {
    205 	return sdp_set_uuidseq_attr(rec, SDP_ATTR_SVCLASS_ID_LIST, seq);
    206 }
    207 
    208 /*
    209  * Get the service classes to which the service conforms.
    210  *
    211  * When set, the list contains elements of ServiceClassIdentifer(uint16_t)
    212  * ordered from most specific to most generic
    213  */
    214 static inline int sdp_get_service_classes(const sdp_record_t *rec, sdp_list_t **seqp)
    215 {
    216 	return sdp_get_uuidseq_attr(rec, SDP_ATTR_SVCLASS_ID_LIST, seqp);
    217 }
    218 
    219 /*
    220  * Set the BrowseGroupList attribute to the list specified by seq.
    221  *
    222  * A service can belong to one or more service groups
    223  * and the list comprises such group identifiers (UUIDs)
    224  */
    225 static inline int sdp_set_browse_groups(sdp_record_t *rec, sdp_list_t *seq)
    226 {
    227 	return sdp_set_uuidseq_attr(rec, SDP_ATTR_BROWSE_GRP_LIST, seq);
    228 }
    229 
    230 /*
    231  * Set the access protocols of the record to those specified in proto
    232  */
    233 int sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *proto);
    234 
    235 /*
    236  * Set the additional access protocols of the record to those specified in proto
    237  */
    238 int sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *proto);
    239 
    240 /*
    241  * Get protocol port (i.e. PSM for L2CAP, Channel for RFCOMM)
    242  */
    243 int sdp_get_proto_port(const sdp_list_t *list, int proto);
    244 
    245 /*
    246  * Get protocol descriptor.
    247  */
    248 sdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto);
    249 
    250 /*
    251  * Set the LanguageBase attributes to the values specified in list
    252  * (a linked list of sdp_lang_attr_t objects, one for each language in
    253  * which user-visible attributes are present).
    254  */
    255 int sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *list);
    256 
    257 /*
    258  * Set the ServiceInfoTimeToLive attribute of the service.
    259  * This is the number of seconds that this record is guaranteed
    260  * not to change after being obtained by a client.
    261  */
    262 static inline int sdp_set_service_ttl(sdp_record_t *rec, uint32_t ttl)
    263 {
    264 	return sdp_attr_add_new(rec, SDP_ATTR_SVCINFO_TTL, SDP_UINT32, &ttl);
    265 }
    266 
    267 /*
    268  * Set the ServiceRecordState attribute of a service. This is
    269  * guaranteed to change if there is any kind of modification to
    270  * the record.
    271  */
    272 static inline int sdp_set_record_state(sdp_record_t *rec, uint32_t state)
    273 {
    274 	return sdp_attr_add_new(rec, SDP_ATTR_RECORD_STATE, SDP_UINT32, &state);
    275 }
    276 
    277 /*
    278  * Set the ServiceID attribute of a service.
    279  */
    280 void sdp_set_service_id(sdp_record_t *rec, uuid_t uuid);
    281 
    282 /*
    283  * Set the GroupID attribute of a service
    284  */
    285 void sdp_set_group_id(sdp_record_t *rec, uuid_t grouuuid);
    286 
    287 /*
    288  * Set the ServiceAvailability attribute of a service.
    289  *
    290  * Note that this represents the relative availability
    291  * of the service: 0x00 means completely unavailable;
    292  * 0xFF means maximum availability.
    293  */
    294 static inline int sdp_set_service_avail(sdp_record_t *rec, uint8_t avail)
    295 {
    296 	return sdp_attr_add_new(rec, SDP_ATTR_SERVICE_AVAILABILITY, SDP_UINT8, &avail);
    297 }
    298 
    299 /*
    300  * Set the profile descriptor list attribute of a record.
    301  *
    302  * Each element in the list is an object of type
    303  * sdp_profile_desc_t which is a definition of the
    304  * Bluetooth profile that this service conforms to.
    305  */
    306 int sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *desc);
    307 
    308 /*
    309  * Set URL attributes of a record.
    310  *
    311  * ClientExecutableURL: a URL to a client's platform specific (WinCE,
    312  * PalmOS) executable code that can be used to access this service.
    313  *
    314  * DocumentationURL: a URL pointing to service documentation
    315  *
    316  * IconURL: a URL to an icon that can be used to represent this service.
    317  *
    318  * Note: pass NULL for any URLs that you don't want to set or remove
    319  */
    320 void sdp_set_url_attr(sdp_record_t *rec, const char *clientExecURL, const char *docURL, const char *iconURL);
    321 
    322 /*
    323  * a service search request.
    324  *
    325  *  INPUT :
    326  *
    327  *    sdp_list_t *search
    328  *      list containing elements of the search
    329  *      pattern. Each entry in the list is a UUID
    330  *      of the service to be searched
    331  *
    332  *    uint16_t max_rec_num
    333  *       An integer specifying the maximum number of
    334  *       entries that the client can handle in the response.
    335  *
    336  *  OUTPUT :
    337  *
    338  *    int return value
    339  *      0
    340  *        The request completed successfully. This does not
    341  *        mean the requested services were found
    342  *      -1
    343  *        The request completed unsuccessfully
    344  *
    345  *    sdp_list_t *rsp_list
    346  *      This variable is set on a successful return if there are
    347  *      non-zero service handles. It is a singly linked list of
    348  *      service record handles (uint16_t)
    349  */
    350 int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num, sdp_list_t **rsp_list);
    351 
    352 /*
    353  *  a service attribute request.
    354  *
    355  *  INPUT :
    356  *
    357  *    uint32_t handle
    358  *      The handle of the service for which the attribute(s) are
    359  *      requested
    360  *
    361  *    sdp_attrreq_type_t reqtype
    362  *      Attribute identifiers are 16 bit unsigned integers specified
    363  *      in one of 2 ways described below :
    364  *      SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
    365  *         They are the actual attribute identifiers in ascending order
    366  *
    367  *      SDP_ATTR_REQ_RANGE - 32bit identifier range
    368  *         The high-order 16bits is the start of range
    369  *         the low-order 16bits are the end of range
    370  *         0x0000 to 0xFFFF gets all attributes
    371  *
    372  *    sdp_list_t *attrid_list
    373  *      Singly linked list containing attribute identifiers desired.
    374  *      Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
    375  *      or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
    376  *
    377  *  OUTPUT :
    378  *    int return value
    379  *      0
    380  *        The request completed successfully. This does not
    381  *        mean the requested services were found
    382  *      -1
    383  *        The request completed unsuccessfully due to a timeout
    384  */
    385 sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list);
    386 
    387 /*
    388  *  This is a service search request combined with the service
    389  *  attribute request. First a service class match is done and
    390  *  for matching service, requested attributes are extracted
    391  *
    392  *  INPUT :
    393  *
    394  *    sdp_list_t *search
    395  *      Singly linked list containing elements of the search
    396  *      pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
    397  *      of the service to be searched
    398  *
    399  *    AttributeSpecification attrSpec
    400  *      Attribute identifiers are 16 bit unsigned integers specified
    401  *      in one of 2 ways described below :
    402  *      SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
    403  *         They are the actual attribute identifiers in ascending order
    404  *
    405  *      SDP_ATTR_REQ_RANGE - 32bit identifier range
    406  *         The high-order 16bits is the start of range
    407  *         the low-order 16bits are the end of range
    408  *         0x0000 to 0xFFFF gets all attributes
    409  *
    410  *    sdp_list_t *attrid_list
    411  *      Singly linked list containing attribute identifiers desired.
    412  *      Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
    413  *      or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
    414  *
    415  *  OUTPUT :
    416  *    int return value
    417  *      0
    418  *        The request completed successfully. This does not
    419  *        mean the requested services were found
    420  *      -1
    421  *        The request completed unsuccessfully due to a timeout
    422  *
    423  *    sdp_list_t *rsp_list
    424  *      This variable is set on a successful return to point to
    425  *      service(s) found. Each element of this list is of type
    426  *      sdp_record_t *.
    427  */
    428 int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list, sdp_list_t **rsp_list);
    429 
    430 /*
    431  * Allocate/free a service record and its attributes
    432  */
    433 sdp_record_t *sdp_record_alloc(void);
    434 void sdp_record_free(sdp_record_t *rec);
    435 
    436 /*
    437  * Register a service record.
    438  *
    439  * Note: It is the responsbility of the Service Provider to create the
    440  * record first and set its attributes using setXXX() methods.
    441  *
    442  * The service provider must then call sdp_record_register() to make
    443  * the service record visible to SDP clients.  This function returns 0
    444  * on success or -1 on failure (and sets errno).
    445  */
    446 int sdp_device_record_register_binary(sdp_session_t *session, bdaddr_t *device, uint8_t *data, uint32_t size, uint8_t flags, uint32_t *handle);
    447 int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags);
    448 int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags);
    449 
    450 /*
    451  * Unregister a service record.
    452  */
    453 int sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle);
    454 int sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec);
    455 int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec);
    456 
    457 /*
    458  * Update an existing service record.  (Calling this function
    459  * before a previous call to sdp_record_register() will result
    460  * in an error.)
    461  */
    462 int sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size);
    463 int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec);
    464 int sdp_record_update(sdp_session_t *sess, const sdp_record_t *rec);
    465 
    466 void sdp_record_print(const sdp_record_t *rec);
    467 
    468 /*
    469  * UUID functions
    470  */
    471 uuid_t *sdp_uuid16_create(uuid_t *uuid, uint16_t data);
    472 uuid_t *sdp_uuid32_create(uuid_t *uuid, uint32_t data);
    473 uuid_t *sdp_uuid128_create(uuid_t *uuid, const void *data);
    474 int sdp_uuid16_cmp(const void *p1, const void *p2);
    475 int sdp_uuid128_cmp(const void *p1, const void *p2);
    476 int sdp_uuid_cmp(const void *p1, const void *p2);
    477 uuid_t *sdp_uuid_to_uuid128(const uuid_t *uuid);
    478 void sdp_uuid16_to_uuid128(uuid_t *uuid128, const uuid_t *uuid16);
    479 void sdp_uuid32_to_uuid128(uuid_t *uuid128, const uuid_t *uuid32);
    480 int sdp_uuid128_to_uuid(uuid_t *uuid);
    481 int sdp_uuid_to_proto(uuid_t *uuid);
    482 int sdp_uuid_extract(const uint8_t *buffer, int bufsize, uuid_t *uuid, int *scanned);
    483 void sdp_uuid_print(const uuid_t *uuid);
    484 
    485 #define MAX_LEN_UUID_STR 37
    486 #define MAX_LEN_PROTOCOL_UUID_STR 8
    487 #define MAX_LEN_SERVICECLASS_UUID_STR 28
    488 #define MAX_LEN_PROFILEDESCRIPTOR_UUID_STR 28
    489 
    490 int sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n);
    491 int sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n);
    492 int sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n);
    493 int sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n);
    494 
    495 /*
    496  * In all the sdp_get_XXX(handle, XXX *xxx) functions below,
    497  * the XXX * is set to point to the value, should it exist
    498  * and 0 is returned. If the value does not exist, -1 is
    499  * returned and errno set to ENODATA.
    500  *
    501  * In all the methods below, the memory management rules are
    502  * simple. Don't free anything! The pointer returned, in the
    503  * case of constructed types, is a pointer to the contents
    504  * of the sdp_record_t.
    505  */
    506 
    507 /*
    508  * Get the access protocols from the service record
    509  */
    510 int sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **protos);
    511 
    512 /*
    513  * Get the additional access protocols from the service record
    514  */
    515 int sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **protos);
    516 
    517 /*
    518  * Extract the list of browse groups to which the service belongs.
    519  * When set, seqp contains elements of GroupID (uint16_t)
    520  */
    521 static inline int sdp_get_browse_groups(const sdp_record_t *rec, sdp_list_t **seqp)
    522 {
    523 	return sdp_get_uuidseq_attr(rec, SDP_ATTR_BROWSE_GRP_LIST, seqp);
    524 }
    525 
    526 /*
    527  * Extract language attribute meta-data of the service record.
    528  * For each language in the service record, LangSeq has a struct of type
    529  * sdp_lang_attr_t.
    530  */
    531 int sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq);
    532 
    533 /*
    534  * Extract the Bluetooth profile descriptor sequence from a record.
    535  * Each element in the list is of type sdp_profile_desc_t
    536  * which contains the UUID of the profile and its version number
    537  * (encoded as major and minor in the high-order 8bits
    538  * and low-order 8bits respectively of the uint16_t)
    539  */
    540 int sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDesc);
    541 
    542 /*
    543  * Extract SDP server version numbers
    544  *
    545  * Note: that this is an attribute of the SDP server only and
    546  * contains a list of uint16_t each of which represent the
    547  * major and minor SDP version numbers supported by this server
    548  */
    549 int sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **pVnumList);
    550 
    551 int sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid);
    552 int sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid);
    553 int sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState);
    554 int sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail);
    555 int sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo);
    556 int sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState);
    557 
    558 static inline int sdp_get_service_name(const sdp_record_t *rec, char *str, int len)
    559 {
    560 	return sdp_get_string_attr(rec, SDP_ATTR_SVCNAME_PRIMARY, str, len);
    561 }
    562 
    563 static inline int sdp_get_service_desc(const sdp_record_t *rec, char *str, int len)
    564 {
    565 	return sdp_get_string_attr(rec, SDP_ATTR_SVCDESC_PRIMARY, str, len);
    566 }
    567 
    568 static inline int sdp_get_provider_name(const sdp_record_t *rec, char *str, int len)
    569 {
    570 	return sdp_get_string_attr(rec, SDP_ATTR_PROVNAME_PRIMARY, str, len);
    571 }
    572 
    573 static inline int sdp_get_doc_url(const sdp_record_t *rec, char *str, int len)
    574 {
    575 	return sdp_get_string_attr(rec, SDP_ATTR_DOC_URL, str, len);
    576 }
    577 
    578 static inline int sdp_get_clnt_exec_url(const sdp_record_t *rec, char *str, int len)
    579 {
    580 	return sdp_get_string_attr(rec, SDP_ATTR_CLNT_EXEC_URL, str, len);
    581 }
    582 
    583 static inline int sdp_get_icon_url(const sdp_record_t *rec, char *str, int len)
    584 {
    585 	return sdp_get_string_attr(rec, SDP_ATTR_ICON_URL, str, len);
    586 }
    587 
    588 /*
    589  * Set the supported features
    590  * sf should be a list of list with each feature data
    591  * Returns 0 on success -1 on fail
    592  */
    593 int sdp_set_supp_feat(sdp_record_t *rec, const sdp_list_t *sf);
    594 
    595 /*
    596  * Get the supported features
    597  * seqp is set to a list of list with each feature data
    598  * Returns 0 on success, if an error occurred -1 is returned and errno is set
    599  */
    600 int sdp_get_supp_feat(const sdp_record_t *rec, sdp_list_t **seqp);
    601 
    602 sdp_record_t *sdp_extract_pdu(const uint8_t *pdata, int bufsize, int *scanned);
    603 sdp_record_t *sdp_copy_record(sdp_record_t *rec);
    604 
    605 void sdp_data_print(sdp_data_t *data);
    606 void sdp_print_service_attr(sdp_list_t *alist);
    607 
    608 int sdp_attrid_comp_func(const void *key1, const void *key2);
    609 
    610 void sdp_set_seq_len(uint8_t *ptr, uint32_t length);
    611 void sdp_set_attrid(sdp_buf_t *pdu, uint16_t id);
    612 void sdp_append_to_pdu(sdp_buf_t *dst, sdp_data_t *d);
    613 void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len);
    614 
    615 int sdp_gen_pdu(sdp_buf_t *pdu, sdp_data_t *data);
    616 int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *pdu);
    617 
    618 int sdp_extract_seqtype(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size);
    619 
    620 sdp_data_t *sdp_extract_attr(const uint8_t *pdata, int bufsize, int *extractedLength, sdp_record_t *rec);
    621 
    622 void sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid);
    623 void sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq);
    624 
    625 int sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *req, uint8_t *rsp, uint32_t reqsize, uint32_t *rspsize);
    626 
    627 #ifdef __cplusplus
    628 }
    629 #endif
    630 
    631 #endif /* __SDP_LIB_H */
    632