OSDN Git Service

build: Add --enable-midi to bootstrap-configure
[android-x86/external-bluetooth-bluez.git] / lib / sdp.c
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@qualcomm.com>
7  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
8  *  Copyright (C) 2002-2003  Stephen Crane <steve.crane@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 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #include <stdio.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <limits.h>
37 #include <string.h>
38 #include <syslog.h>
39 #include <sys/time.h>
40 #include <sys/types.h>
41 #include <sys/socket.h>
42 #include <sys/un.h>
43 #include <netinet/in.h>
44
45 #include "bluetooth.h"
46 #include "hci.h"
47 #include "hci_lib.h"
48 #include "l2cap.h"
49 #include "sdp.h"
50 #include "sdp_lib.h"
51
52 #define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg)
53 #define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg)
54
55 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
56
57 #ifdef SDP_DEBUG
58 #define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg)
59 #else
60 #define SDPDBG(fmt...)
61 #endif
62
63 static uint128_t bluetooth_base_uuid = {
64         .data = {       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
65                         0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }
66 };
67
68 #define SDP_MAX_ATTR_LEN 65535
69
70 /* match MTU used by RFCOMM */
71 #define SDP_LARGE_L2CAP_MTU 1013
72
73 static sdp_data_t *sdp_copy_seq(sdp_data_t *data);
74 static int sdp_attr_add_new_with_length(sdp_record_t *rec,
75         uint16_t attr, uint8_t dtd, const void *value, uint32_t len);
76 static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d);
77
78 /* Message structure. */
79 struct tupla {
80         int index;
81         char *str;
82 };
83
84 static struct tupla Protocol[] = {
85         { SDP_UUID,             "SDP"           },
86         { UDP_UUID,             "UDP"           },
87         { RFCOMM_UUID,          "RFCOMM"        },
88         { TCP_UUID,             "TCP"           },
89         { TCS_BIN_UUID,         "TCS-BIN"       },
90         { TCS_AT_UUID,          "TCS-AT"        },
91         { OBEX_UUID,            "OBEX"          },
92         { IP_UUID,              "IP"            },
93         { FTP_UUID,             "FTP"           },
94         { HTTP_UUID,            "HTTP"          },
95         { WSP_UUID,             "WSP"           },
96         { BNEP_UUID,            "BNEP"          },
97         { UPNP_UUID,            "UPNP"          },
98         { HIDP_UUID,            "HIDP"          },
99         { HCRP_CTRL_UUID,       "HCRP-Ctrl"     },
100         { HCRP_DATA_UUID,       "HCRP-Data"     },
101         { HCRP_NOTE_UUID,       "HCRP-Notify"   },
102         { AVCTP_UUID,           "AVCTP"         },
103         { AVDTP_UUID,           "AVDTP"         },
104         { CMTP_UUID,            "CMTP"          },
105         { UDI_UUID,             "UDI"           },
106         { MCAP_CTRL_UUID,       "MCAP-Ctrl"     },
107         { MCAP_DATA_UUID,       "MCAP-Data"     },
108         { L2CAP_UUID,           "L2CAP"         },
109         { ATT_UUID,             "ATT"           },
110         { 0 }
111 };
112
113 static struct tupla ServiceClass[] = {
114         { SDP_SERVER_SVCLASS_ID,                "SDP Server"                    },
115         { BROWSE_GRP_DESC_SVCLASS_ID,           "Browse Group Descriptor"       },
116         { PUBLIC_BROWSE_GROUP,                  "Public Browse Group"           },
117         { SERIAL_PORT_SVCLASS_ID,               "Serial Port"                   },
118         { LAN_ACCESS_SVCLASS_ID,                "LAN Access Using PPP"          },
119         { DIALUP_NET_SVCLASS_ID,                "Dialup Networking"             },
120         { IRMC_SYNC_SVCLASS_ID,                 "IrMC Sync"                     },
121         { OBEX_OBJPUSH_SVCLASS_ID,              "OBEX Object Push"              },
122         { OBEX_FILETRANS_SVCLASS_ID,            "OBEX File Transfer"            },
123         { IRMC_SYNC_CMD_SVCLASS_ID,             "IrMC Sync Command"             },
124         { HEADSET_SVCLASS_ID,                   "Headset"                       },
125         { CORDLESS_TELEPHONY_SVCLASS_ID,        "Cordless Telephony"            },
126         { AUDIO_SOURCE_SVCLASS_ID,              "Audio Source"                  },
127         { AUDIO_SINK_SVCLASS_ID,                "Audio Sink"                    },
128         { AV_REMOTE_TARGET_SVCLASS_ID,          "AV Remote Target"              },
129         { ADVANCED_AUDIO_SVCLASS_ID,            "Advanced Audio"                },
130         { AV_REMOTE_SVCLASS_ID,                 "AV Remote"                     },
131         { AV_REMOTE_CONTROLLER_SVCLASS_ID,      "AV Remote Controller"          },
132         { INTERCOM_SVCLASS_ID,                  "Intercom"                      },
133         { FAX_SVCLASS_ID,                       "Fax"                           },
134         { HEADSET_AGW_SVCLASS_ID,               "Headset Audio Gateway"         },
135         { WAP_SVCLASS_ID,                       "WAP"                           },
136         { WAP_CLIENT_SVCLASS_ID,                "WAP Client"                    },
137         { PANU_SVCLASS_ID,                      "PAN User"                      },
138         { NAP_SVCLASS_ID,                       "Network Access Point"          },
139         { GN_SVCLASS_ID,                        "PAN Group Network"             },
140         { DIRECT_PRINTING_SVCLASS_ID,           "Direct Printing"               },
141         { REFERENCE_PRINTING_SVCLASS_ID,        "Reference Printing"            },
142         { IMAGING_SVCLASS_ID,                   "Imaging"                       },
143         { IMAGING_RESPONDER_SVCLASS_ID,         "Imaging Responder"             },
144         { IMAGING_ARCHIVE_SVCLASS_ID,           "Imaging Automatic Archive"     },
145         { IMAGING_REFOBJS_SVCLASS_ID,           "Imaging Referenced Objects"    },
146         { HANDSFREE_SVCLASS_ID,                 "Handsfree"                     },
147         { HANDSFREE_AGW_SVCLASS_ID,             "Handsfree Audio Gateway"       },
148         { DIRECT_PRT_REFOBJS_SVCLASS_ID,        "Direct Printing Ref. Objects"  },
149         { REFLECTED_UI_SVCLASS_ID,              "Reflected UI"                  },
150         { BASIC_PRINTING_SVCLASS_ID,            "Basic Printing"                },
151         { PRINTING_STATUS_SVCLASS_ID,           "Printing Status"               },
152         { HID_SVCLASS_ID,                       "Human Interface Device"        },
153         { HCR_SVCLASS_ID,                       "Hardcopy Cable Replacement"    },
154         { HCR_PRINT_SVCLASS_ID,                 "HCR Print"                     },
155         { HCR_SCAN_SVCLASS_ID,                  "HCR Scan"                      },
156         { CIP_SVCLASS_ID,                       "Common ISDN Access"            },
157         { VIDEO_CONF_GW_SVCLASS_ID,             "Video Conferencing Gateway"    },
158         { UDI_MT_SVCLASS_ID,                    "UDI MT"                        },
159         { UDI_TA_SVCLASS_ID,                    "UDI TA"                        },
160         { AV_SVCLASS_ID,                        "Audio/Video"                   },
161         { SAP_SVCLASS_ID,                       "SIM Access"                    },
162         { PBAP_PCE_SVCLASS_ID,                  "Phonebook Access - PCE"        },
163         { PBAP_PSE_SVCLASS_ID,                  "Phonebook Access - PSE"        },
164         { PBAP_SVCLASS_ID,                      "Phonebook Access"              },
165         { MAP_MSE_SVCLASS_ID,                   "Message Access - MAS"          },
166         { MAP_MCE_SVCLASS_ID,                   "Message Access - MNS"          },
167         { MAP_SVCLASS_ID,                       "Message Access"                },
168         { PNP_INFO_SVCLASS_ID,                  "PnP Information"               },
169         { GENERIC_NETWORKING_SVCLASS_ID,        "Generic Networking"            },
170         { GENERIC_FILETRANS_SVCLASS_ID,         "Generic File Transfer"         },
171         { GENERIC_AUDIO_SVCLASS_ID,             "Generic Audio"                 },
172         { GENERIC_TELEPHONY_SVCLASS_ID,         "Generic Telephony"             },
173         { UPNP_SVCLASS_ID,                      "UPnP"                          },
174         { UPNP_IP_SVCLASS_ID,                   "UPnP IP"                       },
175         { UPNP_PAN_SVCLASS_ID,                  "UPnP PAN"                      },
176         { UPNP_LAP_SVCLASS_ID,                  "UPnP LAP"                      },
177         { UPNP_L2CAP_SVCLASS_ID,                "UPnP L2CAP"                    },
178         { VIDEO_SOURCE_SVCLASS_ID,              "Video Source"                  },
179         { VIDEO_SINK_SVCLASS_ID,                "Video Sink"                    },
180         { VIDEO_DISTRIBUTION_SVCLASS_ID,        "Video Distribution"            },
181         { HDP_SVCLASS_ID,                       "HDP"                           },
182         { HDP_SOURCE_SVCLASS_ID,                "HDP Source"                    },
183         { HDP_SINK_SVCLASS_ID,                  "HDP Sink"                      },
184         { GENERIC_ACCESS_SVCLASS_ID,            "Generic Access"                },
185         { GENERIC_ATTRIB_SVCLASS_ID,            "Generic Attribute"             },
186         { APPLE_AGENT_SVCLASS_ID,               "Apple Agent"                   },
187         { 0 }
188 };
189
190 #define Profile ServiceClass
191
192 static char *string_lookup(struct tupla *pt0, int index)
193 {
194         struct tupla *pt;
195
196         for (pt = pt0; pt->index; pt++)
197                 if (pt->index == index)
198                         return pt->str;
199
200         return "";
201 }
202
203 static char *string_lookup_uuid(struct tupla *pt0, const uuid_t *uuid)
204 {
205         uuid_t tmp_uuid;
206
207         memcpy(&tmp_uuid, uuid, sizeof(tmp_uuid));
208
209         if (sdp_uuid128_to_uuid(&tmp_uuid)) {
210                 switch (tmp_uuid.type) {
211                 case SDP_UUID16:
212                         return string_lookup(pt0, tmp_uuid.value.uuid16);
213                 case SDP_UUID32:
214                         return string_lookup(pt0, tmp_uuid.value.uuid32);
215                 }
216         }
217
218         return "";
219 }
220
221 /*
222  * Prints into a string the Protocol UUID
223  * coping a maximum of n characters.
224  */
225 static int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t n)
226 {
227         char *str2;
228
229         if (!uuid) {
230                 snprintf(str, n, "NULL");
231                 return -2;
232         }
233
234         switch (uuid->type) {
235         case SDP_UUID16:
236                 str2 = string_lookup(message, uuid->value.uuid16);
237                 snprintf(str, n, "%s", str2);
238                 break;
239         case SDP_UUID32:
240                 str2 = string_lookup(message, uuid->value.uuid32);
241                 snprintf(str, n, "%s", str2);
242                 break;
243         case SDP_UUID128:
244                 str2 = string_lookup_uuid(message, uuid);
245                 snprintf(str, n, "%s", str2);
246                 break;
247         default:
248                 snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
249                 return -1;
250         }
251
252         return 0;
253 }
254
255 int sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n)
256 {
257         return uuid2str(Protocol, uuid, str, n);
258 }
259
260 int sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n)
261 {
262         return uuid2str(ServiceClass, uuid, str, n);
263 }
264
265 int sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n)
266 {
267         return uuid2str(Profile, uuid, str, n);
268 }
269
270 /*
271  * convert the UUID to string, copying a maximum of n characters.
272  */
273 int sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n)
274 {
275         if (!uuid) {
276                 snprintf(str, n, "NULL");
277                 return -2;
278         }
279         switch (uuid->type) {
280         case SDP_UUID16:
281                 snprintf(str, n, "%.4x", uuid->value.uuid16);
282                 break;
283         case SDP_UUID32:
284                 snprintf(str, n, "%.8x", uuid->value.uuid32);
285                 break;
286         case SDP_UUID128:{
287                 unsigned int   data0;
288                 unsigned short data1;
289                 unsigned short data2;
290                 unsigned short data3;
291                 unsigned int   data4;
292                 unsigned short data5;
293
294                 memcpy(&data0, &uuid->value.uuid128.data[0], 4);
295                 memcpy(&data1, &uuid->value.uuid128.data[4], 2);
296                 memcpy(&data2, &uuid->value.uuid128.data[6], 2);
297                 memcpy(&data3, &uuid->value.uuid128.data[8], 2);
298                 memcpy(&data4, &uuid->value.uuid128.data[10], 4);
299                 memcpy(&data5, &uuid->value.uuid128.data[14], 2);
300
301                 snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
302                                 ntohl(data0), ntohs(data1),
303                                 ntohs(data2), ntohs(data3),
304                                 ntohl(data4), ntohs(data5));
305                 }
306                 break;
307         default:
308                 snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
309                 return -1;      /* Enum type of UUID not set */
310         }
311         return 0;
312 }
313
314 #ifdef SDP_DEBUG
315 /*
316  * Function prints the UUID in hex as per defined syntax -
317  *
318  * 4bytes-2bytes-2bytes-2bytes-6bytes
319  *
320  * There is some ugly code, including hardcoding, but
321  * that is just the way it is converting 16 and 32 bit
322  * UUIDs to 128 bit as defined in the SDP doc
323  */
324 void sdp_uuid_print(const uuid_t *uuid)
325 {
326         if (uuid == NULL) {
327                 SDPERR("Null passed to print UUID");
328                 return;
329         }
330         if (uuid->type == SDP_UUID16) {
331                 SDPDBG("  uint16_t : 0x%.4x", uuid->value.uuid16);
332         } else if (uuid->type == SDP_UUID32) {
333                 SDPDBG("  uint32_t : 0x%.8x", uuid->value.uuid32);
334         } else if (uuid->type == SDP_UUID128) {
335                 unsigned int data0;
336                 unsigned short data1;
337                 unsigned short data2;
338                 unsigned short data3;
339                 unsigned int data4;
340                 unsigned short data5;
341
342                 memcpy(&data0, &uuid->value.uuid128.data[0], 4);
343                 memcpy(&data1, &uuid->value.uuid128.data[4], 2);
344                 memcpy(&data2, &uuid->value.uuid128.data[6], 2);
345                 memcpy(&data3, &uuid->value.uuid128.data[8], 2);
346                 memcpy(&data4, &uuid->value.uuid128.data[10], 4);
347                 memcpy(&data5, &uuid->value.uuid128.data[14], 2);
348
349                 SDPDBG("  uint128_t : 0x%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
350                                 ntohl(data0), ntohs(data1), ntohs(data2),
351                                 ntohs(data3), ntohl(data4), ntohs(data5));
352         } else
353                 SDPERR("Enum type of UUID not set");
354 }
355 #endif
356
357 sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value,
358                                                         uint32_t length)
359 {
360         sdp_data_t *seq;
361         sdp_data_t *d = malloc(sizeof(sdp_data_t));
362
363         if (!d)
364                 return NULL;
365
366         memset(d, 0, sizeof(sdp_data_t));
367         d->dtd = dtd;
368         d->unitSize = sizeof(uint8_t);
369
370         switch (dtd) {
371         case SDP_DATA_NIL:
372                 break;
373         case SDP_UINT8:
374                 d->val.uint8 = *(uint8_t *) value;
375                 d->unitSize += sizeof(uint8_t);
376                 break;
377         case SDP_INT8:
378         case SDP_BOOL:
379                 d->val.int8 = *(int8_t *) value;
380                 d->unitSize += sizeof(int8_t);
381                 break;
382         case SDP_UINT16:
383                 d->val.uint16 = bt_get_unaligned((uint16_t *) value);
384                 d->unitSize += sizeof(uint16_t);
385                 break;
386         case SDP_INT16:
387                 d->val.int16 = bt_get_unaligned((int16_t *) value);
388                 d->unitSize += sizeof(int16_t);
389                 break;
390         case SDP_UINT32:
391                 d->val.uint32 = bt_get_unaligned((uint32_t *) value);
392                 d->unitSize += sizeof(uint32_t);
393                 break;
394         case SDP_INT32:
395                 d->val.int32 = bt_get_unaligned((int32_t *) value);
396                 d->unitSize += sizeof(int32_t);
397                 break;
398         case SDP_INT64:
399                 d->val.int64 = bt_get_unaligned((int64_t *) value);
400                 d->unitSize += sizeof(int64_t);
401                 break;
402         case SDP_UINT64:
403                 d->val.uint64 = bt_get_unaligned((uint64_t *) value);
404                 d->unitSize += sizeof(uint64_t);
405                 break;
406         case SDP_UINT128:
407                 memcpy(&d->val.uint128.data, value, sizeof(uint128_t));
408                 d->unitSize += sizeof(uint128_t);
409                 break;
410         case SDP_INT128:
411                 memcpy(&d->val.int128.data, value, sizeof(uint128_t));
412                 d->unitSize += sizeof(uint128_t);
413                 break;
414         case SDP_UUID16:
415                 sdp_uuid16_create(&d->val.uuid, bt_get_unaligned((uint16_t *) value));
416                 d->unitSize += sizeof(uint16_t);
417                 break;
418         case SDP_UUID32:
419                 sdp_uuid32_create(&d->val.uuid, bt_get_unaligned((uint32_t *) value));
420                 d->unitSize += sizeof(uint32_t);
421                 break;
422         case SDP_UUID128:
423                 sdp_uuid128_create(&d->val.uuid, value);
424                 d->unitSize += sizeof(uint128_t);
425                 break;
426         case SDP_URL_STR8:
427         case SDP_URL_STR16:
428         case SDP_TEXT_STR8:
429         case SDP_TEXT_STR16:
430                 if (!value) {
431                         free(d);
432                         return NULL;
433                 }
434
435                 d->unitSize += length;
436                 if (length <= USHRT_MAX) {
437                         d->val.str = malloc(length);
438                         if (!d->val.str) {
439                                 free(d);
440                                 return NULL;
441                         }
442
443                         memcpy(d->val.str, value, length);
444                 } else {
445                         SDPERR("Strings of size > USHRT_MAX not supported");
446                         free(d);
447                         d = NULL;
448                 }
449                 break;
450         case SDP_URL_STR32:
451         case SDP_TEXT_STR32:
452                 SDPERR("Strings of size > USHRT_MAX not supported");
453                 break;
454         case SDP_ALT8:
455         case SDP_ALT16:
456         case SDP_ALT32:
457         case SDP_SEQ8:
458         case SDP_SEQ16:
459         case SDP_SEQ32:
460                 if (dtd == SDP_ALT8 || dtd == SDP_SEQ8)
461                         d->unitSize += sizeof(uint8_t);
462                 else if (dtd == SDP_ALT16 || dtd == SDP_SEQ16)
463                         d->unitSize += sizeof(uint16_t);
464                 else if (dtd == SDP_ALT32 || dtd == SDP_SEQ32)
465                         d->unitSize += sizeof(uint32_t);
466                 seq = (sdp_data_t *)value;
467                 d->val.dataseq = seq;
468                 for (; seq; seq = seq->next)
469                         d->unitSize += seq->unitSize;
470                 break;
471         default:
472                 free(d);
473                 d = NULL;
474         }
475
476         return d;
477 }
478
479 sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value)
480 {
481         uint32_t length;
482
483         switch (dtd) {
484         case SDP_URL_STR8:
485         case SDP_URL_STR16:
486         case SDP_TEXT_STR8:
487         case SDP_TEXT_STR16:
488                 if (!value)
489                         return NULL;
490
491                 length = strlen((char *) value);
492                 break;
493         default:
494                 length = 0;
495                 break;
496         }
497
498         return sdp_data_alloc_with_length(dtd, value, length);
499 }
500
501 sdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d)
502 {
503         if (seq) {
504                 sdp_data_t *p;
505                 for (p = seq; p->next; p = p->next);
506                 p->next = d;
507         } else
508                 seq = d;
509         d->next = NULL;
510         return seq;
511 }
512
513 sdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length,
514                                                                 int len)
515 {
516         sdp_data_t *curr = NULL, *seq = NULL;
517         int i;
518
519         for (i = 0; i < len; i++) {
520                 sdp_data_t *data;
521                 int8_t dtd = *(uint8_t *) dtds[i];
522
523                 if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
524                         data = (sdp_data_t *) values[i];
525                 else
526                         data = sdp_data_alloc_with_length(dtd, values[i], length[i]);
527
528                 if (!data)
529                         return NULL;
530
531                 if (curr)
532                         curr->next = data;
533                 else
534                         seq = data;
535
536                 curr = data;
537         }
538
539         return sdp_data_alloc(SDP_SEQ8, seq);
540 }
541
542 sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len)
543 {
544         sdp_data_t *curr = NULL, *seq = NULL;
545         int i;
546
547         for (i = 0; i < len; i++) {
548                 sdp_data_t *data;
549                 uint8_t dtd = *(uint8_t *) dtds[i];
550
551                 if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
552                         data = (sdp_data_t *) values[i];
553                 else
554                         data = sdp_data_alloc(dtd, values[i]);
555
556                 if (!data)
557                         return NULL;
558
559                 if (curr)
560                         curr->next = data;
561                 else
562                         seq = data;
563
564                 curr = data;
565         }
566
567         return sdp_data_alloc(SDP_SEQ8, seq);
568 }
569
570 static void extract_svclass_uuid(sdp_data_t *data, uuid_t *uuid)
571 {
572         sdp_data_t *d;
573
574         if (!data || !SDP_IS_SEQ(data->dtd))
575                 return;
576
577         d = data->val.dataseq;
578         if (!d)
579                 return;
580
581         if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128)
582                 return;
583
584         *uuid = d->val.uuid;
585 }
586
587 int sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
588 {
589         sdp_data_t *p = sdp_data_get(rec, attr);
590
591         if (p)
592                 return -1;
593
594         d->attrId = attr;
595         rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);
596
597         if (attr == SDP_ATTR_SVCLASS_ID_LIST)
598                 extract_svclass_uuid(d, &rec->svclass);
599
600         return 0;
601 }
602
603 void sdp_attr_remove(sdp_record_t *rec, uint16_t attr)
604 {
605         sdp_data_t *d = sdp_data_get(rec, attr);
606
607         if (d)
608                 rec->attrlist = sdp_list_remove(rec->attrlist, d);
609
610         if (attr == SDP_ATTR_SVCLASS_ID_LIST)
611                 memset(&rec->svclass, 0, sizeof(rec->svclass));
612 }
613
614 void sdp_set_seq_len(uint8_t *ptr, uint32_t length)
615 {
616         uint8_t dtd = *ptr++;
617
618         switch (dtd) {
619         case SDP_SEQ8:
620         case SDP_ALT8:
621         case SDP_TEXT_STR8:
622         case SDP_URL_STR8:
623                 *ptr = (uint8_t) length;
624                 break;
625         case SDP_SEQ16:
626         case SDP_ALT16:
627         case SDP_TEXT_STR16:
628         case SDP_URL_STR16:
629                 bt_put_be16(length, ptr);
630                 break;
631         case SDP_SEQ32:
632         case SDP_ALT32:
633         case SDP_TEXT_STR32:
634         case SDP_URL_STR32:
635                 bt_put_be32(length, ptr);
636                 break;
637         }
638 }
639
640 static int sdp_get_data_type_size(uint8_t dtd)
641 {
642         int size = sizeof(uint8_t);
643
644         switch (dtd) {
645         case SDP_SEQ8:
646         case SDP_TEXT_STR8:
647         case SDP_URL_STR8:
648         case SDP_ALT8:
649                 size += sizeof(uint8_t);
650                 break;
651         case SDP_SEQ16:
652         case SDP_TEXT_STR16:
653         case SDP_URL_STR16:
654         case SDP_ALT16:
655                 size += sizeof(uint16_t);
656                 break;
657         case SDP_SEQ32:
658         case SDP_TEXT_STR32:
659         case SDP_URL_STR32:
660         case SDP_ALT32:
661                 size += sizeof(uint32_t);
662                 break;
663         }
664
665         return size;
666 }
667
668 void sdp_set_attrid(sdp_buf_t *buf, uint16_t attr)
669 {
670         uint8_t *p = buf->data;
671
672         /* data type for attr */
673         *p++ = SDP_UINT16;
674         buf->data_size = sizeof(uint8_t);
675         bt_put_be16(attr, p);
676         buf->data_size += sizeof(uint16_t);
677 }
678
679 static int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata)
680 {
681         sdp_data_t *d;
682         int n = 0;
683
684         for (d = sdpdata->val.dataseq; d; d = d->next) {
685                 if (buf->data)
686                         n += sdp_gen_pdu(buf, d);
687                 else
688                         n += sdp_gen_buffer(buf, d);
689         }
690
691         return n;
692 }
693
694 static int sdp_get_data_size(sdp_buf_t *buf, sdp_data_t *d)
695 {
696         uint32_t data_size = 0;
697         uint8_t dtd = d->dtd;
698
699         switch (dtd) {
700         case SDP_DATA_NIL:
701                 break;
702         case SDP_UINT8:
703                 data_size = sizeof(uint8_t);
704                 break;
705         case SDP_UINT16:
706                 data_size = sizeof(uint16_t);
707                 break;
708         case SDP_UINT32:
709                 data_size = sizeof(uint32_t);
710                 break;
711         case SDP_UINT64:
712                 data_size = sizeof(uint64_t);
713                 break;
714         case SDP_UINT128:
715                 data_size = sizeof(uint128_t);
716                 break;
717         case SDP_INT8:
718         case SDP_BOOL:
719                 data_size = sizeof(int8_t);
720                 break;
721         case SDP_INT16:
722                 data_size = sizeof(int16_t);
723                 break;
724         case SDP_INT32:
725                 data_size = sizeof(int32_t);
726                 break;
727         case SDP_INT64:
728                 data_size = sizeof(int64_t);
729                 break;
730         case SDP_INT128:
731                 data_size = sizeof(uint128_t);
732                 break;
733         case SDP_TEXT_STR8:
734         case SDP_TEXT_STR16:
735         case SDP_TEXT_STR32:
736         case SDP_URL_STR8:
737         case SDP_URL_STR16:
738         case SDP_URL_STR32:
739                 data_size = d->unitSize - sizeof(uint8_t);
740                 break;
741         case SDP_SEQ8:
742         case SDP_SEQ16:
743         case SDP_SEQ32:
744                 data_size = get_data_size(buf, d);
745                 break;
746         case SDP_ALT8:
747         case SDP_ALT16:
748         case SDP_ALT32:
749                 data_size = get_data_size(buf, d);
750                 break;
751         case SDP_UUID16:
752                 data_size = sizeof(uint16_t);
753                 break;
754         case SDP_UUID32:
755                 data_size = sizeof(uint32_t);
756                 break;
757         case SDP_UUID128:
758                 data_size = sizeof(uint128_t);
759                 break;
760         default:
761                 break;
762         }
763
764         return data_size;
765 }
766
767 static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d)
768 {
769         int orig = buf->buf_size;
770
771         if (buf->buf_size == 0 && d->dtd == 0) {
772                 /* create initial sequence */
773                 buf->buf_size += sizeof(uint8_t);
774
775                 /* reserve space for sequence size */
776                 buf->buf_size += sizeof(uint8_t);
777         }
778
779         /* attribute length */
780         buf->buf_size += sizeof(uint8_t) + sizeof(uint16_t);
781
782         buf->buf_size += sdp_get_data_type_size(d->dtd);
783         buf->buf_size += sdp_get_data_size(buf, d);
784
785         if (buf->buf_size > UCHAR_MAX && d->dtd == SDP_SEQ8)
786                 buf->buf_size += sizeof(uint8_t);
787
788         return buf->buf_size - orig;
789 }
790
791 int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
792 {
793         uint32_t pdu_size, data_size;
794         unsigned char *src = NULL, is_seq = 0, is_alt = 0;
795         uint16_t u16;
796         uint32_t u32;
797         uint64_t u64;
798         uint128_t u128;
799         uint8_t *seqp = buf->data + buf->data_size;
800         uint32_t orig_data_size = buf->data_size;
801
802 recalculate:
803         pdu_size = sdp_get_data_type_size(d->dtd);
804         buf->data_size += pdu_size;
805
806         data_size = sdp_get_data_size(buf, d);
807         if (data_size > UCHAR_MAX && d->dtd == SDP_SEQ8) {
808                 buf->data_size = orig_data_size;
809                 d->dtd = SDP_SEQ16;
810                 goto recalculate;
811         }
812
813         *seqp = d->dtd;
814
815         switch (d->dtd) {
816         case SDP_DATA_NIL:
817                 break;
818         case SDP_UINT8:
819                 src = &d->val.uint8;
820                 break;
821         case SDP_UINT16:
822                 u16 = htons(d->val.uint16);
823                 src = (unsigned char *) &u16;
824                 break;
825         case SDP_UINT32:
826                 u32 = htonl(d->val.uint32);
827                 src = (unsigned char *) &u32;
828                 break;
829         case SDP_UINT64:
830                 u64 = hton64(d->val.uint64);
831                 src = (unsigned char *) &u64;
832                 break;
833         case SDP_UINT128:
834                 hton128(&d->val.uint128, &u128);
835                 src = (unsigned char *) &u128;
836                 break;
837         case SDP_INT8:
838         case SDP_BOOL:
839                 src = (unsigned char *) &d->val.int8;
840                 break;
841         case SDP_INT16:
842                 u16 = htons(d->val.int16);
843                 src = (unsigned char *) &u16;
844                 break;
845         case SDP_INT32:
846                 u32 = htonl(d->val.int32);
847                 src = (unsigned char *) &u32;
848                 break;
849         case SDP_INT64:
850                 u64 = hton64(d->val.int64);
851                 src = (unsigned char *) &u64;
852                 break;
853         case SDP_INT128:
854                 hton128(&d->val.int128, &u128);
855                 src = (unsigned char *) &u128;
856                 break;
857         case SDP_TEXT_STR8:
858         case SDP_TEXT_STR16:
859         case SDP_TEXT_STR32:
860         case SDP_URL_STR8:
861         case SDP_URL_STR16:
862         case SDP_URL_STR32:
863                 src = (unsigned char *) d->val.str;
864                 sdp_set_seq_len(seqp, data_size);
865                 break;
866         case SDP_SEQ8:
867         case SDP_SEQ16:
868         case SDP_SEQ32:
869                 is_seq = 1;
870                 sdp_set_seq_len(seqp, data_size);
871                 break;
872         case SDP_ALT8:
873         case SDP_ALT16:
874         case SDP_ALT32:
875                 is_alt = 1;
876                 sdp_set_seq_len(seqp, data_size);
877                 break;
878         case SDP_UUID16:
879                 u16 = htons(d->val.uuid.value.uuid16);
880                 src = (unsigned char *) &u16;
881                 break;
882         case SDP_UUID32:
883                 u32 = htonl(d->val.uuid.value.uuid32);
884                 src = (unsigned char *) &u32;
885                 break;
886         case SDP_UUID128:
887                 src = (unsigned char *) &d->val.uuid.value.uuid128;
888                 break;
889         default:
890                 break;
891         }
892
893         if (!is_seq && !is_alt) {
894                 if (src && buf->buf_size >= buf->data_size + data_size) {
895                         memcpy(buf->data + buf->data_size, src, data_size);
896                         buf->data_size += data_size;
897                 } else if (d->dtd != SDP_DATA_NIL) {
898                         SDPDBG("Gen PDU : Can't copy from invalid source or dest");
899                 }
900         }
901
902         pdu_size += data_size;
903
904         return pdu_size;
905 }
906
907 static void sdp_attr_pdu(void *value, void *udata)
908 {
909         sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value);
910 }
911
912 static void sdp_attr_size(void *value, void *udata)
913 {
914         sdp_gen_buffer((sdp_buf_t *)udata, (sdp_data_t *)value);
915 }
916
917 int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf)
918 {
919         memset(buf, 0, sizeof(sdp_buf_t));
920         sdp_list_foreach(rec->attrlist, sdp_attr_size, buf);
921
922         buf->data = malloc(buf->buf_size);
923         if (!buf->data)
924                 return -ENOMEM;
925         buf->data_size = 0;
926         memset(buf->data, 0, buf->buf_size);
927
928         sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf);
929
930         return 0;
931 }
932
933 void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
934 {
935         sdp_data_t *p;
936
937         if (!rec)
938                 return;
939
940         p = sdp_data_get(rec, attr);
941         if (p) {
942                 rec->attrlist = sdp_list_remove(rec->attrlist, p);
943                 sdp_data_free(p);
944         }
945
946         d->attrId = attr;
947         rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);
948
949         if (attr == SDP_ATTR_SVCLASS_ID_LIST)
950                 extract_svclass_uuid(d, &rec->svclass);
951 }
952
953 int sdp_attrid_comp_func(const void *key1, const void *key2)
954 {
955         const sdp_data_t *d1 = (const sdp_data_t *)key1;
956         const sdp_data_t *d2 = (const sdp_data_t *)key2;
957
958         if (d1 && d2)
959                 return d1->attrId - d2->attrId;
960         return 0;
961 }
962
963 static void data_seq_free(sdp_data_t *seq)
964 {
965         sdp_data_t *d = seq->val.dataseq;
966
967         while (d) {
968                 sdp_data_t *next = d->next;
969                 sdp_data_free(d);
970                 d = next;
971         }
972 }
973
974 void sdp_data_free(sdp_data_t *d)
975 {
976         switch (d->dtd) {
977         case SDP_SEQ8:
978         case SDP_SEQ16:
979         case SDP_SEQ32:
980                 data_seq_free(d);
981                 break;
982         case SDP_URL_STR8:
983         case SDP_URL_STR16:
984         case SDP_URL_STR32:
985         case SDP_TEXT_STR8:
986         case SDP_TEXT_STR16:
987         case SDP_TEXT_STR32:
988                 free(d->val.str);
989                 break;
990         }
991         free(d);
992 }
993
994 int sdp_uuid_extract(const uint8_t *p, int bufsize, uuid_t *uuid, int *scanned)
995 {
996         uint8_t type;
997
998         if (bufsize < (int) sizeof(uint8_t)) {
999                 SDPERR("Unexpected end of packet");
1000                 return -1;
1001         }
1002
1003         type = *(const uint8_t *) p;
1004
1005         if (!SDP_IS_UUID(type)) {
1006                 SDPERR("Unknown data type : %d expecting a svc UUID", type);
1007                 return -1;
1008         }
1009         p += sizeof(uint8_t);
1010         *scanned += sizeof(uint8_t);
1011         bufsize -= sizeof(uint8_t);
1012         if (type == SDP_UUID16) {
1013                 if (bufsize < (int) sizeof(uint16_t)) {
1014                         SDPERR("Not enough room for 16-bit UUID");
1015                         return -1;
1016                 }
1017                 sdp_uuid16_create(uuid, bt_get_be16(p));
1018                 *scanned += sizeof(uint16_t);
1019         } else if (type == SDP_UUID32) {
1020                 if (bufsize < (int) sizeof(uint32_t)) {
1021                         SDPERR("Not enough room for 32-bit UUID");
1022                         return -1;
1023                 }
1024                 sdp_uuid32_create(uuid, bt_get_be32(p));
1025                 *scanned += sizeof(uint32_t);
1026         } else {
1027                 if (bufsize < (int) sizeof(uint128_t)) {
1028                         SDPERR("Not enough room for 128-bit UUID");
1029                         return -1;
1030                 }
1031                 sdp_uuid128_create(uuid, p);
1032                 *scanned += sizeof(uint128_t);
1033         }
1034         return 0;
1035 }
1036
1037 static sdp_data_t *extract_int(const void *p, int bufsize, int *len)
1038 {
1039         sdp_data_t *d;
1040
1041         if (bufsize < (int) sizeof(uint8_t)) {
1042                 SDPERR("Unexpected end of packet");
1043                 return NULL;
1044         }
1045
1046         d = malloc(sizeof(sdp_data_t));
1047         if (!d)
1048                 return NULL;
1049
1050         SDPDBG("Extracting integer");
1051         memset(d, 0, sizeof(sdp_data_t));
1052         d->dtd = *(uint8_t *) p;
1053         p += sizeof(uint8_t);
1054         *len += sizeof(uint8_t);
1055         bufsize -= sizeof(uint8_t);
1056
1057         switch (d->dtd) {
1058         case SDP_DATA_NIL:
1059                 break;
1060         case SDP_BOOL:
1061         case SDP_INT8:
1062         case SDP_UINT8:
1063                 if (bufsize < (int) sizeof(uint8_t)) {
1064                         SDPERR("Unexpected end of packet");
1065                         free(d);
1066                         return NULL;
1067                 }
1068                 *len += sizeof(uint8_t);
1069                 d->val.uint8 = *(uint8_t *) p;
1070                 break;
1071         case SDP_INT16:
1072         case SDP_UINT16:
1073                 if (bufsize < (int) sizeof(uint16_t)) {
1074                         SDPERR("Unexpected end of packet");
1075                         free(d);
1076                         return NULL;
1077                 }
1078                 *len += sizeof(uint16_t);
1079                 d->val.uint16 = bt_get_be16(p);
1080                 break;
1081         case SDP_INT32:
1082         case SDP_UINT32:
1083                 if (bufsize < (int) sizeof(uint32_t)) {
1084                         SDPERR("Unexpected end of packet");
1085                         free(d);
1086                         return NULL;
1087                 }
1088                 *len += sizeof(uint32_t);
1089                 d->val.uint32 = bt_get_be32(p);
1090                 break;
1091         case SDP_INT64:
1092         case SDP_UINT64:
1093                 if (bufsize < (int) sizeof(uint64_t)) {
1094                         SDPERR("Unexpected end of packet");
1095                         free(d);
1096                         return NULL;
1097                 }
1098                 *len += sizeof(uint64_t);
1099                 d->val.uint64 = bt_get_be64(p);
1100                 break;
1101         case SDP_INT128:
1102         case SDP_UINT128:
1103                 if (bufsize < (int) sizeof(uint128_t)) {
1104                         SDPERR("Unexpected end of packet");
1105                         free(d);
1106                         return NULL;
1107                 }
1108                 *len += sizeof(uint128_t);
1109                 ntoh128((uint128_t *) p, &d->val.uint128);
1110                 break;
1111         default:
1112                 free(d);
1113                 d = NULL;
1114         }
1115         return d;
1116 }
1117
1118 static sdp_data_t *extract_uuid(const uint8_t *p, int bufsize, int *len,
1119                                                         sdp_record_t *rec)
1120 {
1121         sdp_data_t *d = malloc(sizeof(sdp_data_t));
1122
1123         if (!d)
1124                 return NULL;
1125
1126         SDPDBG("Extracting UUID");
1127         memset(d, 0, sizeof(sdp_data_t));
1128         if (sdp_uuid_extract(p, bufsize, &d->val.uuid, len) < 0) {
1129                 free(d);
1130                 return NULL;
1131         }
1132         d->dtd = *p;
1133         if (rec)
1134                 sdp_pattern_add_uuid(rec, &d->val.uuid);
1135         return d;
1136 }
1137
1138 /*
1139  * Extract strings from the PDU (could be service description and similar info)
1140  */
1141 static sdp_data_t *extract_str(const void *p, int bufsize, int *len)
1142 {
1143         char *s;
1144         int n;
1145         sdp_data_t *d;
1146
1147         if (bufsize < (int) sizeof(uint8_t)) {
1148                 SDPERR("Unexpected end of packet");
1149                 return NULL;
1150         }
1151
1152         d = malloc(sizeof(sdp_data_t));
1153         if (!d)
1154                 return NULL;
1155
1156         memset(d, 0, sizeof(sdp_data_t));
1157         d->dtd = *(uint8_t *) p;
1158         p += sizeof(uint8_t);
1159         *len += sizeof(uint8_t);
1160         bufsize -= sizeof(uint8_t);
1161
1162         switch (d->dtd) {
1163         case SDP_TEXT_STR8:
1164         case SDP_URL_STR8:
1165                 if (bufsize < (int) sizeof(uint8_t)) {
1166                         SDPERR("Unexpected end of packet");
1167                         free(d);
1168                         return NULL;
1169                 }
1170                 n = *(uint8_t *) p;
1171                 p += sizeof(uint8_t);
1172                 *len += sizeof(uint8_t);
1173                 bufsize -= sizeof(uint8_t);
1174                 break;
1175         case SDP_TEXT_STR16:
1176         case SDP_URL_STR16:
1177                 if (bufsize < (int) sizeof(uint16_t)) {
1178                         SDPERR("Unexpected end of packet");
1179                         free(d);
1180                         return NULL;
1181                 }
1182                 n = bt_get_be16(p);
1183                 p += sizeof(uint16_t);
1184                 *len += sizeof(uint16_t);
1185                 bufsize -= sizeof(uint16_t);
1186                 break;
1187         default:
1188                 SDPERR("Sizeof text string > UINT16_MAX");
1189                 free(d);
1190                 return NULL;
1191         }
1192
1193         if (bufsize < n) {
1194                 SDPERR("String too long to fit in packet");
1195                 free(d);
1196                 return NULL;
1197         }
1198
1199         s = malloc(n + 1);
1200         if (!s) {
1201                 SDPERR("Not enough memory for incoming string");
1202                 free(d);
1203                 return NULL;
1204         }
1205         memset(s, 0, n + 1);
1206         memcpy(s, p, n);
1207
1208         *len += n;
1209
1210         SDPDBG("Len : %d", n);
1211         SDPDBG("Str : %s", s);
1212
1213         d->val.str = s;
1214         d->unitSize = n + sizeof(uint8_t);
1215         return d;
1216 }
1217
1218 /*
1219  * Extract the sequence type and its length, and return offset into buf
1220  * or 0 on failure.
1221  */
1222 int sdp_extract_seqtype(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size)
1223 {
1224         uint8_t dtd;
1225         int scanned = sizeof(uint8_t);
1226
1227         if (bufsize < (int) sizeof(uint8_t)) {
1228                 SDPERR("Unexpected end of packet");
1229                 return 0;
1230         }
1231
1232         dtd = *(uint8_t *) buf;
1233         buf += sizeof(uint8_t);
1234         bufsize -= sizeof(uint8_t);
1235         *dtdp = dtd;
1236         switch (dtd) {
1237         case SDP_SEQ8:
1238         case SDP_ALT8:
1239                 if (bufsize < (int) sizeof(uint8_t)) {
1240                         SDPERR("Unexpected end of packet");
1241                         return 0;
1242                 }
1243                 *size = *(uint8_t *) buf;
1244                 scanned += sizeof(uint8_t);
1245                 break;
1246         case SDP_SEQ16:
1247         case SDP_ALT16:
1248                 if (bufsize < (int) sizeof(uint16_t)) {
1249                         SDPERR("Unexpected end of packet");
1250                         return 0;
1251                 }
1252                 *size = bt_get_be16(buf);
1253                 scanned += sizeof(uint16_t);
1254                 break;
1255         case SDP_SEQ32:
1256         case SDP_ALT32:
1257                 if (bufsize < (int) sizeof(uint32_t)) {
1258                         SDPERR("Unexpected end of packet");
1259                         return 0;
1260                 }
1261                 *size = bt_get_be32(buf);
1262                 scanned += sizeof(uint32_t);
1263                 break;
1264         default:
1265                 SDPERR("Unknown sequence type, aborting");
1266                 return 0;
1267         }
1268         return scanned;
1269 }
1270
1271 static sdp_data_t *extract_seq(const void *p, int bufsize, int *len,
1272                                                         sdp_record_t *rec)
1273 {
1274         int seqlen, n = 0;
1275         sdp_data_t *curr, *prev;
1276         sdp_data_t *d = malloc(sizeof(sdp_data_t));
1277
1278         if (!d)
1279                 return NULL;
1280
1281         SDPDBG("Extracting SEQ");
1282         memset(d, 0, sizeof(sdp_data_t));
1283         *len = sdp_extract_seqtype(p, bufsize, &d->dtd, &seqlen);
1284         SDPDBG("Sequence Type : 0x%x length : 0x%x", d->dtd, seqlen);
1285
1286         if (*len == 0)
1287                 return d;
1288
1289         if (*len > bufsize) {
1290                 SDPERR("Packet not big enough to hold sequence.");
1291                 free(d);
1292                 return NULL;
1293         }
1294
1295         p += *len;
1296         bufsize -= *len;
1297         prev = NULL;
1298         while (n < seqlen) {
1299                 int attrlen = 0;
1300                 curr = sdp_extract_attr(p, bufsize, &attrlen, rec);
1301                 if (curr == NULL)
1302                         break;
1303
1304                 if (prev)
1305                         prev->next = curr;
1306                 else
1307                         d->val.dataseq = curr;
1308                 prev = curr;
1309                 p += attrlen;
1310                 n += attrlen;
1311                 bufsize -= attrlen;
1312
1313                 SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen);
1314         }
1315
1316         *len += n;
1317         return d;
1318 }
1319
1320 sdp_data_t *sdp_extract_attr(const uint8_t *p, int bufsize, int *size,
1321                                                         sdp_record_t *rec)
1322 {
1323         sdp_data_t *elem;
1324         int n = 0;
1325         uint8_t dtd;
1326
1327         if (bufsize < (int) sizeof(uint8_t)) {
1328                 SDPERR("Unexpected end of packet");
1329                 return NULL;
1330         }
1331
1332         dtd = *(const uint8_t *)p;
1333
1334         SDPDBG("extract_attr: dtd=0x%x", dtd);
1335         switch (dtd) {
1336         case SDP_DATA_NIL:
1337         case SDP_BOOL:
1338         case SDP_UINT8:
1339         case SDP_UINT16:
1340         case SDP_UINT32:
1341         case SDP_UINT64:
1342         case SDP_UINT128:
1343         case SDP_INT8:
1344         case SDP_INT16:
1345         case SDP_INT32:
1346         case SDP_INT64:
1347         case SDP_INT128:
1348                 elem = extract_int(p, bufsize, &n);
1349                 break;
1350         case SDP_UUID16:
1351         case SDP_UUID32:
1352         case SDP_UUID128:
1353                 elem = extract_uuid(p, bufsize, &n, rec);
1354                 break;
1355         case SDP_TEXT_STR8:
1356         case SDP_TEXT_STR16:
1357         case SDP_TEXT_STR32:
1358         case SDP_URL_STR8:
1359         case SDP_URL_STR16:
1360         case SDP_URL_STR32:
1361                 elem = extract_str(p, bufsize, &n);
1362                 break;
1363         case SDP_SEQ8:
1364         case SDP_SEQ16:
1365         case SDP_SEQ32:
1366         case SDP_ALT8:
1367         case SDP_ALT16:
1368         case SDP_ALT32:
1369                 elem = extract_seq(p, bufsize, &n, rec);
1370                 break;
1371         default:
1372                 SDPERR("Unknown data descriptor : 0x%x terminating", dtd);
1373                 return NULL;
1374         }
1375         *size += n;
1376         return elem;
1377 }
1378
1379 #ifdef SDP_DEBUG
1380 static void attr_print_func(void *value, void *userData)
1381 {
1382         sdp_data_t *d = (sdp_data_t *)value;
1383
1384         SDPDBG("=====================================");
1385         SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x",  d->attrId);
1386         SDPDBG("ATTRIBUTE VALUE PTR : %p", value);
1387         if (d)
1388                 sdp_data_print(d);
1389         else
1390                 SDPDBG("NULL value");
1391         SDPDBG("=====================================");
1392 }
1393
1394 void sdp_print_service_attr(sdp_list_t *svcAttrList)
1395 {
1396         SDPDBG("Printing service attr list %p", svcAttrList);
1397         sdp_list_foreach(svcAttrList, attr_print_func, NULL);
1398         SDPDBG("Printed service attr list %p", svcAttrList);
1399 }
1400 #endif
1401
1402 sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int bufsize, int *scanned)
1403 {
1404         int extracted = 0, seqlen = 0;
1405         uint8_t dtd;
1406         uint16_t attr;
1407         sdp_record_t *rec = sdp_record_alloc();
1408         const uint8_t *p = buf;
1409
1410         *scanned = sdp_extract_seqtype(buf, bufsize, &dtd, &seqlen);
1411         p += *scanned;
1412         bufsize -= *scanned;
1413         rec->attrlist = NULL;
1414
1415         while (extracted < seqlen && bufsize > 0) {
1416                 int n = sizeof(uint8_t), attrlen = 0;
1417                 sdp_data_t *data = NULL;
1418
1419                 SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d",
1420                                                         seqlen, extracted);
1421
1422                 if (bufsize < n + (int) sizeof(uint16_t)) {
1423                         SDPERR("Unexpected end of packet");
1424                         break;
1425                 }
1426
1427                 dtd = *(uint8_t *) p;
1428                 attr = bt_get_be16(p + n);
1429                 n += sizeof(uint16_t);
1430
1431                 SDPDBG("DTD of attrId : %d Attr id : 0x%x ", dtd, attr);
1432
1433                 data = sdp_extract_attr(p + n, bufsize - n, &attrlen, rec);
1434
1435                 SDPDBG("Attr id : 0x%x attrValueLength : %d", attr, attrlen);
1436
1437                 n += attrlen;
1438                 if (data == NULL) {
1439                         SDPDBG("Terminating extraction of attributes");
1440                         break;
1441                 }
1442
1443                 if (attr == SDP_ATTR_RECORD_HANDLE)
1444                         rec->handle = data->val.uint32;
1445
1446                 if (attr == SDP_ATTR_SVCLASS_ID_LIST)
1447                         extract_svclass_uuid(data, &rec->svclass);
1448
1449                 extracted += n;
1450                 p += n;
1451                 bufsize -= n;
1452                 sdp_attr_replace(rec, attr, data);
1453
1454                 SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d",
1455                                                         seqlen, extracted);
1456         }
1457 #ifdef SDP_DEBUG
1458         SDPDBG("Successful extracting of Svc Rec attributes");
1459         sdp_print_service_attr(rec->attrlist);
1460 #endif
1461         *scanned += seqlen;
1462         return rec;
1463 }
1464
1465 static void sdp_copy_pattern(void *value, void *udata)
1466 {
1467         uuid_t *uuid = value;
1468         sdp_record_t *rec = udata;
1469
1470         sdp_pattern_add_uuid(rec, uuid);
1471 }
1472
1473 static void *sdp_data_value(sdp_data_t *data, uint32_t *len)
1474 {
1475         void *val = NULL;
1476
1477         switch (data->dtd) {
1478         case SDP_DATA_NIL:
1479                 break;
1480         case SDP_UINT8:
1481                 val = &data->val.uint8;
1482                 break;
1483         case SDP_INT8:
1484         case SDP_BOOL:
1485                 val = &data->val.int8;
1486                 break;
1487         case SDP_UINT16:
1488                 val = &data->val.uint16;
1489                 break;
1490         case SDP_INT16:
1491                 val = &data->val.int16;
1492                 break;
1493         case SDP_UINT32:
1494                 val = &data->val.uint32;
1495                 break;
1496         case SDP_INT32:
1497                 val = &data->val.int32;
1498                 break;
1499         case SDP_INT64:
1500                 val = &data->val.int64;
1501                 break;
1502         case SDP_UINT64:
1503                 val = &data->val.uint64;
1504                 break;
1505         case SDP_UINT128:
1506                 val = &data->val.uint128;
1507                 break;
1508         case SDP_INT128:
1509                 val = &data->val.int128;
1510                 break;
1511         case SDP_UUID16:
1512                 val = &data->val.uuid.value.uuid16;
1513                 break;
1514         case SDP_UUID32:
1515                 val = &data->val.uuid.value.uuid32;
1516                 break;
1517         case SDP_UUID128:
1518                 val = &data->val.uuid.value.uuid128;
1519                 break;
1520         case SDP_URL_STR8:
1521         case SDP_URL_STR16:
1522         case SDP_TEXT_STR8:
1523         case SDP_TEXT_STR16:
1524         case SDP_URL_STR32:
1525         case SDP_TEXT_STR32:
1526                 val = data->val.str;
1527                 if (len)
1528                         *len = data->unitSize - 1;
1529                 break;
1530         case SDP_ALT8:
1531         case SDP_ALT16:
1532         case SDP_ALT32:
1533         case SDP_SEQ8:
1534         case SDP_SEQ16:
1535         case SDP_SEQ32:
1536                 val = sdp_copy_seq(data->val.dataseq);
1537                 break;
1538         }
1539
1540         return val;
1541 }
1542
1543 static sdp_data_t *sdp_copy_seq(sdp_data_t *data)
1544 {
1545         sdp_data_t *tmp, *seq = NULL, *cur = NULL;
1546
1547         for (tmp = data; tmp; tmp = tmp->next) {
1548                 sdp_data_t *datatmp;
1549                 void *value;
1550
1551                 value = sdp_data_value(tmp, NULL);
1552                 datatmp = sdp_data_alloc_with_length(tmp->dtd, value,
1553                                                                 tmp->unitSize);
1554
1555                 if (cur)
1556                         cur->next = datatmp;
1557                 else
1558                         seq = datatmp;
1559
1560                 cur = datatmp;
1561         }
1562
1563         return seq;
1564 }
1565
1566 static void sdp_copy_attrlist(void *value, void *udata)
1567 {
1568         sdp_data_t *data = value;
1569         sdp_record_t *rec = udata;
1570         void *val;
1571         uint32_t len = 0;
1572
1573         val = sdp_data_value(data, &len);
1574
1575         if (!len)
1576                 sdp_attr_add_new(rec, data->attrId, data->dtd, val);
1577         else
1578                 sdp_attr_add_new_with_length(rec, data->attrId,
1579                                                         data->dtd, val, len);
1580 }
1581
1582 sdp_record_t *sdp_copy_record(sdp_record_t *rec)
1583 {
1584         sdp_record_t *cpy;
1585
1586         cpy = sdp_record_alloc();
1587
1588         cpy->handle = rec->handle;
1589
1590         sdp_list_foreach(rec->pattern, sdp_copy_pattern, cpy);
1591         sdp_list_foreach(rec->attrlist, sdp_copy_attrlist, cpy);
1592
1593         cpy->svclass = rec->svclass;
1594
1595         return cpy;
1596 }
1597
1598 #ifdef SDP_DEBUG
1599 static void print_dataseq(sdp_data_t *p)
1600 {
1601         sdp_data_t *d;
1602
1603         for (d = p; d; d = d->next)
1604                 sdp_data_print(d);
1605 }
1606 #endif
1607
1608 void sdp_record_print(const sdp_record_t *rec)
1609 {
1610         sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
1611         if (d && SDP_IS_TEXT_STR(d->dtd))
1612                 printf("Service Name: %.*s\n", d->unitSize, d->val.str);
1613         d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);
1614         if (d && SDP_IS_TEXT_STR(d->dtd))
1615                 printf("Service Description: %.*s\n", d->unitSize, d->val.str);
1616         d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY);
1617         if (d && SDP_IS_TEXT_STR(d->dtd))
1618                 printf("Service Provider: %.*s\n", d->unitSize, d->val.str);
1619 }
1620
1621 #ifdef SDP_DEBUG
1622 void sdp_data_print(sdp_data_t *d)
1623 {
1624         switch (d->dtd) {
1625         case SDP_DATA_NIL:
1626                 SDPDBG("NIL");
1627                 break;
1628         case SDP_BOOL:
1629         case SDP_UINT8:
1630         case SDP_UINT16:
1631         case SDP_UINT32:
1632         case SDP_UINT64:
1633         case SDP_UINT128:
1634         case SDP_INT8:
1635         case SDP_INT16:
1636         case SDP_INT32:
1637         case SDP_INT64:
1638         case SDP_INT128:
1639                 SDPDBG("Integer : 0x%x", d->val.uint32);
1640                 break;
1641         case SDP_UUID16:
1642         case SDP_UUID32:
1643         case SDP_UUID128:
1644                 SDPDBG("UUID");
1645                 sdp_uuid_print(&d->val.uuid);
1646                 break;
1647         case SDP_TEXT_STR8:
1648         case SDP_TEXT_STR16:
1649         case SDP_TEXT_STR32:
1650                 SDPDBG("Text : %s", d->val.str);
1651                 break;
1652         case SDP_URL_STR8:
1653         case SDP_URL_STR16:
1654         case SDP_URL_STR32:
1655                 SDPDBG("URL : %s", d->val.str);
1656                 break;
1657         case SDP_SEQ8:
1658         case SDP_SEQ16:
1659         case SDP_SEQ32:
1660                 print_dataseq(d->val.dataseq);
1661                 break;
1662         case SDP_ALT8:
1663         case SDP_ALT16:
1664         case SDP_ALT32:
1665                 SDPDBG("Data Sequence Alternates");
1666                 print_dataseq(d->val.dataseq);
1667                 break;
1668         }
1669 }
1670 #endif
1671
1672 sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId)
1673 {
1674         if (rec && rec->attrlist) {
1675                 sdp_data_t sdpTemplate;
1676                 sdp_list_t *p;
1677
1678                 sdpTemplate.attrId = attrId;
1679                 p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func);
1680                 if (p)
1681                         return p->data;
1682         }
1683         return NULL;
1684 }
1685
1686 static int sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size)
1687 {
1688         uint32_t sent = 0;
1689
1690         while (sent < size) {
1691                 int n = send(session->sock, buf + sent, size - sent, 0);
1692                 if (n < 0)
1693                         return -1;
1694                 sent += n;
1695         }
1696         return 0;
1697 }
1698
1699 static int sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size)
1700 {
1701         fd_set readFds;
1702         struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 };
1703
1704         FD_ZERO(&readFds);
1705         FD_SET(session->sock, &readFds);
1706         SDPDBG("Waiting for response");
1707         if (select(session->sock + 1, &readFds, NULL, NULL, &timeout) == 0) {
1708                 SDPERR("Client timed out");
1709                 errno = ETIMEDOUT;
1710                 return -1;
1711         }
1712         return recv(session->sock, buf, size, 0);
1713 }
1714
1715 /*
1716  * generic send request, wait for response method.
1717  */
1718 int sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf,
1719                         uint8_t *rspbuf, uint32_t reqsize, uint32_t *rspsize)
1720 {
1721         int n;
1722         sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *) reqbuf;
1723         sdp_pdu_hdr_t *rsphdr = (sdp_pdu_hdr_t *) rspbuf;
1724
1725         SDPDBG("");
1726         if (0 > sdp_send_req(session, reqbuf, reqsize)) {
1727                 SDPERR("Error sending data:%m");
1728                 return -1;
1729         }
1730         n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
1731         if (0 > n)
1732                 return -1;
1733         SDPDBG("Read : %d", n);
1734         if (n == 0 || reqhdr->tid != rsphdr->tid) {
1735                 errno = EPROTO;
1736                 return -1;
1737         }
1738         *rspsize = n;
1739         return 0;
1740 }
1741
1742 /*
1743  * singly-linked lists (after openobex implementation)
1744  */
1745 sdp_list_t *sdp_list_append(sdp_list_t *p, void *d)
1746 {
1747         sdp_list_t *q, *n = malloc(sizeof(sdp_list_t));
1748
1749         if (!n)
1750                 return NULL;
1751
1752         n->data = d;
1753         n->next = 0;
1754
1755         if (!p)
1756                 return n;
1757
1758         for (q = p; q->next; q = q->next);
1759         q->next = n;
1760
1761         return p;
1762 }
1763
1764 sdp_list_t *sdp_list_remove(sdp_list_t *list, void *d)
1765 {
1766         sdp_list_t *p, *q;
1767
1768         for (q = 0, p = list; p; q = p, p = p->next)
1769                 if (p->data == d) {
1770                         if (q)
1771                                 q->next = p->next;
1772                         else
1773                                 list = p->next;
1774                         free(p);
1775                         break;
1776                 }
1777
1778         return list;
1779 }
1780
1781 sdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d,
1782                                                         sdp_comp_func_t f)
1783 {
1784         sdp_list_t *q, *p, *n;
1785
1786         n = malloc(sizeof(sdp_list_t));
1787         if (!n)
1788                 return NULL;
1789         n->data = d;
1790         for (q = 0, p = list; p; q = p, p = p->next)
1791                 if (f(p->data, d) >= 0)
1792                         break;
1793         /* insert between q and p; if !q insert at head */
1794         if (q)
1795                 q->next = n;
1796         else
1797                 list = n;
1798         n->next = p;
1799         return list;
1800 }
1801
1802 /*
1803  * Every element of the list points to things which need
1804  * to be free()'d. This method frees the list's contents
1805  */
1806 void sdp_list_free(sdp_list_t *list, sdp_free_func_t f)
1807 {
1808         sdp_list_t *next;
1809         while (list) {
1810                 next = list->next;
1811                 if (f)
1812                         f(list->data);
1813                 free(list);
1814                 list = next;
1815         }
1816 }
1817
1818 static inline int __find_port(sdp_data_t *seq, int proto)
1819 {
1820         if (!seq || !seq->next)
1821                 return 0;
1822
1823         if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) {
1824                 seq = seq->next;
1825                 switch (seq->dtd) {
1826                 case SDP_UINT8:
1827                         return seq->val.uint8;
1828                 case SDP_UINT16:
1829                         return seq->val.uint16;
1830                 }
1831         }
1832         return 0;
1833 }
1834
1835 int sdp_get_proto_port(const sdp_list_t *list, int proto)
1836 {
1837         if (proto != L2CAP_UUID && proto != RFCOMM_UUID) {
1838                 errno = EINVAL;
1839                 return -1;
1840         }
1841
1842         for (; list; list = list->next) {
1843                 sdp_list_t *p;
1844                 for (p = list->data; p; p = p->next) {
1845                         sdp_data_t *seq = p->data;
1846                         int port = __find_port(seq, proto);
1847                         if (port)
1848                                 return port;
1849                 }
1850         }
1851         return 0;
1852 }
1853
1854 sdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto)
1855 {
1856         for (; list; list = list->next) {
1857                 sdp_list_t *p;
1858                 for (p = list->data; p; p = p->next) {
1859                         sdp_data_t *seq = p->data;
1860                         if (SDP_IS_UUID(seq->dtd) &&
1861                                         sdp_uuid_to_proto(&seq->val.uuid) == proto)
1862                                 return seq->next;
1863                 }
1864         }
1865         return NULL;
1866 }
1867
1868 static int sdp_get_proto_descs(uint16_t attr_id, const sdp_record_t *rec,
1869                                                         sdp_list_t **pap)
1870 {
1871         sdp_data_t *pdlist, *curr;
1872         sdp_list_t *ap = NULL;
1873
1874         pdlist = sdp_data_get(rec, attr_id);
1875         if (pdlist == NULL) {
1876                 errno = ENODATA;
1877                 return -1;
1878         }
1879
1880         SDPDBG("Attribute value type: 0x%02x", pdlist->dtd);
1881
1882         if (attr_id == SDP_ATTR_ADD_PROTO_DESC_LIST) {
1883                 if (!SDP_IS_SEQ(pdlist->dtd)) {
1884                         errno = EINVAL;
1885                         return -1;
1886                 }
1887                 pdlist = pdlist->val.dataseq;
1888         }
1889
1890         for (; pdlist; pdlist = pdlist->next) {
1891                 sdp_list_t *pds = NULL;
1892
1893                 if (!SDP_IS_SEQ(pdlist->dtd) && !SDP_IS_ALT(pdlist->dtd))
1894                         goto failed;
1895
1896                 for (curr = pdlist->val.dataseq; curr; curr = curr->next) {
1897                         if (!SDP_IS_SEQ(curr->dtd)) {
1898                                 sdp_list_free(pds, NULL);
1899                                 goto failed;
1900                         }
1901                         pds = sdp_list_append(pds, curr->val.dataseq);
1902                 }
1903
1904                 ap = sdp_list_append(ap, pds);
1905         }
1906
1907         *pap = ap;
1908
1909         return 0;
1910
1911 failed:
1912         sdp_list_foreach(ap, (sdp_list_func_t) sdp_list_free, NULL);
1913         sdp_list_free(ap, NULL);
1914         errno = EINVAL;
1915
1916         return -1;
1917 }
1918
1919 int sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1920 {
1921         return sdp_get_proto_descs(SDP_ATTR_PROTO_DESC_LIST, rec, pap);
1922 }
1923
1924 int sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1925 {
1926         return sdp_get_proto_descs(SDP_ATTR_ADD_PROTO_DESC_LIST, rec, pap);
1927 }
1928
1929 int sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr,
1930                                                         sdp_list_t **seqp)
1931 {
1932         sdp_data_t *sdpdata = sdp_data_get(rec, attr);
1933
1934         *seqp = NULL;
1935         if (sdpdata && SDP_IS_SEQ(sdpdata->dtd)) {
1936                 sdp_data_t *d;
1937                 for (d = sdpdata->val.dataseq; d; d = d->next) {
1938                         uuid_t *u;
1939                         if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128) {
1940                                 errno = EINVAL;
1941                                 goto fail;
1942                         }
1943
1944                         u = malloc(sizeof(uuid_t));
1945                         if (!u)
1946                                 goto fail;
1947
1948                         *u = d->val.uuid;
1949                         *seqp = sdp_list_append(*seqp, u);
1950                 }
1951                 return 0;
1952         }
1953 fail:
1954         sdp_list_free(*seqp, free);
1955         *seqp = NULL;
1956         return -1;
1957 }
1958
1959 int sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq)
1960 {
1961         int status = 0, i, len;
1962         void **dtds, **values;
1963         uint8_t uuid16 = SDP_UUID16;
1964         uint8_t uuid32 = SDP_UUID32;
1965         uint8_t uuid128 = SDP_UUID128;
1966         sdp_list_t *p;
1967
1968         len = sdp_list_len(seq);
1969         if (!seq || len == 0)
1970                 return -1;
1971         dtds = malloc(len * sizeof(void *));
1972         if (!dtds)
1973                 return -1;
1974
1975         values = malloc(len * sizeof(void *));
1976         if (!values) {
1977                 free(dtds);
1978                 return -1;
1979         }
1980
1981         for (p = seq, i = 0; i < len; i++, p = p->next) {
1982                 uuid_t *uuid = p->data;
1983                 if (uuid)
1984                         switch (uuid->type) {
1985                         case SDP_UUID16:
1986                                 dtds[i] = &uuid16;
1987                                 values[i] = &uuid->value.uuid16;
1988                                 break;
1989                         case SDP_UUID32:
1990                                 dtds[i] = &uuid32;
1991                                 values[i] = &uuid->value.uuid32;
1992                                 break;
1993                         case SDP_UUID128:
1994                                 dtds[i] = &uuid128;
1995                                 values[i] = &uuid->value.uuid128;
1996                                 break;
1997                         default:
1998                                 status = -1;
1999                                 break;
2000                         }
2001                 else {
2002                         status = -1;
2003                         break;
2004                 }
2005         }
2006         if (status == 0) {
2007                 sdp_data_t *data = sdp_seq_alloc(dtds, values, len);
2008                 sdp_attr_replace(rec, aid, data);
2009                 sdp_pattern_add_uuidseq(rec, seq);
2010         }
2011         free(dtds);
2012         free(values);
2013         return status;
2014 }
2015
2016 int sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq)
2017 {
2018         sdp_lang_attr_t *lang;
2019         sdp_data_t *sdpdata, *curr_data;
2020
2021         *langSeq = NULL;
2022         sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST);
2023         if (sdpdata == NULL) {
2024                 errno = ENODATA;
2025                 return -1;
2026         }
2027
2028         if (!SDP_IS_SEQ(sdpdata->dtd))
2029                 goto invalid;
2030         curr_data = sdpdata->val.dataseq;
2031
2032         while (curr_data) {
2033                 sdp_data_t *pCode, *pEncoding, *pOffset;
2034
2035                 pCode = curr_data;
2036                 if (pCode->dtd != SDP_UINT16)
2037                         goto invalid;
2038
2039                 /* LanguageBaseAttributeIDList entries are always grouped as
2040                  * triplets */
2041                 if (!pCode->next || !pCode->next->next)
2042                         goto invalid;
2043
2044                 pEncoding = pCode->next;
2045                 if (pEncoding->dtd != SDP_UINT16)
2046                         goto invalid;
2047
2048                 pOffset = pEncoding->next;
2049                 if (pOffset->dtd != SDP_UINT16)
2050                         goto invalid;
2051
2052                 lang = malloc(sizeof(sdp_lang_attr_t));
2053                 if (!lang) {
2054                         sdp_list_free(*langSeq, free);
2055                         *langSeq = NULL;
2056                         return -1;
2057                 }
2058                 lang->code_ISO639 = pCode->val.uint16;
2059                 lang->encoding = pEncoding->val.uint16;
2060                 lang->base_offset = pOffset->val.uint16;
2061                 SDPDBG("code_ISO639 :  0x%02x", lang->code_ISO639);
2062                 SDPDBG("encoding :     0x%02x", lang->encoding);
2063                 SDPDBG("base_offfset : 0x%02x", lang->base_offset);
2064                 *langSeq = sdp_list_append(*langSeq, lang);
2065
2066                 curr_data = pOffset->next;
2067         }
2068
2069         return 0;
2070
2071 invalid:
2072         sdp_list_free(*langSeq, free);
2073         *langSeq = NULL;
2074         errno = EINVAL;
2075
2076         return -1;
2077 }
2078
2079 int sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq)
2080 {
2081         sdp_profile_desc_t *profDesc;
2082         sdp_data_t *sdpdata, *seq;
2083
2084         *profDescSeq = NULL;
2085         sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST);
2086         if (sdpdata == NULL) {
2087                 errno = ENODATA;
2088                 return -1;
2089         }
2090
2091         if (!SDP_IS_SEQ(sdpdata->dtd) || sdpdata->val.dataseq == NULL)
2092                 goto invalid;
2093
2094         for (seq = sdpdata->val.dataseq; seq; seq = seq->next) {
2095                 uuid_t *uuid = NULL;
2096                 uint16_t version = 0x100;
2097
2098                 if (SDP_IS_UUID(seq->dtd)) {
2099                         /* Mac OS X 10.7.3 and old Samsung phones do not comply
2100                          * to the SDP specification for
2101                          * BluetoothProfileDescriptorList. This workaround
2102                          * allows to properly parse UUID/version from SDP
2103                          * record published by these systems. */
2104                         sdp_data_t *next = seq->next;
2105                         uuid = &seq->val.uuid;
2106                         if (next && next->dtd == SDP_UINT16) {
2107                                 version = next->val.uint16;
2108                                 seq = next;
2109                         }
2110                 } else if (SDP_IS_SEQ(seq->dtd)) {
2111                         sdp_data_t *puuid, *pVnum;
2112
2113                         puuid = seq->val.dataseq;
2114                         if (puuid == NULL || !SDP_IS_UUID(puuid->dtd))
2115                                 goto invalid;
2116
2117                         uuid = &puuid->val.uuid;
2118
2119                         pVnum = puuid->next;
2120                         if (pVnum == NULL || pVnum->dtd != SDP_UINT16)
2121                                 goto invalid;
2122
2123                         version = pVnum->val.uint16;
2124                 } else
2125                         goto invalid;
2126
2127                 if (uuid != NULL) {
2128                         profDesc = malloc(sizeof(sdp_profile_desc_t));
2129                         if (!profDesc) {
2130                                 sdp_list_free(*profDescSeq, free);
2131                                 *profDescSeq = NULL;
2132                                 return -1;
2133                         }
2134                         profDesc->uuid = *uuid;
2135                         profDesc->version = version;
2136 #ifdef SDP_DEBUG
2137                         sdp_uuid_print(&profDesc->uuid);
2138                         SDPDBG("Vnum : 0x%04x", profDesc->version);
2139 #endif
2140                         *profDescSeq = sdp_list_append(*profDescSeq, profDesc);
2141                 }
2142         }
2143         return 0;
2144
2145 invalid:
2146         sdp_list_free(*profDescSeq, free);
2147         *profDescSeq = NULL;
2148         errno = EINVAL;
2149
2150         return -1;
2151 }
2152
2153 int sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16)
2154 {
2155         sdp_data_t *d, *curr;
2156
2157         *u16 = NULL;
2158         d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST);
2159         if (d == NULL) {
2160                 errno = ENODATA;
2161                 return -1;
2162         }
2163
2164         if (!SDP_IS_SEQ(d->dtd) || d->val.dataseq == NULL)
2165                 goto invalid;
2166
2167         for (curr = d->val.dataseq; curr; curr = curr->next) {
2168                 if (curr->dtd != SDP_UINT16)
2169                         goto invalid;
2170                 *u16 = sdp_list_append(*u16, &curr->val.uint16);
2171         }
2172
2173         return 0;
2174
2175 invalid:
2176         sdp_list_free(*u16, NULL);
2177         *u16 = NULL;
2178         errno = EINVAL;
2179
2180         return -1;
2181 }
2182
2183 /* flexible extraction of basic attributes - Jean II */
2184 /* How do we expect caller to extract predefined data sequences? */
2185 int sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value)
2186 {
2187         sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
2188
2189         if (sdpdata)
2190                 /* Verify that it is what the caller expects */
2191                 if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 ||
2192                 sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 ||
2193                 sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 ||
2194                 sdpdata->dtd == SDP_INT32) {
2195                         *value = sdpdata->val.uint32;
2196                         return 0;
2197                 }
2198         errno = EINVAL;
2199         return -1;
2200 }
2201
2202 int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value,
2203                                                                 int valuelen)
2204 {
2205         sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
2206         if (sdpdata)
2207                 /* Verify that it is what the caller expects */
2208                 if (SDP_IS_TEXT_STR(sdpdata->dtd))
2209                         if ((int) strlen(sdpdata->val.str) < valuelen) {
2210                                 strcpy(value, sdpdata->val.str);
2211                                 return 0;
2212                         }
2213         errno = EINVAL;
2214         return -1;
2215 }
2216
2217 #define get_basic_attr(attrID, pAttrValue, fieldName)           \
2218         sdp_data_t *data = sdp_data_get(rec, attrID);           \
2219         if (data) {                                             \
2220                 *pAttrValue = data->val.fieldName;              \
2221                 return 0;                                       \
2222         }                                                       \
2223         errno = EINVAL;                                         \
2224         return -1;
2225
2226 int sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid)
2227 {
2228         get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid);
2229 }
2230
2231 int sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid)
2232 {
2233         get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid);
2234 }
2235
2236 int sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState)
2237 {
2238         get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32);
2239 }
2240
2241 int sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail)
2242 {
2243         get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8);
2244 }
2245
2246 int sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo)
2247 {
2248         get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32);
2249 }
2250
2251 int sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState)
2252 {
2253         get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32);
2254 }
2255
2256 /*
2257  * NOTE that none of the setXXX() functions below will
2258  * actually update the SDP server, unless the
2259  * {register, update}sdp_record_t() function is invoked.
2260  */
2261
2262 int sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd,
2263                                                         const void *value)
2264 {
2265         sdp_data_t *d = sdp_data_alloc(dtd, value);
2266         if (d) {
2267                 sdp_attr_replace(rec, attr, d);
2268                 return 0;
2269         }
2270         return -1;
2271 }
2272
2273 static int sdp_attr_add_new_with_length(sdp_record_t *rec,
2274         uint16_t attr, uint8_t dtd, const void *value, uint32_t len)
2275 {
2276         sdp_data_t *d;
2277
2278         d = sdp_data_alloc_with_length(dtd, value, len);
2279         if (!d)
2280                 return -1;
2281
2282         sdp_attr_replace(rec, attr, d);
2283
2284         return 0;
2285 }
2286
2287 /*
2288  * Set the information attributes of the service
2289  * pointed to by rec. The attributes are
2290  * service name, description and provider name
2291  */
2292 void sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov,
2293                                                         const char *desc)
2294 {
2295         if (name)
2296                 sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY,
2297                                                         SDP_TEXT_STR8, name);
2298         if (prov)
2299                 sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY,
2300                                                         SDP_TEXT_STR8, prov);
2301         if (desc)
2302                 sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY,
2303                                                         SDP_TEXT_STR8, desc);
2304 }
2305
2306 static sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto)
2307 {
2308         sdp_data_t *seq = NULL;
2309         void *dtds[10], *values[10];
2310         void **seqDTDs, **seqs;
2311         int i, seqlen;
2312         sdp_list_t *p;
2313
2314         seqlen = sdp_list_len(proto);
2315         seqDTDs = malloc(seqlen * sizeof(void *));
2316         if (!seqDTDs)
2317                 return NULL;
2318
2319         seqs = malloc(seqlen * sizeof(void *));
2320         if (!seqs) {
2321                 free(seqDTDs);
2322                 return NULL;
2323         }
2324
2325         for (i = 0, p = proto; p; p = p->next, i++) {
2326                 sdp_list_t *elt = p->data;
2327                 sdp_data_t *s;
2328                 uuid_t *uuid = NULL;
2329                 unsigned int pslen = 0;
2330                 for (; elt && pslen < ARRAY_SIZE(dtds); elt = elt->next, pslen++) {
2331                         sdp_data_t *d = elt->data;
2332                         dtds[pslen] = &d->dtd;
2333                         switch (d->dtd) {
2334                         case SDP_UUID16:
2335                                 uuid = (uuid_t *) d;
2336                                 values[pslen] = &uuid->value.uuid16;
2337                                 break;
2338                         case SDP_UUID32:
2339                                 uuid = (uuid_t *) d;
2340                                 values[pslen] = &uuid->value.uuid32;
2341                                 break;
2342                         case SDP_UUID128:
2343                                 uuid = (uuid_t *) d;
2344                                 values[pslen] = &uuid->value.uuid128;
2345                                 break;
2346                         case SDP_UINT8:
2347                                 values[pslen] = &d->val.uint8;
2348                                 break;
2349                         case SDP_UINT16:
2350                                 values[pslen] = &d->val.uint16;
2351                                 break;
2352                         case SDP_SEQ8:
2353                         case SDP_SEQ16:
2354                         case SDP_SEQ32:
2355                                 values[pslen] = d;
2356                                 break;
2357                         /* FIXME: more */
2358                         }
2359                 }
2360                 s = sdp_seq_alloc(dtds, values, pslen);
2361                 if (s) {
2362                         seqDTDs[i] = &s->dtd;
2363                         seqs[i] = s;
2364                         if (uuid)
2365                                 sdp_pattern_add_uuid(rec, uuid);
2366                 }
2367         }
2368         seq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
2369         free(seqDTDs);
2370         free(seqs);
2371         return seq;
2372 }
2373
2374 /*
2375  * sets the access protocols of the service specified
2376  * to the value specified in "access_proto"
2377  *
2378  * Note that if there are alternate mechanisms by
2379  * which the service is accessed, then they should
2380  * be specified as sequences
2381  *
2382  * Using a value of NULL for accessProtocols has
2383  * effect of removing this attribute (if previously set)
2384  *
2385  * This function replaces the existing sdp_access_proto_t
2386  * structure (if any) with the new one specified.
2387  *
2388  * returns 0 if successful or -1 if there is a failure.
2389  */
2390 int sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
2391 {
2392         const sdp_list_t *p;
2393         sdp_data_t *protos = NULL;
2394
2395         for (p = ap; p; p = p->next) {
2396                 sdp_data_t *seq = access_proto_to_dataseq(rec, p->data);
2397                 protos = sdp_seq_append(protos, seq);
2398         }
2399
2400         sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos);
2401
2402         return 0;
2403 }
2404
2405 int sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
2406 {
2407         const sdp_list_t *p;
2408         sdp_data_t *protos = NULL;
2409
2410         for (p = ap; p; p = p->next) {
2411                 sdp_data_t *seq = access_proto_to_dataseq(rec, p->data);
2412                 protos = sdp_seq_append(protos, seq);
2413         }
2414
2415         sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST,
2416                         protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL);
2417
2418         return 0;
2419 }
2420
2421 /*
2422  * set the "LanguageBase" attributes of the service record
2423  * record to the value specified in "langAttrList".
2424  *
2425  * "langAttrList" is a linked list of "sdp_lang_attr_t"
2426  * objects, one for each language in which user visible
2427  * attributes are present in the service record.
2428  *
2429  * Using a value of NULL for langAttrList has
2430  * effect of removing this attribute (if previously set)
2431  *
2432  * This function replaces the exisiting sdp_lang_attr_t
2433  * structure (if any) with the new one specified.
2434  *
2435  * returns 0 if successful or -1 if there is a failure.
2436  */
2437 int sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq)
2438 {
2439         uint8_t uint16 = SDP_UINT16;
2440         int status = 0, i = 0, seqlen = sdp_list_len(seq);
2441         void **dtds, **values;
2442         const sdp_list_t *p;
2443
2444         dtds = malloc(3 * seqlen * sizeof(void *));
2445         if (!dtds)
2446                 return -1;
2447
2448         values = malloc(3 * seqlen * sizeof(void *));
2449         if (!values) {
2450                 free(dtds);
2451                 return -1;
2452         }
2453
2454         for (p = seq; p; p = p->next) {
2455                 sdp_lang_attr_t *lang = p->data;
2456                 if (!lang) {
2457                         status = -1;
2458                         break;
2459                 }
2460                 dtds[i] = &uint16;
2461                 values[i] = &lang->code_ISO639;
2462                 i++;
2463                 dtds[i] = &uint16;
2464                 values[i] = &lang->encoding;
2465                 i++;
2466                 dtds[i] = &uint16;
2467                 values[i] = &lang->base_offset;
2468                 i++;
2469         }
2470         if (status == 0) {
2471                 sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen);
2472                 sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq);
2473         }
2474         free(dtds);
2475         free(values);
2476         return status;
2477 }
2478
2479 /*
2480  * set the "ServiceID" attribute of the service.
2481  *
2482  * This is the UUID of the service.
2483  *
2484  * returns 0 if successful or -1 if there is a failure.
2485  */
2486 void sdp_set_service_id(sdp_record_t *rec, uuid_t uuid)
2487 {
2488         switch (uuid.type) {
2489         case SDP_UUID16:
2490                 sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16,
2491                                                         &uuid.value.uuid16);
2492                 break;
2493         case SDP_UUID32:
2494                 sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32,
2495                                                         &uuid.value.uuid32);
2496                 break;
2497         case SDP_UUID128:
2498                 sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128,
2499                                                         &uuid.value.uuid128);
2500                 break;
2501         }
2502         sdp_pattern_add_uuid(rec, &uuid);
2503 }
2504
2505 /*
2506  * set the GroupID attribute of the service record defining a group.
2507  *
2508  * This is the UUID of the group.
2509  *
2510  * returns 0 if successful or -1 if there is a failure.
2511  */
2512 void sdp_set_group_id(sdp_record_t *rec, uuid_t uuid)
2513 {
2514         switch (uuid.type) {
2515         case SDP_UUID16:
2516                 sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16,
2517                                                         &uuid.value.uuid16);
2518                 break;
2519         case SDP_UUID32:
2520                 sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32,
2521                                                         &uuid.value.uuid32);
2522                 break;
2523         case SDP_UUID128:
2524                 sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128,
2525                                                         &uuid.value.uuid128);
2526                 break;
2527         }
2528         sdp_pattern_add_uuid(rec, &uuid);
2529 }
2530
2531 /*
2532  * set the ProfileDescriptorList attribute of the service record
2533  * pointed to by record to the value specified in "profileDesc".
2534  *
2535  * Each element in the list is an object of type
2536  * sdp_profile_desc_t which is a definition of the
2537  * Bluetooth profile that this service conforms to.
2538  *
2539  * Using a value of NULL for profileDesc has
2540  * effect of removing this attribute (if previously set)
2541  *
2542  * This function replaces the exisiting ProfileDescriptorList
2543  * structure (if any) with the new one specified.
2544  *
2545  * returns 0 if successful or -1 if there is a failure.
2546  */
2547 int sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles)
2548 {
2549         int status = 0;
2550         uint8_t uuid16 = SDP_UUID16;
2551         uint8_t uuid32 = SDP_UUID32;
2552         uint8_t uuid128 = SDP_UUID128;
2553         uint8_t uint16 = SDP_UINT16;
2554         int i = 0, seqlen = sdp_list_len(profiles);
2555         void **seqDTDs, **seqs;
2556         const sdp_list_t *p;
2557         sdp_data_t *pAPSeq;
2558
2559         seqDTDs = malloc(seqlen * sizeof(void *));
2560         if (!seqDTDs)
2561                 return -1;
2562
2563         seqs = malloc(seqlen * sizeof(void *));
2564         if (!seqs) {
2565                 free(seqDTDs);
2566                 return -1;
2567         }
2568
2569         for (p = profiles; p; p = p->next) {
2570                 sdp_data_t *seq;
2571                 void *dtds[2], *values[2];
2572                 sdp_profile_desc_t *profile = p->data;
2573                 if (!profile) {
2574                         status = -1;
2575                         goto end;
2576                 }
2577                 switch (profile->uuid.type) {
2578                 case SDP_UUID16:
2579                         dtds[0] = &uuid16;
2580                         values[0] = &profile->uuid.value.uuid16;
2581                         break;
2582                 case SDP_UUID32:
2583                         dtds[0] = &uuid32;
2584                         values[0] = &profile->uuid.value.uuid32;
2585                         break;
2586                 case SDP_UUID128:
2587                         dtds[0] = &uuid128;
2588                         values[0] = &profile->uuid.value.uuid128;
2589                         break;
2590                 default:
2591                         status = -1;
2592                         goto end;
2593                 }
2594                 dtds[1] = &uint16;
2595                 values[1] = &profile->version;
2596                 seq = sdp_seq_alloc(dtds, values, 2);
2597
2598                 if (seq == NULL) {
2599                         status = -1;
2600                         goto end;
2601                 }
2602
2603                 seqDTDs[i] = &seq->dtd;
2604                 seqs[i] = seq;
2605                 sdp_pattern_add_uuid(rec, &profile->uuid);
2606                 i++;
2607         }
2608
2609         pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
2610         sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq);
2611 end:
2612         free(seqDTDs);
2613         free(seqs);
2614         return status;
2615 }
2616
2617 /*
2618  * sets various URL attributes of the service
2619  * pointed to by record. The URL include
2620  *
2621  * client: a URL to the client's
2622  *   platform specific (WinCE, PalmOS) executable
2623  *   code that can be used to access this service.
2624  *
2625  * doc: a URL pointing to service documentation
2626  *
2627  * icon: a URL to an icon that can be used to represent
2628  *   this service.
2629  *
2630  * Note that you need to pass NULL for any URLs
2631  * that you don't want to set or remove
2632  */
2633 void sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc,
2634                                                         const char *icon)
2635 {
2636         sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client);
2637         sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc);
2638         sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon);
2639 }
2640
2641 uuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val)
2642 {
2643         memset(u, 0, sizeof(uuid_t));
2644         u->type = SDP_UUID16;
2645         u->value.uuid16 = val;
2646         return u;
2647 }
2648
2649 uuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val)
2650 {
2651         memset(u, 0, sizeof(uuid_t));
2652         u->type = SDP_UUID32;
2653         u->value.uuid32 = val;
2654         return u;
2655 }
2656
2657 uuid_t *sdp_uuid128_create(uuid_t *u, const void *val)
2658 {
2659         memset(u, 0, sizeof(uuid_t));
2660         u->type = SDP_UUID128;
2661         memcpy(&u->value.uuid128, val, sizeof(uint128_t));
2662         return u;
2663 }
2664
2665 /*
2666  * UUID comparison function
2667  * returns 0 if uuidValue1 == uuidValue2 else -1
2668  */
2669 int sdp_uuid_cmp(const void *p1, const void *p2)
2670 {
2671         uuid_t *u1 = sdp_uuid_to_uuid128(p1);
2672         uuid_t *u2 = sdp_uuid_to_uuid128(p2);
2673         int ret;
2674
2675         ret = sdp_uuid128_cmp(u1, u2);
2676
2677         bt_free(u1);
2678         bt_free(u2);
2679
2680         return ret;
2681 }
2682
2683 /*
2684  * UUID comparison function
2685  * returns 0 if uuidValue1 == uuidValue2 else -1
2686  */
2687 int sdp_uuid16_cmp(const void *p1, const void *p2)
2688 {
2689         const uuid_t *u1 = p1;
2690         const uuid_t *u2 = p2;
2691         return memcmp(&u1->value.uuid16, &u2->value.uuid16, sizeof(uint16_t));
2692 }
2693
2694 /*
2695  * UUID comparison function
2696  * returns 0 if uuidValue1 == uuidValue2 else -1
2697  */
2698 int sdp_uuid128_cmp(const void *p1, const void *p2)
2699 {
2700         const uuid_t *u1 = p1;
2701         const uuid_t *u2 = p2;
2702         return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t));
2703 }
2704
2705 /*
2706  * 128 to 16 bit and 32 to 16 bit UUID conversion functions
2707  * yet to be implemented. Note that the input is in NBO in
2708  * both 32 and 128 bit UUIDs and conversion is needed
2709  */
2710 void sdp_uuid16_to_uuid128(uuid_t *uuid128, const uuid_t *uuid16)
2711 {
2712         /*
2713          * We have a 16 bit value, which needs to be added to
2714          * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base
2715          */
2716         unsigned short data1;
2717
2718         /* allocate a 128bit UUID and init to the Bluetooth base UUID */
2719         uuid128->value.uuid128 = bluetooth_base_uuid;
2720         uuid128->type = SDP_UUID128;
2721
2722         /* extract bytes 2 and 3 of 128bit BT base UUID */
2723         memcpy(&data1, &bluetooth_base_uuid.data[2], 2);
2724
2725         /* add the given UUID (16 bits) */
2726         data1 += htons(uuid16->value.uuid16);
2727
2728         /* set bytes 2 and 3 of the 128 bit value */
2729         memcpy(&uuid128->value.uuid128.data[2], &data1, 2);
2730 }
2731
2732 void sdp_uuid32_to_uuid128(uuid_t *uuid128, const uuid_t *uuid32)
2733 {
2734         /*
2735          * We have a 32 bit value, which needs to be added to
2736          * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base
2737          */
2738         unsigned int data0;
2739
2740         /* allocate a 128bit UUID and init to the Bluetooth base UUID */
2741         uuid128->value.uuid128 = bluetooth_base_uuid;
2742         uuid128->type = SDP_UUID128;
2743
2744         /* extract first 4 bytes */
2745         memcpy(&data0, &bluetooth_base_uuid.data[0], 4);
2746
2747         /* add the given UUID (32bits) */
2748         data0 += htonl(uuid32->value.uuid32);
2749
2750         /* set the 4 bytes of the 128 bit value */
2751         memcpy(&uuid128->value.uuid128.data[0], &data0, 4);
2752 }
2753
2754 uuid_t *sdp_uuid_to_uuid128(const uuid_t *uuid)
2755 {
2756         uuid_t *uuid128 = bt_malloc(sizeof(uuid_t));
2757
2758         if (!uuid128)
2759                 return NULL;
2760
2761         memset(uuid128, 0, sizeof(uuid_t));
2762         switch (uuid->type) {
2763         case SDP_UUID128:
2764                 *uuid128 = *uuid;
2765                 break;
2766         case SDP_UUID32:
2767                 sdp_uuid32_to_uuid128(uuid128, uuid);
2768                 break;
2769         case SDP_UUID16:
2770                 sdp_uuid16_to_uuid128(uuid128, uuid);
2771                 break;
2772         }
2773         return uuid128;
2774 }
2775
2776 /*
2777  * converts a 128-bit uuid to a 16/32-bit one if possible
2778  * returns true if uuid contains a 16/32-bit UUID at exit
2779  */
2780 int sdp_uuid128_to_uuid(uuid_t *uuid)
2781 {
2782         uint128_t *b = &bluetooth_base_uuid;
2783         uint128_t *u = &uuid->value.uuid128;
2784         uint32_t data;
2785         unsigned int i;
2786
2787         if (uuid->type != SDP_UUID128)
2788                 return 1;
2789
2790         for (i = 4; i < sizeof(b->data); i++)
2791                 if (b->data[i] != u->data[i])
2792                         return 0;
2793
2794         memcpy(&data, u->data, 4);
2795         data = htonl(data);
2796         if (data <= 0xffff) {
2797                 uuid->type = SDP_UUID16;
2798                 uuid->value.uuid16 = (uint16_t) data;
2799         } else {
2800                 uuid->type = SDP_UUID32;
2801                 uuid->value.uuid32 = data;
2802         }
2803         return 1;
2804 }
2805
2806 /*
2807  * convert a UUID to the 16-bit short-form
2808  */
2809 int sdp_uuid_to_proto(uuid_t *uuid)
2810 {
2811         uuid_t u = *uuid;
2812         if (sdp_uuid128_to_uuid(&u)) {
2813                 switch (u.type) {
2814                 case SDP_UUID16:
2815                         return u.value.uuid16;
2816                 case SDP_UUID32:
2817                         return u.value.uuid32;
2818                 }
2819         }
2820         return 0;
2821 }
2822
2823 /*
2824  * This function appends data to the PDU buffer "dst" from source "src".
2825  * The data length is also computed and set.
2826  * Should the PDU length exceed 2^8, then sequence type is
2827  * set accordingly and the data is memmove()'d.
2828  */
2829 void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len)
2830 {
2831         uint8_t *p = dst->data;
2832         uint8_t dtd = *p;
2833
2834         SDPDBG("Append src size: %d", len);
2835         SDPDBG("Append dst size: %d", dst->data_size);
2836         SDPDBG("Dst buffer size: %d", dst->buf_size);
2837         if (dst->data_size == 0 && dtd == 0) {
2838                 /* create initial sequence */
2839                 *p = SDP_SEQ8;
2840                 dst->data_size += sizeof(uint8_t);
2841                 /* reserve space for sequence size */
2842                 dst->data_size += sizeof(uint8_t);
2843         }
2844
2845         memcpy(dst->data + dst->data_size, data, len);
2846         dst->data_size += len;
2847
2848         dtd = *(uint8_t *) dst->data;
2849         if (dst->data_size > UCHAR_MAX && dtd == SDP_SEQ8) {
2850                 short offset = sizeof(uint8_t) + sizeof(uint8_t);
2851                 memmove(dst->data + offset + 1, dst->data + offset,
2852                                                 dst->data_size - offset);
2853                 *p = SDP_SEQ16;
2854                 dst->data_size += 1;
2855         }
2856         dtd = *(uint8_t *) p;
2857         p += sizeof(uint8_t);
2858         switch (dtd) {
2859         case SDP_SEQ8:
2860                 *(uint8_t *) p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t);
2861                 break;
2862         case SDP_SEQ16:
2863                 bt_put_be16(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t), p);
2864                 break;
2865         case SDP_SEQ32:
2866                 bt_put_be32(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t), p);
2867                 break;
2868         }
2869 }
2870
2871 void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d)
2872 {
2873         sdp_buf_t append;
2874
2875         memset(&append, 0, sizeof(sdp_buf_t));
2876         sdp_gen_buffer(&append, d);
2877         append.data = malloc(append.buf_size);
2878         if (!append.data)
2879                 return;
2880
2881         sdp_set_attrid(&append, d->attrId);
2882         sdp_gen_pdu(&append, d);
2883         sdp_append_to_buf(pdu, append.data, append.data_size);
2884         free(append.data);
2885 }
2886
2887 /*
2888  * Registers an sdp record.
2889  *
2890  * It is incorrect to call this method on a record that
2891  * has been already registered with the server.
2892  *
2893  * Returns zero on success, otherwise -1 (and sets errno).
2894  */
2895 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)
2896 {
2897         uint8_t *req, *rsp, *p;
2898         uint32_t reqsize, rspsize;
2899         sdp_pdu_hdr_t *reqhdr, *rsphdr;
2900         int status;
2901
2902         SDPDBG("");
2903
2904         if (!session->local) {
2905                 errno = EREMOTE;
2906                 return -1;
2907         }
2908         req = malloc(SDP_REQ_BUFFER_SIZE);
2909         rsp = malloc(SDP_RSP_BUFFER_SIZE);
2910         if (req == NULL || rsp == NULL) {
2911                 status = -1;
2912                 errno = ENOMEM;
2913                 goto end;
2914         }
2915
2916         reqhdr = (sdp_pdu_hdr_t *)req;
2917         reqhdr->pdu_id = SDP_SVC_REGISTER_REQ;
2918         reqhdr->tid    = htons(sdp_gen_tid(session));
2919         reqsize = sizeof(sdp_pdu_hdr_t) + 1;
2920         p = req + sizeof(sdp_pdu_hdr_t);
2921
2922         if (bacmp(device, BDADDR_ANY)) {
2923                 *p++ = flags | SDP_DEVICE_RECORD;
2924                 bacpy((bdaddr_t *) p, device);
2925                 p += sizeof(bdaddr_t);
2926                 reqsize += sizeof(bdaddr_t);
2927         } else
2928                 *p++ = flags;
2929
2930         memcpy(p, data, size);
2931         reqsize += size;
2932         reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2933
2934         status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize);
2935         if (status < 0)
2936                 goto end;
2937
2938         if (rspsize < sizeof(sdp_pdu_hdr_t)) {
2939                 SDPERR("Unexpected end of packet");
2940                 errno = EPROTO;
2941                 status = -1;
2942                 goto end;
2943         }
2944
2945         rsphdr = (sdp_pdu_hdr_t *) rsp;
2946         p = rsp + sizeof(sdp_pdu_hdr_t);
2947
2948         if (rsphdr->pdu_id == SDP_ERROR_RSP) {
2949                 /* Invalid service record */
2950                 errno = EINVAL;
2951                 status = -1;
2952         } else if (rsphdr->pdu_id != SDP_SVC_REGISTER_RSP) {
2953                 errno = EPROTO;
2954                 status = -1;
2955         } else {
2956                 if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint32_t)) {
2957                         SDPERR("Unexpected end of packet");
2958                         errno = EPROTO;
2959                         status = -1;
2960                         goto end;
2961                 }
2962                 if (handle)
2963                         *handle  = bt_get_be32(p);
2964         }
2965
2966 end:
2967         free(req);
2968         free(rsp);
2969
2970         return status;
2971 }
2972
2973 int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags)
2974 {
2975         sdp_buf_t pdu;
2976         uint32_t handle;
2977         int err;
2978
2979         SDPDBG("");
2980
2981         if (rec->handle && rec->handle != 0xffffffff) {
2982                 uint32_t handle = rec->handle;
2983                 sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
2984                 sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
2985         }
2986
2987         if (sdp_gen_record_pdu(rec, &pdu) < 0) {
2988                 errno = ENOMEM;
2989                 return -1;
2990         }
2991
2992         err = sdp_device_record_register_binary(session, device,
2993                                 pdu.data, pdu.data_size, flags, &handle);
2994
2995         free(pdu.data);
2996
2997         if (err == 0) {
2998                 sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
2999                 rec->handle = handle;
3000                 sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
3001         }
3002
3003         return err;
3004 }
3005
3006 int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags)
3007 {
3008         return sdp_device_record_register(session, BDADDR_ANY, rec, flags);
3009 }
3010
3011 /*
3012  * unregister a service record
3013  */
3014 int sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle)
3015 {
3016         uint8_t *reqbuf, *rspbuf, *p;
3017         uint32_t reqsize = 0, rspsize = 0;
3018         sdp_pdu_hdr_t *reqhdr, *rsphdr;
3019         int status;
3020
3021         SDPDBG("");
3022
3023         if (handle == SDP_SERVER_RECORD_HANDLE) {
3024                 errno = EINVAL;
3025                 return -1;
3026         }
3027
3028         if (!session->local) {
3029                 errno = EREMOTE;
3030                 return -1;
3031         }
3032
3033         reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3034         rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3035         if (!reqbuf || !rspbuf) {
3036                 errno = ENOMEM;
3037                 status = -1;
3038                 goto end;
3039         }
3040         reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3041         reqhdr->pdu_id = SDP_SVC_REMOVE_REQ;
3042         reqhdr->tid    = htons(sdp_gen_tid(session));
3043
3044         p = reqbuf + sizeof(sdp_pdu_hdr_t);
3045         reqsize = sizeof(sdp_pdu_hdr_t);
3046         bt_put_be32(handle, p);
3047         reqsize += sizeof(uint32_t);
3048
3049         reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3050         status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3051         if (status < 0)
3052                 goto end;
3053
3054         if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
3055                 SDPERR("Unexpected end of packet");
3056                 errno = EPROTO;
3057                 status = -1;
3058                 goto end;
3059         }
3060
3061         rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3062         p = rspbuf + sizeof(sdp_pdu_hdr_t);
3063
3064         if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3065                 /* For this case the status always is invalid record handle */
3066                 errno = EINVAL;
3067                 status = -1;
3068         } else if (rsphdr->pdu_id != SDP_SVC_REMOVE_RSP) {
3069                 errno = EPROTO;
3070                 status = -1;
3071         } else {
3072                 uint16_t tmp;
3073
3074                 memcpy(&tmp, p, sizeof(tmp));
3075
3076                 status = tmp;
3077         }
3078 end:
3079         free(reqbuf);
3080         free(rspbuf);
3081
3082         return status;
3083 }
3084
3085 int sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec)
3086 {
3087         int err;
3088
3089         err = sdp_device_record_unregister_binary(session, device, rec->handle);
3090         if (err == 0)
3091                 sdp_record_free(rec);
3092
3093         return err;
3094 }
3095
3096 int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec)
3097 {
3098         return sdp_device_record_unregister(session, BDADDR_ANY, rec);
3099 }
3100
3101 /*
3102  * modify an existing service record
3103  */
3104 int sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size)
3105 {
3106         return -1;
3107 }
3108
3109 int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec)
3110 {
3111         uint8_t *reqbuf, *rspbuf, *p;
3112         uint32_t reqsize, rspsize;
3113         sdp_pdu_hdr_t *reqhdr, *rsphdr;
3114         uint32_t handle;
3115         sdp_buf_t pdu;
3116         int status;
3117
3118         SDPDBG("");
3119
3120         handle = rec->handle;
3121
3122         if (handle == SDP_SERVER_RECORD_HANDLE) {
3123                 errno = EINVAL;
3124                 return -1;
3125         }
3126         if (!session->local) {
3127                 errno = EREMOTE;
3128                 return -1;
3129         }
3130         reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3131         rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3132         if (!reqbuf || !rspbuf) {
3133                 errno = ENOMEM;
3134                 status = -1;
3135                 goto end;
3136         }
3137         reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3138         reqhdr->pdu_id = SDP_SVC_UPDATE_REQ;
3139         reqhdr->tid    = htons(sdp_gen_tid(session));
3140
3141         p = reqbuf + sizeof(sdp_pdu_hdr_t);
3142         reqsize = sizeof(sdp_pdu_hdr_t);
3143
3144         bt_put_be32(handle, p);
3145         reqsize += sizeof(uint32_t);
3146         p += sizeof(uint32_t);
3147
3148         if (sdp_gen_record_pdu(rec, &pdu) < 0) {
3149                 errno = ENOMEM;
3150                 status = -1;
3151                 goto end;
3152         }
3153         memcpy(p, pdu.data, pdu.data_size);
3154         reqsize += pdu.data_size;
3155         free(pdu.data);
3156
3157         reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3158         status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3159         if (status < 0)
3160                 goto end;
3161
3162         if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
3163                 SDPERR("Unexpected end of packet");
3164                 errno = EPROTO;
3165                 status = -1;
3166                 goto end;
3167         }
3168
3169         SDPDBG("Send req status : %d", status);
3170
3171         rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3172         p = rspbuf + sizeof(sdp_pdu_hdr_t);
3173
3174         if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3175                 /* The status can be invalid sintax or invalid record handle */
3176                 errno = EINVAL;
3177                 status = -1;
3178         } else if (rsphdr->pdu_id != SDP_SVC_UPDATE_RSP) {
3179                 errno = EPROTO;
3180                 status = -1;
3181         } else {
3182                 uint16_t tmp;
3183
3184                 memcpy(&tmp, p, sizeof(tmp));
3185
3186                 status = tmp;
3187         }
3188 end:
3189         free(reqbuf);
3190         free(rspbuf);
3191         return status;
3192 }
3193
3194 int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec)
3195 {
3196         return sdp_device_record_update(session, BDADDR_ANY, rec);
3197 }
3198
3199 sdp_record_t *sdp_record_alloc(void)
3200 {
3201         sdp_record_t *rec = malloc(sizeof(sdp_record_t));
3202
3203         if (!rec)
3204                 return NULL;
3205
3206         memset(rec, 0, sizeof(sdp_record_t));
3207         rec->handle = 0xffffffff;
3208         return rec;
3209 }
3210
3211 /*
3212  * Free the contents of a service record
3213  */
3214 void sdp_record_free(sdp_record_t *rec)
3215 {
3216         sdp_list_free(rec->attrlist, (sdp_free_func_t) sdp_data_free);
3217         sdp_list_free(rec->pattern, free);
3218         free(rec);
3219 }
3220
3221 void sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid)
3222 {
3223         uuid_t *uuid128 = sdp_uuid_to_uuid128(uuid);
3224
3225         SDPDBG("Elements in target pattern : %d", sdp_list_len(rec->pattern));
3226         SDPDBG("Trying to add : 0x%lx", (unsigned long) uuid128);
3227
3228         if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL)
3229                 rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp);
3230         else
3231                 bt_free(uuid128);
3232
3233         SDPDBG("Elements in target pattern : %d", sdp_list_len(rec->pattern));
3234 }
3235
3236 void sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq)
3237 {
3238         for (; seq; seq = seq->next) {
3239                 uuid_t *uuid = (uuid_t *)seq->data;
3240                 sdp_pattern_add_uuid(rec, uuid);
3241         }
3242 }
3243
3244 /*
3245  * Extract a sequence of service record handles from a PDU buffer
3246  * and add the entries to a sdp_list_t. Note that the service record
3247  * handles are not in "data element sequence" form, but just like
3248  * an array of service handles
3249  */
3250 static void extract_record_handle_seq(uint8_t *pdu, int bufsize, sdp_list_t **seq, int count, unsigned int *scanned)
3251 {
3252         sdp_list_t *pSeq = *seq;
3253         uint8_t *pdata = pdu;
3254         int n;
3255
3256         for (n = 0; n < count; n++) {
3257                 uint32_t *pSvcRec;
3258                 if (bufsize < (int) sizeof(uint32_t)) {
3259                         SDPERR("Unexpected end of packet");
3260                         break;
3261                 }
3262                 pSvcRec = malloc(sizeof(uint32_t));
3263                 if (!pSvcRec)
3264                         break;
3265                 *pSvcRec = bt_get_be32(pdata);
3266                 pSeq = sdp_list_append(pSeq, pSvcRec);
3267                 pdata += sizeof(uint32_t);
3268                 *scanned += sizeof(uint32_t);
3269                 bufsize -= sizeof(uint32_t);
3270         }
3271         *seq = pSeq;
3272 }
3273 /*
3274  * Generate the attribute sequence pdu form
3275  * from sdp_list_t elements. Return length of attr seq
3276  */
3277 static int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd)
3278 {
3279         sdp_data_t *dataseq;
3280         void **types, **values;
3281         sdp_buf_t buf;
3282         int i, seqlen = sdp_list_len(seq);
3283
3284         /* Fill up the value and the dtd arrays */
3285         SDPDBG("");
3286
3287         SDPDBG("Seq length : %d", seqlen);
3288
3289         types = malloc(seqlen * sizeof(void *));
3290         if (!types)
3291                 return -ENOMEM;
3292
3293         values = malloc(seqlen * sizeof(void *));
3294         if (!values) {
3295                 free(types);
3296                 return -ENOMEM;
3297         }
3298
3299         for (i = 0; i < seqlen; i++) {
3300                 void *data = seq->data;
3301                 types[i] = &dtd;
3302                 if (SDP_IS_UUID(dtd))
3303                         data = &((uuid_t *)data)->value;
3304                 values[i] = data;
3305                 seq = seq->next;
3306         }
3307
3308         dataseq = sdp_seq_alloc(types, values, seqlen);
3309         if (!dataseq) {
3310                 free(types);
3311                 free(values);
3312                 return -ENOMEM;
3313         }
3314
3315         memset(&buf, 0, sizeof(sdp_buf_t));
3316         sdp_gen_buffer(&buf, dataseq);
3317         buf.data = malloc(buf.buf_size);
3318
3319         if (!buf.data) {
3320                 sdp_data_free(dataseq);
3321                 free(types);
3322                 free(values);
3323                 return -ENOMEM;
3324         }
3325
3326         SDPDBG("Data Seq : 0x%p", seq);
3327         seqlen = sdp_gen_pdu(&buf, dataseq);
3328         SDPDBG("Copying : %d", buf.data_size);
3329         memcpy(dst, buf.data, buf.data_size);
3330
3331         sdp_data_free(dataseq);
3332
3333         free(types);
3334         free(values);
3335         free(buf.data);
3336         return seqlen;
3337 }
3338
3339 static int gen_searchseq_pdu(uint8_t *dst, const sdp_list_t *seq)
3340 {
3341         uuid_t *uuid = seq->data;
3342         return gen_dataseq_pdu(dst, seq, uuid->type);
3343 }
3344
3345 static int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataType)
3346 {
3347         return gen_dataseq_pdu(dst, seq, dataType);
3348 }
3349
3350 typedef struct {
3351         uint8_t length;
3352         unsigned char data[16];
3353 } __attribute__ ((packed)) sdp_cstate_t;
3354
3355 static int copy_cstate(uint8_t *pdata, int pdata_len, const sdp_cstate_t *cstate)
3356 {
3357         if (cstate) {
3358                 uint8_t len = cstate->length;
3359                 if (len >= pdata_len) {
3360                         SDPERR("Continuation state size exceeds internal buffer");
3361                         len = pdata_len - 1;
3362                 }
3363                 *pdata++ = len;
3364                 memcpy(pdata, cstate->data, len);
3365                 return len + 1;
3366         }
3367         *pdata = 0;
3368         return 1;
3369 }
3370
3371 /*
3372  * This is a service search request.
3373  *
3374  * INPUT :
3375  *
3376  *   sdp_list_t *search
3377  *     Singly linked list containing elements of the search
3378  *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
3379  *     of the service to be searched
3380  *
3381  *   uint16_t max_rec_num
3382  *      A 16 bit integer which tells the service, the maximum
3383  *      entries that the client can handle in the response. The
3384  *      server is obliged not to return > max_rec_num entries
3385  *
3386  * OUTPUT :
3387  *
3388  *   int return value
3389  *     0:
3390  *       The request completed successfully. This does not
3391  *       mean the requested services were found
3392  *     -1:
3393  *       On any failure and sets errno
3394  *
3395  *   sdp_list_t **rsp_list
3396  *     This variable is set on a successful return if there are
3397  *     non-zero service handles. It is a singly linked list of
3398  *     service record handles (uint16_t)
3399  */
3400 int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search,
3401                         uint16_t max_rec_num, sdp_list_t **rsp)
3402 {
3403         int status = 0;
3404         uint32_t reqsize = 0, _reqsize;
3405         uint32_t rspsize = 0, rsplen;
3406         int seqlen = 0;
3407         int rec_count;
3408         unsigned scanned, pdata_len;
3409         uint8_t *pdata, *_pdata;
3410         uint8_t *reqbuf, *rspbuf;
3411         sdp_pdu_hdr_t *reqhdr, *rsphdr;
3412         sdp_cstate_t *cstate = NULL;
3413
3414         reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3415         rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3416         if (!reqbuf || !rspbuf) {
3417                 errno = ENOMEM;
3418                 status = -1;
3419                 goto end;
3420         }
3421         reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3422         reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
3423         pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
3424         reqsize = sizeof(sdp_pdu_hdr_t);
3425
3426         /* add service class IDs for search */
3427         seqlen = gen_searchseq_pdu(pdata, search);
3428
3429         SDPDBG("Data seq added : %d", seqlen);
3430
3431         /* set the length and increment the pointer */
3432         reqsize += seqlen;
3433         pdata += seqlen;
3434
3435         /* specify the maximum svc rec count that client expects */
3436         bt_put_be16(max_rec_num, pdata);
3437         reqsize += sizeof(uint16_t);
3438         pdata += sizeof(uint16_t);
3439
3440         _reqsize = reqsize;
3441         _pdata   = pdata;
3442         *rsp = NULL;
3443
3444         do {
3445                 /* Add continuation state or NULL (first time) */
3446                 reqsize = _reqsize + copy_cstate(_pdata,
3447                                         SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
3448
3449                 /* Set the request header's param length */
3450                 reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3451
3452                 reqhdr->tid  = htons(sdp_gen_tid(session));
3453                 /*
3454                  * Send the request, wait for response and if
3455                  * no error, set the appropriate values and return
3456                  */
3457                 status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3458                 if (status < 0)
3459                         goto end;
3460
3461                 if (rspsize < sizeof(sdp_pdu_hdr_t)) {
3462                         SDPERR("Unexpected end of packet");
3463                         status = -1;
3464                         goto end;
3465                 }
3466
3467                 rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3468                 rsplen = ntohs(rsphdr->plen);
3469
3470                 if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3471                         SDPDBG("Status : 0x%x", rsphdr->pdu_id);
3472                         status = -1;
3473                         goto end;
3474                 }
3475                 scanned = 0;
3476                 pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3477                 pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
3478
3479                 if (pdata_len < sizeof(uint16_t) + sizeof(uint16_t)) {
3480                         SDPERR("Unexpected end of packet");
3481                         status = -1;
3482                         goto end;
3483                 }
3484
3485                 /* net service record match count */
3486                 pdata += sizeof(uint16_t);
3487                 scanned += sizeof(uint16_t);
3488                 pdata_len -= sizeof(uint16_t);
3489                 rec_count = bt_get_be16(pdata);
3490                 pdata += sizeof(uint16_t);
3491                 scanned += sizeof(uint16_t);
3492                 pdata_len -= sizeof(uint16_t);
3493
3494                 SDPDBG("Current svc count: %d", rec_count);
3495                 SDPDBG("ResponseLength: %d", rsplen);
3496
3497                 if (!rec_count) {
3498                         status = -1;
3499                         goto end;
3500                 }
3501                 extract_record_handle_seq(pdata, pdata_len, rsp, rec_count, &scanned);
3502                 SDPDBG("BytesScanned : %d", scanned);
3503
3504                 if (rsplen > scanned) {
3505                         uint8_t cstate_len;
3506
3507                         if (rspsize < sizeof(sdp_pdu_hdr_t) + scanned + sizeof(uint8_t)) {
3508                                 SDPERR("Unexpected end of packet: continuation state data missing");
3509                                 status = -1;
3510                                 goto end;
3511                         }
3512
3513                         pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned;
3514                         cstate_len = *(uint8_t *) pdata;
3515                         if (cstate_len > 0) {
3516                                 cstate = (sdp_cstate_t *)pdata;
3517                                 SDPDBG("Cont state length: %d", cstate_len);
3518                         } else
3519                                 cstate = NULL;
3520                 }
3521         } while (cstate);
3522
3523 end:
3524         free(reqbuf);
3525         free(rspbuf);
3526
3527         return status;
3528 }
3529
3530 /*
3531  * This is a service attribute request.
3532  *
3533  * INPUT :
3534  *
3535  *   uint32_t handle
3536  *     The handle of the service for which the attribute(s) are
3537  *     requested
3538  *
3539  *   sdp_attrreq_type_t reqtype
3540  *     Attribute identifiers are 16 bit unsigned integers specified
3541  *     in one of 2 ways described below :
3542  *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3543  *        They are the actual attribute identifiers in ascending order
3544  *
3545  *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3546  *        The high-order 16bits is the start of range
3547  *        the low-order 16bits are the end of range
3548  *        0x0000 to 0xFFFF gets all attributes
3549  *
3550  *   sdp_list_t *attrid
3551  *     Singly linked list containing attribute identifiers desired.
3552  *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3553  *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3554  *
3555  * OUTPUT :
3556  *   return sdp_record_t *
3557  *     0:
3558  *       On any error and sets errno
3559  *     !0:
3560  *       The service record
3561  */
3562 sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle,
3563                         sdp_attrreq_type_t reqtype, const sdp_list_t *attrids)
3564 {
3565         uint32_t reqsize = 0, _reqsize;
3566         uint32_t rspsize = 0, rsp_count;
3567         int attr_list_len = 0;
3568         int seqlen = 0;
3569         unsigned int pdata_len;
3570         uint8_t *pdata, *_pdata;
3571         uint8_t *reqbuf, *rspbuf;
3572         sdp_pdu_hdr_t *reqhdr, *rsphdr;
3573         sdp_cstate_t *cstate = NULL;
3574         uint8_t cstate_len = 0;
3575         sdp_buf_t rsp_concat_buf;
3576         sdp_record_t *rec = 0;
3577
3578         if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
3579                 errno = EINVAL;
3580                 return NULL;
3581         }
3582
3583         memset(&rsp_concat_buf, 0, sizeof(sdp_buf_t));
3584
3585         reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3586         rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3587         if (!reqbuf || !rspbuf) {
3588                 errno = ENOMEM;
3589                 goto end;
3590         }
3591         reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3592         reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
3593
3594         pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
3595         reqsize = sizeof(sdp_pdu_hdr_t);
3596
3597         /* add the service record handle */
3598         bt_put_be32(handle, pdata);
3599         reqsize += sizeof(uint32_t);
3600         pdata += sizeof(uint32_t);
3601
3602         /* specify the response limit */
3603         bt_put_be16(65535, pdata);
3604         reqsize += sizeof(uint16_t);
3605         pdata += sizeof(uint16_t);
3606
3607         /* get attr seq PDU form */
3608         seqlen = gen_attridseq_pdu(pdata, attrids,
3609                 reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
3610         if (seqlen == -1) {
3611                 errno = EINVAL;
3612                 goto end;
3613         }
3614         pdata += seqlen;
3615         reqsize += seqlen;
3616         SDPDBG("Attr list length : %d", seqlen);
3617
3618         /* save before Continuation State */
3619         _pdata = pdata;
3620         _reqsize = reqsize;
3621
3622         do {
3623                 int status;
3624
3625                 /* add NULL continuation state */
3626                 reqsize = _reqsize + copy_cstate(_pdata,
3627                                         SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
3628
3629                 /* set the request header's param length */
3630                 reqhdr->tid  = htons(sdp_gen_tid(session));
3631                 reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3632
3633                 status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3634                 if (status < 0)
3635                         goto end;
3636
3637                 if (rspsize < sizeof(sdp_pdu_hdr_t)) {
3638                         SDPERR("Unexpected end of packet");
3639                         goto end;
3640                 }
3641
3642                 rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3643                 if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3644                         SDPDBG("PDU ID : 0x%x", rsphdr->pdu_id);
3645                         goto end;
3646                 }
3647                 pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3648                 pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
3649
3650                 if (pdata_len < sizeof(uint16_t)) {
3651                         SDPERR("Unexpected end of packet");
3652                         goto end;
3653                 }
3654
3655                 rsp_count = bt_get_be16(pdata);
3656                 attr_list_len += rsp_count;
3657                 pdata += sizeof(uint16_t);
3658                 pdata_len -= sizeof(uint16_t);
3659
3660                 /*
3661                  * if continuation state set need to re-issue request before
3662                  * parsing
3663                  */
3664                 if (pdata_len < rsp_count + sizeof(uint8_t)) {
3665                         SDPERR("Unexpected end of packet: continuation state data missing");
3666                         goto end;
3667                 }
3668                 cstate_len = *(uint8_t *) (pdata + rsp_count);
3669
3670                 SDPDBG("Response id : %d", rsphdr->pdu_id);
3671                 SDPDBG("Attrlist byte count : %d", rsp_count);
3672                 SDPDBG("sdp_cstate_t length : %d", cstate_len);
3673
3674                 /*
3675                  * a split response: concatenate intermediate responses
3676                  * and the last one (which has cstate_len == 0)
3677                  */
3678                 if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
3679                         uint8_t *targetPtr = NULL;
3680
3681                         cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
3682
3683                         /* build concatenated response buffer */
3684                         rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
3685                         rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
3686                         targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
3687                         memcpy(targetPtr, pdata, rsp_count);
3688                         rsp_concat_buf.data_size += rsp_count;
3689                 }
3690         } while (cstate);
3691
3692         if (attr_list_len > 0) {
3693                 int scanned = 0;
3694                 if (rsp_concat_buf.data_size != 0) {
3695                         pdata = rsp_concat_buf.data;
3696                         pdata_len = rsp_concat_buf.data_size;
3697                 }
3698                 rec = sdp_extract_pdu(pdata, pdata_len, &scanned);
3699         }
3700
3701 end:
3702         free(reqbuf);
3703         free(rsp_concat_buf.data);
3704         free(rspbuf);
3705         return rec;
3706 }
3707
3708 /*
3709  * SDP transaction structure for asynchronous search
3710  */
3711 struct sdp_transaction {
3712         sdp_callback_t *cb;     /* called when the transaction finishes */
3713         void *udata;            /* client user data */
3714         uint8_t *reqbuf;        /* pointer to request PDU */
3715         sdp_buf_t rsp_concat_buf;
3716         uint32_t reqsize;       /* without cstate */
3717         int err;                /* ZERO if success or the errno if failed */
3718 };
3719
3720 /*
3721  * Creates a new sdp session for asynchronous search
3722  * INPUT:
3723  *  int sk
3724  *     non-blocking L2CAP socket
3725  *
3726  * RETURN:
3727  *  sdp_session_t *
3728  *  NULL - On memory allocation failure
3729  */
3730 sdp_session_t *sdp_create(int sk, uint32_t flags)
3731 {
3732         sdp_session_t *session;
3733         struct sdp_transaction *t;
3734
3735         session = malloc(sizeof(sdp_session_t));
3736         if (!session) {
3737                 errno = ENOMEM;
3738                 return NULL;
3739         }
3740         memset(session, 0, sizeof(*session));
3741
3742         session->flags = flags;
3743         session->sock = sk;
3744
3745         t = malloc(sizeof(struct sdp_transaction));
3746         if (!t) {
3747                 errno = ENOMEM;
3748                 free(session);
3749                 return NULL;
3750         }
3751         memset(t, 0, sizeof(*t));
3752
3753         session->priv = t;
3754
3755         return session;
3756 }
3757
3758 /*
3759  * Sets the callback function/user data used to notify the application
3760  * that the asynchronous transaction finished. This function must be
3761  * called before request an asynchronous search.
3762  *
3763  * INPUT:
3764  *  sdp_session_t *session
3765  *      Current sdp session to be handled
3766  *  sdp_callback_t *cb
3767  *      callback to be called when the transaction finishes
3768  *  void *udata
3769  *      user data passed to callback
3770  * RETURN:
3771  *       0 - Success
3772  *      -1 - Failure
3773  */
3774 int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata)
3775 {
3776         struct sdp_transaction *t;
3777
3778         if (!session || !session->priv)
3779                 return -1;
3780
3781         t = session->priv;
3782         t->cb = func;
3783         t->udata = udata;
3784
3785         return 0;
3786 }
3787
3788 /*
3789  * This function starts an asynchronous service search request.
3790  * The incoming and outgoing data are stored in the transaction structure
3791  * buffers. When there is incoming data the sdp_process function must be
3792  * called to get the data and handle the continuation state.
3793  *
3794  * INPUT :
3795  *  sdp_session_t *session
3796  *     Current sdp session to be handled
3797  *
3798  *   sdp_list_t *search
3799  *     Singly linked list containing elements of the search
3800  *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
3801  *     of the service to be searched
3802  *
3803  *   uint16_t max_rec_num
3804  *      A 16 bit integer which tells the service, the maximum
3805  *      entries that the client can handle in the response. The
3806  *      server is obliged not to return > max_rec_num entries
3807  *
3808  * OUTPUT :
3809  *
3810  *   int return value
3811  *      0  - if the request has been sent properly
3812  *      -1 - On any failure and sets errno
3813  */
3814
3815 int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num)
3816 {
3817         struct sdp_transaction *t;
3818         sdp_pdu_hdr_t *reqhdr;
3819         uint8_t *pdata;
3820         int cstate_len, seqlen = 0;
3821
3822         if (!session || !session->priv)
3823                 return -1;
3824
3825         t = session->priv;
3826
3827         /* clean possible allocated buffer */
3828         free(t->rsp_concat_buf.data);
3829         memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
3830
3831         if (!t->reqbuf) {
3832                 t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3833                 if (!t->reqbuf) {
3834                         t->err = ENOMEM;
3835                         goto end;
3836                 }
3837         }
3838         memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3839
3840         reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3841         reqhdr->tid = htons(sdp_gen_tid(session));
3842         reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
3843
3844         /* generate PDU */
3845         pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3846         t->reqsize = sizeof(sdp_pdu_hdr_t);
3847
3848         /* add service class IDs for search */
3849         seqlen = gen_searchseq_pdu(pdata, search);
3850
3851         SDPDBG("Data seq added : %d", seqlen);
3852
3853         /* now set the length and increment the pointer */
3854         t->reqsize += seqlen;
3855         pdata += seqlen;
3856
3857         bt_put_be16(max_rec_num, pdata);
3858         t->reqsize += sizeof(uint16_t);
3859         pdata += sizeof(uint16_t);
3860
3861         /* set the request header's param length */
3862         cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
3863         reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3864
3865         if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3866                 SDPERR("Error sending data:%m");
3867                 t->err = errno;
3868                 goto end;
3869         }
3870
3871         return 0;
3872 end:
3873
3874         free(t->reqbuf);
3875         t->reqbuf = NULL;
3876
3877         return -1;
3878 }
3879
3880 /*
3881  * This function starts an asynchronous service attribute request.
3882  * The incoming and outgoing data are stored in the transaction structure
3883  * buffers. When there is incoming data the sdp_process function must be
3884  * called to get the data and handle the continuation state.
3885  *
3886  * INPUT :
3887  *  sdp_session_t *session
3888  *      Current sdp session to be handled
3889  *
3890  *   uint32_t handle
3891  *     The handle of the service for which the attribute(s) are
3892  *     requested
3893  *
3894  *   sdp_attrreq_type_t reqtype
3895  *     Attribute identifiers are 16 bit unsigned integers specified
3896  *     in one of 2 ways described below :
3897  *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3898  *        They are the actual attribute identifiers in ascending order
3899  *
3900  *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3901  *        The high-order 16bits is the start of range
3902  *        the low-order 16bits are the end of range
3903  *        0x0000 to 0xFFFF gets all attributes
3904  *
3905  *   sdp_list_t *attrid_list
3906  *     Singly linked list containing attribute identifiers desired.
3907  *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3908  *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3909  *
3910  * OUTPUT :
3911  *   int return value
3912  *       0 - if the request has been sent properly
3913  *      -1 - On any failure and sets errno
3914  */
3915
3916 int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
3917 {
3918         struct sdp_transaction *t;
3919         sdp_pdu_hdr_t *reqhdr;
3920         uint8_t *pdata;
3921         int cstate_len, seqlen = 0;
3922
3923         if (!session || !session->priv)
3924                 return -1;
3925
3926         t = session->priv;
3927
3928         /* clean possible allocated buffer */
3929         free(t->rsp_concat_buf.data);
3930         memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
3931
3932         if (!t->reqbuf) {
3933                 t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3934                 if (!t->reqbuf) {
3935                         t->err = ENOMEM;
3936                         goto end;
3937                 }
3938         }
3939         memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3940
3941         reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3942         reqhdr->tid = htons(sdp_gen_tid(session));
3943         reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
3944
3945         /* generate PDU */
3946         pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3947         t->reqsize = sizeof(sdp_pdu_hdr_t);
3948
3949         /* add the service record handle */
3950         bt_put_be32(handle, pdata);
3951         t->reqsize += sizeof(uint32_t);
3952         pdata += sizeof(uint32_t);
3953
3954         /* specify the response limit */
3955         bt_put_be16(65535, pdata);
3956         t->reqsize += sizeof(uint16_t);
3957         pdata += sizeof(uint16_t);
3958
3959         /* get attr seq PDU form */
3960         seqlen = gen_attridseq_pdu(pdata, attrid_list,
3961                         reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
3962         if (seqlen == -1) {
3963                 t->err = EINVAL;
3964                 goto end;
3965         }
3966
3967         /* now set the length and increment the pointer */
3968         t->reqsize += seqlen;
3969         pdata += seqlen;
3970         SDPDBG("Attr list length : %d", seqlen);
3971
3972         /* set the request header's param length */
3973         cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
3974         reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3975
3976         if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3977                 SDPERR("Error sending data:%m");
3978                 t->err = errno;
3979                 goto end;
3980         }
3981
3982         return 0;
3983 end:
3984
3985         free(t->reqbuf);
3986         t->reqbuf = NULL;
3987
3988         return -1;
3989 }
3990
3991 /*
3992  * This function starts an asynchronous service search attributes.
3993  * It is a service search request combined with attribute request. The incoming
3994  * and outgoing data are stored in the transaction structure buffers. When there
3995  * is incoming data the sdp_process function must be called to get the data
3996  * and handle the continuation state.
3997  *
3998  * INPUT:
3999  *  sdp_session_t *session
4000  *      Current sdp session to be handled
4001  *
4002  *   sdp_list_t *search
4003  *     Singly linked list containing elements of the search
4004  *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
4005  *     of the service to be searched
4006  *
4007  *   AttributeSpecification attrSpec
4008  *     Attribute identifiers are 16 bit unsigned integers specified
4009  *     in one of 2 ways described below :
4010  *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
4011  *        They are the actual attribute identifiers in ascending order
4012  *
4013  *     SDP_ATTR_REQ_RANGE - 32bit identifier range
4014  *        The high-order 16bits is the start of range
4015  *        the low-order 16bits are the end of range
4016  *        0x0000 to 0xFFFF gets all attributes
4017  *
4018  *   sdp_list_t *attrid_list
4019  *     Singly linked list containing attribute identifiers desired.
4020  *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
4021  *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
4022  *
4023
4024  * RETURN:
4025  *       0 - if the request has been sent properly
4026  *      -1 - On any failure
4027  */
4028 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)
4029 {
4030         struct sdp_transaction *t;
4031         sdp_pdu_hdr_t *reqhdr;
4032         uint8_t *pdata;
4033         int cstate_len, seqlen = 0;
4034
4035         if (!session || !session->priv)
4036                 return -1;
4037
4038         t = session->priv;
4039
4040         /* clean possible allocated buffer */
4041         free(t->rsp_concat_buf.data);
4042         memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
4043
4044         if (!t->reqbuf) {
4045                 t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
4046                 if (!t->reqbuf) {
4047                         t->err = ENOMEM;
4048                         goto end;
4049                 }
4050         }
4051         memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
4052
4053         reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
4054         reqhdr->tid = htons(sdp_gen_tid(session));
4055         reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
4056
4057         /* generate PDU */
4058         pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
4059         t->reqsize = sizeof(sdp_pdu_hdr_t);
4060
4061         /* add service class IDs for search */
4062         seqlen = gen_searchseq_pdu(pdata, search);
4063
4064         SDPDBG("Data seq added : %d", seqlen);
4065
4066         /* now set the length and increment the pointer */
4067         t->reqsize += seqlen;
4068         pdata += seqlen;
4069
4070         bt_put_be16(SDP_MAX_ATTR_LEN, pdata);
4071         t->reqsize += sizeof(uint16_t);
4072         pdata += sizeof(uint16_t);
4073
4074         SDPDBG("Max attr byte count : %d", SDP_MAX_ATTR_LEN);
4075
4076         /* get attr seq PDU form */
4077         seqlen = gen_attridseq_pdu(pdata, attrid_list,
4078                         reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
4079         if (seqlen == -1) {
4080                 t->err = EINVAL;
4081                 goto end;
4082         }
4083
4084         pdata += seqlen;
4085         SDPDBG("Attr list length : %d", seqlen);
4086         t->reqsize += seqlen;
4087
4088         /* set the request header's param length */
4089         cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
4090         reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
4091
4092         if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
4093                 SDPERR("Error sending data:%m");
4094                 t->err = errno;
4095                 goto end;
4096         }
4097
4098         return 0;
4099 end:
4100
4101         free(t->reqbuf);
4102         t->reqbuf = NULL;
4103
4104         return -1;
4105 }
4106
4107 /*
4108  * Function used to get the error reason after sdp_callback_t function has been called
4109  * and the status is 0xffff or if sdp_service_{search, attr, search_attr}_async returns -1.
4110  * It indicates that an error NOT related to SDP_ErrorResponse happened. Get errno directly
4111  * is not safe because multiple transactions can be triggered.
4112  * This function must be used with asynchronous sdp functions only.
4113  *
4114  * INPUT:
4115  *  sdp_session_t *session
4116  *      Current sdp session to be handled
4117  * RETURN:
4118  *       0 = No error in the current transaction
4119  *      -1 - if the session is invalid
4120  *      positive value - the errno value
4121  *
4122  */
4123 int sdp_get_error(sdp_session_t *session)
4124 {
4125         struct sdp_transaction *t;
4126
4127         if (!session || !session->priv) {
4128                 SDPERR("Invalid session");
4129                 return -1;
4130         }
4131
4132         t = session->priv;
4133
4134         return t->err;
4135 }
4136
4137 /*
4138  * Receive the incoming SDP PDU. This function must be called when there is data
4139  * available to be read. On continuation state, the original request (with a new
4140  * transaction ID) and the continuation state data will be appended in the initial PDU.
4141  * If an error happens or the transaction finishes the callback function will be called.
4142  *
4143  * INPUT:
4144  *  sdp_session_t *session
4145  *      Current sdp session to be handled
4146  * RETURN:
4147  *      0  - if the transaction is on continuation state
4148  *      -1 - On any failure or the transaction finished
4149  */
4150 int sdp_process(sdp_session_t *session)
4151 {
4152         struct sdp_transaction *t;
4153         sdp_pdu_hdr_t *reqhdr, *rsphdr;
4154         sdp_cstate_t *pcstate;
4155         uint8_t *pdata, *rspbuf, *targetPtr;
4156         int rsp_count, err = -1;
4157         size_t size = 0;
4158         int n, plen;
4159         uint16_t status = 0xffff;
4160         uint8_t pdu_id = 0x00;
4161
4162         if (!session || !session->priv) {
4163                 SDPERR("Invalid session");
4164                 return -1;
4165         }
4166
4167         rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
4168         if (!rspbuf) {
4169                 SDPERR("Response buffer alloc failure:%m (%d)", errno);
4170                 return -1;
4171         }
4172
4173         memset(rspbuf, 0, SDP_RSP_BUFFER_SIZE);
4174
4175         t = session->priv;
4176         reqhdr = (sdp_pdu_hdr_t *)t->reqbuf;
4177         rsphdr = (sdp_pdu_hdr_t *)rspbuf;
4178
4179         pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
4180
4181         n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
4182         if (n < 0) {
4183                 SDPERR("Read response:%m (%d)", errno);
4184                 t->err = errno;
4185                 goto end;
4186         }
4187
4188         if (reqhdr->tid != rsphdr->tid) {
4189                 t->err = EPROTO;
4190                 SDPERR("Protocol error: transaction id does not match");
4191                 goto end;
4192         }
4193
4194         if (n != (int) (ntohs(rsphdr->plen) + sizeof(sdp_pdu_hdr_t))) {
4195                 t->err = EPROTO;
4196                 SDPERR("Protocol error: invalid length");
4197                 goto end;
4198         }
4199
4200         pdu_id = rsphdr->pdu_id;
4201         switch (rsphdr->pdu_id) {
4202         uint8_t *ssr_pdata;
4203         uint16_t tsrc, csrc;
4204         case SDP_SVC_SEARCH_RSP:
4205                 /*
4206                  * TSRC: Total Service Record Count (2 bytes)
4207                  * CSRC: Current Service Record Count (2 bytes)
4208                  */
4209                 ssr_pdata = pdata;
4210                 tsrc = bt_get_be16(ssr_pdata);
4211                 ssr_pdata += sizeof(uint16_t);
4212                 csrc = bt_get_be16(ssr_pdata);
4213
4214                 /* csrc should never be larger than tsrc */
4215                 if (csrc > tsrc) {
4216                         t->err = EPROTO;
4217                         SDPERR("Protocol error: wrong current service record count value.");
4218                         goto end;
4219                 }
4220
4221                 SDPDBG("Total svc count: %d", tsrc);
4222                 SDPDBG("Current svc count: %d", csrc);
4223
4224                 /* parameter length without continuation state */
4225                 plen = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
4226
4227                 if (t->rsp_concat_buf.data_size == 0) {
4228                         /* first fragment */
4229                         rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
4230                 } else if (t->rsp_concat_buf.data_size >= sizeof(uint16_t) * 2) {
4231                         /* point to the first csrc */
4232                         uint8_t *pcsrc = t->rsp_concat_buf.data + 2;
4233                         uint16_t tcsrc, tcsrc2;
4234
4235                         /* FIXME: update the interface later. csrc doesn't need be passed to clients */
4236
4237                         pdata += sizeof(uint16_t); /* point to csrc */
4238
4239                         /* the first csrc contains the sum of partial csrc responses */
4240                         memcpy(&tcsrc, pcsrc, sizeof(tcsrc));
4241                         memcpy(&tcsrc2, pdata, sizeof(tcsrc2));
4242                         tcsrc += tcsrc2;
4243                         memcpy(pcsrc, &tcsrc, sizeof(tcsrc));
4244
4245                         pdata += sizeof(uint16_t); /* point to the first handle */
4246                         rsp_count = csrc * 4;
4247                 } else {
4248                         t->err = EPROTO;
4249                         SDPERR("Protocol error: invalid PDU size");
4250                         status = SDP_INVALID_PDU_SIZE;
4251                         goto end;
4252                 }
4253                 status = 0x0000;
4254                 break;
4255         case SDP_SVC_ATTR_RSP:
4256         case SDP_SVC_SEARCH_ATTR_RSP:
4257                 rsp_count = bt_get_be16(pdata);
4258                 SDPDBG("Attrlist byte count : %d", rsp_count);
4259
4260                 /* Valid range for rsp_count is 0x0002-0xFFFF */
4261                 if (t->rsp_concat_buf.data_size == 0 && rsp_count < 0x0002) {
4262                         t->err = EPROTO;
4263                         SDPERR("Protocol error: invalid AttrList size");
4264                         status = SDP_INVALID_PDU_SIZE;
4265                         goto end;
4266                 }
4267
4268                 /*
4269                  * Number of bytes in the AttributeLists parameter(without
4270                  * continuation state) + AttributeListsByteCount field size.
4271                  */
4272                 plen = sizeof(uint16_t) + rsp_count;
4273
4274                 pdata += sizeof(uint16_t); /* points to attribute list */
4275                 status = 0x0000;
4276                 break;
4277         case SDP_ERROR_RSP:
4278                 status = bt_get_be16(pdata);
4279                 size = ntohs(rsphdr->plen);
4280
4281                 goto end;
4282         default:
4283                 t->err = EPROTO;
4284                 SDPERR("Illegal PDU ID: 0x%x", rsphdr->pdu_id);
4285                 goto end;
4286         }
4287
4288         /* Out of bound check before using rsp_count as offset for
4289          * continuation state, which has at least a one byte size
4290          * field.
4291          */
4292         if ((n - (int) sizeof(sdp_pdu_hdr_t)) < plen + 1) {
4293                 t->err = EPROTO;
4294                 SDPERR("Protocol error: invalid PDU size");
4295                 status = SDP_INVALID_PDU_SIZE;
4296                 goto end;
4297         }
4298
4299         pcstate = (sdp_cstate_t *) (pdata + rsp_count);
4300
4301         SDPDBG("Cstate length : %d", pcstate->length);
4302
4303         /*
4304          * Check out of bound. Continuation state must have at least
4305          * 1 byte: ZERO to indicate that it is not a partial response.
4306          */
4307         if ((n - (int) sizeof(sdp_pdu_hdr_t))  != (plen + pcstate->length + 1)) {
4308                 t->err = EPROTO;
4309                 SDPERR("Protocol error: wrong PDU size.");
4310                 status = 0xffff;
4311                 goto end;
4312         }
4313
4314         /*
4315          * This is a split response, need to concatenate intermediate
4316          * responses and the last one which will have cstate length == 0
4317          */
4318         t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count);
4319         targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size;
4320         t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count;
4321         memcpy(targetPtr, pdata, rsp_count);
4322         t->rsp_concat_buf.data_size += rsp_count;
4323
4324         if (pcstate->length > 0) {
4325                 int reqsize, cstate_len;
4326
4327                 reqhdr->tid = htons(sdp_gen_tid(session));
4328
4329                 /* add continuation state */
4330                 cstate_len = copy_cstate(t->reqbuf + t->reqsize,
4331                                 SDP_REQ_BUFFER_SIZE - t->reqsize, pcstate);
4332
4333                 reqsize = t->reqsize + cstate_len;
4334
4335                 /* set the request header's param length */
4336                 reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
4337
4338                 if (sdp_send_req(session, t->reqbuf, reqsize) < 0) {
4339                         SDPERR("Error sending data:%m(%d)", errno);
4340                         status = 0xffff;
4341                         t->err = errno;
4342                         goto end;
4343                 }
4344                 err = 0;
4345         }
4346
4347 end:
4348         if (err) {
4349                 if (t->rsp_concat_buf.data_size != 0) {
4350                         pdata = t->rsp_concat_buf.data;
4351                         size = t->rsp_concat_buf.data_size;
4352                 }
4353                 if (t->cb)
4354                         t->cb(pdu_id, status, pdata, size, t->udata);
4355         }
4356
4357         free(rspbuf);
4358
4359         return err;
4360 }
4361
4362 /*
4363  * This is a service search request combined with the service
4364  * attribute request. First a service class match is done and
4365  * for matching service, requested attributes are extracted
4366  *
4367  * INPUT :
4368  *
4369  *   sdp_list_t *search
4370  *     Singly linked list containing elements of the search
4371  *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
4372  *     of the service to be searched
4373  *
4374  *   AttributeSpecification attrSpec
4375  *     Attribute identifiers are 16 bit unsigned integers specified
4376  *     in one of 2 ways described below :
4377  *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
4378  *        They are the actual attribute identifiers in ascending order
4379  *
4380  *     SDP_ATTR_REQ_RANGE - 32bit identifier range
4381  *        The high-order 16bits is the start of range
4382  *        the low-order 16bits are the end of range
4383  *        0x0000 to 0xFFFF gets all attributes
4384  *
4385  *   sdp_list_t *attrids
4386  *     Singly linked list containing attribute identifiers desired.
4387  *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
4388  *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
4389  *
4390  * OUTPUT :
4391  *   int return value
4392  *     0:
4393  *       The request completed successfully. This does not
4394  *       mean the requested services were found
4395  *     -1:
4396  *       On any error and sets errno
4397  *
4398  *   sdp_list_t **rsp
4399  *     This variable is set on a successful return to point to
4400  *     service(s) found. Each element of this list is of type
4401  *     sdp_record_t* (of the services which matched the search list)
4402  */
4403 int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrids, sdp_list_t **rsp)
4404 {
4405         int status = 0;
4406         uint32_t reqsize = 0, _reqsize;
4407         uint32_t rspsize = 0;
4408         int seqlen = 0, attr_list_len = 0;
4409         int rsp_count = 0, cstate_len = 0;
4410         unsigned int pdata_len;
4411         uint8_t *pdata, *_pdata;
4412         uint8_t *reqbuf, *rspbuf;
4413         sdp_pdu_hdr_t *reqhdr, *rsphdr;
4414         uint8_t dataType;
4415         sdp_list_t *rec_list = NULL;
4416         sdp_buf_t rsp_concat_buf;
4417         sdp_cstate_t *cstate = NULL;
4418
4419         if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
4420                 errno = EINVAL;
4421                 return -1;
4422         }
4423
4424         memset(&rsp_concat_buf, 0, sizeof(sdp_buf_t));
4425
4426         reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
4427         rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
4428         if (!reqbuf || !rspbuf) {
4429                 errno = ENOMEM;
4430                 status = -1;
4431                 goto end;
4432         }
4433
4434         reqhdr = (sdp_pdu_hdr_t *) reqbuf;
4435         reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
4436
4437         /* generate PDU */
4438         pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
4439         reqsize = sizeof(sdp_pdu_hdr_t);
4440
4441         /* add service class IDs for search */
4442         seqlen = gen_searchseq_pdu(pdata, search);
4443         if (seqlen < 0) {
4444                 errno = EINVAL;
4445                 status = -1;
4446                 goto end;
4447         }
4448
4449         SDPDBG("Data seq added : %d", seqlen);
4450
4451         /* now set the length and increment the pointer */
4452         reqsize += seqlen;
4453         pdata += seqlen;
4454
4455         bt_put_be16(SDP_MAX_ATTR_LEN, pdata);
4456         reqsize += sizeof(uint16_t);
4457         pdata += sizeof(uint16_t);
4458
4459         SDPDBG("Max attr byte count : %d", SDP_MAX_ATTR_LEN);
4460
4461         /* get attr seq PDU form */
4462         seqlen = gen_attridseq_pdu(pdata, attrids,
4463                 reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
4464         if (seqlen == -1) {
4465                 errno = EINVAL;
4466                 status = -1;
4467                 goto end;
4468         }
4469         pdata += seqlen;
4470         SDPDBG("Attr list length : %d", seqlen);
4471         reqsize += seqlen;
4472         *rsp = 0;
4473
4474         /* save before Continuation State */
4475         _pdata = pdata;
4476         _reqsize = reqsize;
4477
4478         do {
4479                 reqhdr->tid = htons(sdp_gen_tid(session));
4480
4481                 /* add continuation state (can be null) */
4482                 reqsize = _reqsize + copy_cstate(_pdata,
4483                                         SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
4484
4485                 /* set the request header's param length */
4486                 reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
4487                 rsphdr = (sdp_pdu_hdr_t *) rspbuf;
4488                 status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
4489                 if (rspsize < sizeof(sdp_pdu_hdr_t)) {
4490                         SDPERR("Unexpected end of packet");
4491                         status = -1;
4492                         goto end;
4493                 }
4494
4495                 if (status < 0) {
4496                         SDPDBG("Status : 0x%x", rsphdr->pdu_id);
4497                         goto end;
4498                 }
4499
4500                 if (rsphdr->pdu_id == SDP_ERROR_RSP) {
4501                         status = -1;
4502                         goto end;
4503                 }
4504
4505                 pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
4506                 pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
4507
4508                 if (pdata_len < sizeof(uint16_t)) {
4509                         SDPERR("Unexpected end of packet");
4510                         status = -1;
4511                         goto end;
4512                 }
4513
4514                 rsp_count = bt_get_be16(pdata);
4515                 attr_list_len += rsp_count;
4516                 pdata += sizeof(uint16_t); /* pdata points to attribute list */
4517                 pdata_len -= sizeof(uint16_t);
4518
4519                 if (pdata_len < rsp_count + sizeof(uint8_t)) {
4520                         SDPERR("Unexpected end of packet: continuation state data missing");
4521                         status = -1;
4522                         goto end;
4523                 }
4524
4525                 cstate_len = *(uint8_t *) (pdata + rsp_count);
4526
4527                 SDPDBG("Attrlist byte count : %d", attr_list_len);
4528                 SDPDBG("Response byte count : %d", rsp_count);
4529                 SDPDBG("Cstate length : %d", cstate_len);
4530                 /*
4531                  * This is a split response, need to concatenate intermediate
4532                  * responses and the last one which will have cstate_len == 0
4533                  */
4534                 if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
4535                         uint8_t *targetPtr = NULL;
4536
4537                         cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
4538
4539                         /* build concatenated response buffer */
4540                         rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
4541                         targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
4542                         rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
4543                         memcpy(targetPtr, pdata, rsp_count);
4544                         rsp_concat_buf.data_size += rsp_count;
4545                 }
4546         } while (cstate);
4547
4548         if (attr_list_len > 0) {
4549                 int scanned = 0;
4550
4551                 if (rsp_concat_buf.data_size != 0) {
4552                         pdata = rsp_concat_buf.data;
4553                         pdata_len = rsp_concat_buf.data_size;
4554                 }
4555
4556                 /*
4557                  * Response is a sequence of sequence(s) for one or
4558                  * more data element sequence(s) representing services
4559                  * for which attributes are returned
4560                  */
4561                 scanned = sdp_extract_seqtype(pdata, pdata_len, &dataType, &seqlen);
4562
4563                 SDPDBG("Bytes scanned : %d", scanned);
4564                 SDPDBG("Seq length : %d", seqlen);
4565
4566                 if (scanned && seqlen) {
4567                         pdata += scanned;
4568                         pdata_len -= scanned;
4569                         do {
4570                                 int recsize = 0;
4571                                 sdp_record_t *rec = sdp_extract_pdu(pdata, pdata_len, &recsize);
4572                                 if (rec == NULL) {
4573                                         SDPERR("SVC REC is null");
4574                                         status = -1;
4575                                         goto end;
4576                                 }
4577                                 if (!recsize) {
4578                                         sdp_record_free(rec);
4579                                         break;
4580                                 }
4581                                 scanned += recsize;
4582                                 pdata += recsize;
4583                                 pdata_len -= recsize;
4584
4585                                 SDPDBG("Loc seq length : %d", recsize);
4586                                 SDPDBG("Svc Rec Handle : 0x%x", rec->handle);
4587                                 SDPDBG("Bytes scanned : %d", scanned);
4588                                 SDPDBG("Attrlist byte count : %d", attr_list_len);
4589                                 rec_list = sdp_list_append(rec_list, rec);
4590                         } while (scanned < attr_list_len && pdata_len > 0);
4591
4592                         SDPDBG("Successful scan of service attr lists");
4593                         *rsp = rec_list;
4594                 }
4595         }
4596 end:
4597         free(rsp_concat_buf.data);
4598         free(reqbuf);
4599         free(rspbuf);
4600         return status;
4601 }
4602
4603 /*
4604  * Find devices in the piconet.
4605  */
4606 int sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *found)
4607 {
4608         int n = hci_inquiry(-1, 10, num_dev, NULL, &ii, 0);
4609         if (n < 0) {
4610                 SDPERR("Inquiry failed:%m");
4611                 return -1;
4612         }
4613         *found = n;
4614         return 0;
4615 }
4616
4617 int sdp_close(sdp_session_t *session)
4618 {
4619         struct sdp_transaction *t;
4620         int ret;
4621
4622         if (!session)
4623                 return -1;
4624
4625         ret = close(session->sock);
4626
4627         t = session->priv;
4628
4629         if (t) {
4630                 free(t->reqbuf);
4631
4632                 free(t->rsp_concat_buf.data);
4633
4634                 free(t);
4635         }
4636         free(session);
4637         return ret;
4638 }
4639
4640 static inline int sdp_is_local(const bdaddr_t *device)
4641 {
4642         return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0;
4643 }
4644
4645 static int sdp_connect_local(sdp_session_t *session)
4646 {
4647         struct sockaddr_un sa;
4648
4649         session->sock = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
4650         if (session->sock < 0)
4651                 return -1;
4652         session->local = 1;
4653
4654         sa.sun_family = AF_UNIX;
4655         strcpy(sa.sun_path, SDP_UNIX_PATH);
4656
4657         return connect(session->sock, (struct sockaddr *) &sa, sizeof(sa));
4658 }
4659
4660 static int set_l2cap_mtu(int sk, uint16_t mtu)
4661 {
4662         struct l2cap_options l2o;
4663         socklen_t len;
4664
4665         memset(&l2o, 0, sizeof(l2o));
4666         len = sizeof(l2o);
4667
4668         if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &len) < 0)
4669                 return -1;
4670
4671         l2o.imtu = mtu;
4672         l2o.omtu = mtu;
4673
4674         if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0)
4675                 return -1;
4676
4677         return 0;
4678 }
4679
4680 static int sdp_connect_l2cap(const bdaddr_t *src,
4681                 const bdaddr_t *dst, sdp_session_t *session)
4682 {
4683         uint32_t flags = session->flags;
4684         struct sockaddr_l2 sa;
4685         int sk;
4686         int sockflags = SOCK_SEQPACKET | SOCK_CLOEXEC;
4687
4688         if (flags & SDP_NON_BLOCKING)
4689                 sockflags |= SOCK_NONBLOCK;
4690
4691         session->sock = socket(PF_BLUETOOTH, sockflags, BTPROTO_L2CAP);
4692         if (session->sock < 0)
4693                 return -1;
4694         session->local = 0;
4695
4696         sk = session->sock;
4697
4698         memset(&sa, 0, sizeof(sa));
4699
4700         sa.l2_family = AF_BLUETOOTH;
4701         sa.l2_psm = 0;
4702
4703         if (bacmp(src, BDADDR_ANY)) {
4704                 sa.l2_bdaddr = *src;
4705                 if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0)
4706                         return -1;
4707         }
4708
4709         if (flags & SDP_WAIT_ON_CLOSE) {
4710                 struct linger l = { .l_onoff = 1, .l_linger = 1 };
4711                 setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
4712         }
4713
4714         if ((flags & SDP_LARGE_MTU) &&
4715                                 set_l2cap_mtu(sk, SDP_LARGE_L2CAP_MTU) < 0)
4716                 return -1;
4717
4718         sa.l2_psm = htobs(SDP_PSM);
4719         sa.l2_bdaddr = *dst;
4720
4721         do {
4722                 int ret = connect(sk, (struct sockaddr *) &sa, sizeof(sa));
4723                 if (!ret)
4724                         return 0;
4725                 if (ret < 0 && (flags & SDP_NON_BLOCKING) &&
4726                                 (errno == EAGAIN || errno == EINPROGRESS))
4727                         return 0;
4728         } while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY));
4729
4730         return -1;
4731 }
4732
4733 sdp_session_t *sdp_connect(const bdaddr_t *src,
4734                 const bdaddr_t *dst, uint32_t flags)
4735 {
4736         sdp_session_t *session;
4737         int err;
4738
4739         if ((flags & SDP_RETRY_IF_BUSY) && (flags & SDP_NON_BLOCKING)) {
4740                 errno = EINVAL;
4741                 return NULL;
4742         }
4743
4744         session = sdp_create(-1, flags);
4745         if (!session)
4746                 return NULL;
4747
4748         if (sdp_is_local(dst)) {
4749                 if (sdp_connect_local(session) < 0)
4750                         goto fail;
4751         } else {
4752                 if (sdp_connect_l2cap(src, dst, session) < 0)
4753                         goto fail;
4754         }
4755
4756         return session;
4757
4758 fail:
4759         err = errno;
4760         if (session->sock >= 0)
4761                 close(session->sock);
4762         free(session->priv);
4763         free(session);
4764         errno = err;
4765
4766         return NULL;
4767 }
4768
4769 int sdp_get_socket(const sdp_session_t *session)
4770 {
4771         return session->sock;
4772 }
4773
4774 uint16_t sdp_gen_tid(sdp_session_t *session)
4775 {
4776         return session->tid++;
4777 }
4778
4779 /*
4780  * Set the supported features
4781  */
4782 int sdp_set_supp_feat(sdp_record_t *rec, const sdp_list_t *sf)
4783 {
4784         const sdp_list_t *p, *r;
4785         sdp_data_t *feat, *seq_feat;
4786         int seqlen, i;
4787         void **seqDTDs, **seqVals;
4788
4789         seqlen = sdp_list_len(sf);
4790         seqDTDs = malloc(seqlen * sizeof(void *));
4791         if (!seqDTDs)
4792                 return -1;
4793         seqVals = malloc(seqlen * sizeof(void *));
4794         if (!seqVals) {
4795                 free(seqDTDs);
4796                 return -1;
4797         }
4798
4799         for (p = sf, i = 0; p; p = p->next, i++) {
4800                 int plen, j;
4801                 void **dtds, **vals;
4802                 int *lengths;
4803
4804                 plen = sdp_list_len(p->data);
4805                 dtds = malloc(plen * sizeof(void *));
4806                 if (!dtds)
4807                         goto fail;
4808                 vals = malloc(plen * sizeof(void *));
4809                 if (!vals) {
4810                         free(dtds);
4811                         goto fail;
4812                 }
4813                 lengths = malloc(plen * sizeof(int));
4814                 if (!lengths) {
4815                         free(dtds);
4816                         free(vals);
4817                         goto fail;
4818                 }
4819                 for (r = p->data, j = 0; r; r = r->next, j++) {
4820                         sdp_data_t *data = (sdp_data_t *) r->data;
4821                         dtds[j] = &data->dtd;
4822                         switch (data->dtd) {
4823                         case SDP_URL_STR8:
4824                         case SDP_URL_STR16:
4825                         case SDP_TEXT_STR8:
4826                         case SDP_TEXT_STR16:
4827                                 vals[j] = data->val.str;
4828                                 lengths[j] = data->unitSize - sizeof(uint8_t);
4829                                 break;
4830                         case SDP_ALT8:
4831                         case SDP_ALT16:
4832                         case SDP_ALT32:
4833                         case SDP_SEQ8:
4834                         case SDP_SEQ16:
4835                         case SDP_SEQ32:
4836                                 vals[j] = data->val.dataseq;
4837                                 lengths[j] = 0;
4838                                 break;
4839                         default:
4840                                 vals[j] = &data->val;
4841                                 lengths[j] = 0;
4842                                 break;
4843                         }
4844                 }
4845                 feat = sdp_seq_alloc_with_length(dtds, vals, lengths, plen);
4846                 free(dtds);
4847                 free(vals);
4848                 free(lengths);
4849                 if (!feat)
4850                         goto fail;
4851                 seqDTDs[i] = &feat->dtd;
4852                 seqVals[i] = feat;
4853         }
4854         seq_feat = sdp_seq_alloc(seqDTDs, seqVals, seqlen);
4855         if (!seq_feat)
4856                 goto fail;
4857         sdp_attr_replace(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST, seq_feat);
4858
4859         free(seqVals);
4860         free(seqDTDs);
4861         return 0;
4862
4863 fail:
4864         free(seqVals);
4865         free(seqDTDs);
4866         return -1;
4867 }
4868
4869 /*
4870  * Get the supported features
4871  * If an error occurred -1 is returned and errno is set
4872  */
4873 int sdp_get_supp_feat(const sdp_record_t *rec, sdp_list_t **seqp)
4874 {
4875         sdp_data_t *sdpdata, *d;
4876         sdp_list_t *tseq;
4877         tseq = NULL;
4878
4879         sdpdata = sdp_data_get(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST);
4880
4881         if (!sdpdata || !SDP_IS_SEQ(sdpdata->dtd))
4882                 return sdp_get_uuidseq_attr(rec,
4883                                         SDP_ATTR_SUPPORTED_FEATURES_LIST, seqp);
4884
4885         for (d = sdpdata->val.dataseq; d; d = d->next) {
4886                 sdp_data_t *dd;
4887                 sdp_list_t *subseq;
4888
4889                 if (!SDP_IS_SEQ(d->dtd))
4890                         goto fail;
4891
4892                 subseq = NULL;
4893
4894                 for (dd = d->val.dataseq; dd; dd = dd->next) {
4895                         sdp_data_t *data;
4896                         void *val;
4897                         int length;
4898
4899                         switch (dd->dtd) {
4900                         case SDP_URL_STR8:
4901                         case SDP_URL_STR16:
4902                         case SDP_TEXT_STR8:
4903                         case SDP_TEXT_STR16:
4904                                 val = dd->val.str;
4905                                 length = dd->unitSize - sizeof(uint8_t);
4906                                 break;
4907                         case SDP_UINT8:
4908                         case SDP_UINT16:
4909                                 val = &dd->val;
4910                                 length = 0;
4911                                 break;
4912                         default:
4913                                 sdp_list_free(subseq, free);
4914                                 goto fail;
4915                         }
4916
4917                         data = sdp_data_alloc_with_length(dd->dtd, val, length);
4918                         if (data)
4919                                 subseq = sdp_list_append(subseq, data);
4920                 }
4921                 tseq = sdp_list_append(tseq, subseq);
4922         }
4923         *seqp = tseq;
4924         return 0;
4925
4926 fail:
4927         while (tseq) {
4928                 sdp_list_t * next;
4929
4930                 next = tseq->next;
4931                 sdp_list_free(tseq, free);
4932                 tseq = next;
4933         }
4934         errno = EINVAL;
4935         return -1;
4936 }
4937
4938 void sdp_add_lang_attr(sdp_record_t *rec)
4939 {
4940         sdp_lang_attr_t base_lang;
4941         sdp_list_t *langs;
4942
4943         base_lang.code_ISO639 = (0x65 << 8) | 0x6e;
4944         base_lang.encoding = 106;
4945         base_lang.base_offset = SDP_PRIMARY_LANG_BASE;
4946
4947         langs = sdp_list_append(0, &base_lang);
4948         sdp_set_lang_attr(rec, langs);
4949         sdp_list_free(langs, NULL);
4950 }