Linux bluetooth development
 help / color / mirror / Atom feed
* pull request: bluetooth 2013-09-23
From: Gustavo Padovan @ 2013-09-23 21:00 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, linux-bluetooth, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2208 bytes --]

Hi John,

First Bluetooth fixes to 3.12, it includes:

* 3 patches to add device id for 3 new hardwares.

* 2 patches from Johan to fix the rfkill behaviour during setup stage

* a small clean up in the rfcomm TTY code that fixes a potential racy
condition (by Gianluca Anzolin)

* 2 fixes to proper set encryption key size and security level in the
peripheral role of Bluetooth LE devices. (by Andre Guedes)

* a fix for dealing devices where pairing is not necessary, we were keeping
the Bluetooth ACL connection alive for too much time. (by Syam Sidhardhan)

Please pull or let me know of any problems! Thanks!


	Gustavo

---
The following changes since commit f4e1a4d3ecbb9e42bdf8e7869ee8a4ebfa27fb20:

  rt2800: change initialization sequence to fix system freeze (2013-09-09 14:44:34 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth master

for you to fetch changes up to 5bcecf325378218a8e248bb6bcae96ec7362f8ef:

  Bluetooth: btusb: Add support for Belkin F8065bf (2013-09-23 17:44:25 -0300)

----------------------------------------------------------------
Andre Guedes (2):
      Bluetooth: Fix security level for peripheral role
      Bluetooth: Fix encryption key size for peripheral role

Gianluca Anzolin (1):
      Bluetooth: don't release the port in rfcomm_dev_state_change()

Johan Hedberg (2):
      Bluetooth: Introduce a new HCI_RFKILLED flag
      Bluetooth: Fix rfkill functionality during the HCI setup stage

Ken O'Brien (1):
      Bluetooth: btusb: Add support for Belkin F8065bf

Peng Chen (1):
      Bluetooth: Add a new PID/VID 0cf3/e005 for AR3012.

Raphael Kubo da Costa (1):
      Bluetooth: Add support for BCM20702A0 [0b05, 17cb]

Syam Sidhardhan (1):
      Bluetooth: Fix ACL alive for long in case of non pariable devices

 drivers/bluetooth/ath3k.c   |  2 ++
 drivers/bluetooth/btusb.c   |  5 +++++
 include/net/bluetooth/hci.h |  1 +
 net/bluetooth/hci_core.c    | 26 ++++++++++++++++++++------
 net/bluetooth/hci_event.c   |  6 +++++-
 net/bluetooth/l2cap_core.c  |  7 +++++++
 net/bluetooth/rfcomm/tty.c  | 35 ++---------------------------------
 7 files changed, 42 insertions(+), 40 deletions(-)


[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH] drivers: bluetooth: btusb: Added support for Belkin F8065bf usb bluetooth device
From: Gustavo Padovan @ 2013-09-23 20:45 UTC (permalink / raw)
  To: Ken O'Brien; +Cc: marcel, johan.hedberg, linux-bluetooth, linux-kernel
In-Reply-To: <1379787283-5579-1-git-send-email-kernel@kenobrien.org>

Hi Ken,

2013-09-21 Ken O'Brien <kernel@kenobrien.org>:

> Adding generic rule on encountering Belkin bluetooth usb device F8065bf.
> 
> Relevant section from /sys/kernel/debug/usb/devices:
> 
> T:  Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12   MxCh= 0
> D:  Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
> P:  Vendor=050d ProdID=065a Rev= 1.12
> S:  Manufacturer=Broadcom Corp
> S:  Product=BCM20702A0
> S:  SerialNumber=0002723E2D29
> C:* #Ifs= 4 Cfg#= 1 Atr=a0 MxPwr=100mA
> I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
> E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
> E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
> E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
> I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
> I:  If#= 1 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
> I:  If#= 1 Alt= 2 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
> I:  If#= 1 Alt= 3 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
> I:  If#= 1 Alt= 4 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
> I:  If#= 1 Alt= 5 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
> I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
> E:  Ad=84(I) Atr=02(Bulk) MxPS=  32 Ivl=0ms
> E:  Ad=04(O) Atr=02(Bulk) MxPS=  32 Ivl=0ms
> I:* If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)
> 
> Signed-off-by: Ken O'Brien <kernel@kenobrien.org>
> ---
>  drivers/bluetooth/btusb.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)

Patch has been applied to bluetooth.git. Thanks.

	Gustavo

^ permalink raw reply

* RE: [PATCH v5 2/2] Bluetooth: btmrvl: add calibration data download support
From: Bing Zhao @ 2013-09-23 19:35 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: linux-bluetooth@vger.kernel.org, Gustavo Padovan, Johan Hedberg,
	linux-wireless@vger.kernel.org, Mike Frysinger, Hyuckjoo Lee,
	Amitkumar Karwar
In-Reply-To: <05172D80-CE30-4B7D-A64E-11B8E320EF7F@holtmann.org>

Hi Marcel,

> > +	cmd =3D (struct btmrvl_cmd *)skb->data;
> > +	cmd->ocf_ogf =3D
> > +		cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_LOAD_CONFIG_DATA));
> > +	cmd->length =3D BT_CMD_DATA_SIZE;
> > +	cmd->data[0] =3D 0x00;
> > +	cmd->data[1] =3D 0x00;
> > +	cmd->data[2] =3D 0x00;
> > +	cmd->data[3] =3D BT_CMD_DATA_SIZE - 4;
>=20
> why not use __hci_cmd_sync() here. It is designed to be used from ->setup=
() where it is guaranteed
> that the HCI request lock is held. And it is guaranteed that ->setup() is=
 executed in a workqueue.

The reason of not using __hci_cmd_sync() is that we are sending vendor spec=
ific command here (MRVL_VENDOR_PKT). The __hci_cmd_sync seems handle HCI_CO=
MMAND_PKT only.
Please let us know if you have any suggestion to solve this problem.

Thanks,
Bing

^ permalink raw reply

* Re: [PATCH 1/2] android: Add skeleton of BlueZ Android daemon
From: Lukasz Rymanowski @ 2013-09-23 19:28 UTC (permalink / raw)
  To: Frederic Danis; +Cc: Marcel Holtmann, linux-bluetooth
In-Reply-To: <52400F2B.9010501@linux.intel.com>

Hi Marcel,

On Mon, Sep 23, 2013 at 11:51 AM, Frederic Danis
<frederic.danis@linux.intel.com> wrote:
> Hello Marcel,
>
> On 21/09/2013 19:14, Marcel Holtmann wrote:
>>
>> Hi Fred,
>>
>>> Define local mapping to glib path, otherwise this has to be inside
>>> central
>>> place in the build repository.
>>>
>>> Retrieve Bluetooth version from configure.ac.
>>> ---
>>> .gitignore         |    2 +
>>> Android.mk         |    9 ++++
>>> Makefile.am        |    1 +
>>> Makefile.android   |    7 ++++
>>> android/Android.mk |   24 +++++++++++
>>> android/main.c     |  119
>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> configure.ac       |    5 +++
>>> 7 files changed, 167 insertions(+)
>>> create mode 100644 Android.mk
>>> create mode 100644 Makefile.android
>>> create mode 100644 android/Android.mk
>>> create mode 100644 android/main.c
>>
>>
>> lets split this out a little bit. Code additions should not be intermixed
>> with additions to the build system and especially configure options.
>>
>> I rather not have a top-level Android.mk. It should be enough to provide
>> an android/Android.mk.

 BTW, do you expect to have only one Android.mk for the whole project or
this is OK for you to have smaller Android.mk in different subfolders like
/src/shared etc. Both ways are valid.

Br
Lukasz

^ permalink raw reply

* Re: [PATCH 1/2] android: Add skeleton of BlueZ Android daemon
From: Lukasz Rymanowski @ 2013-09-23 19:26 UTC (permalink / raw)
  To: Frederic Danis; +Cc: Marcel Holtmann, linux-bluetooth
In-Reply-To: <52400F2B.9010501@linux.intel.com>

[-- Attachment #1: Type: text/plain, Size: 1320 bytes --]

Hi Marcel


On Mon, Sep 23, 2013 at 11:51 AM, Frederic Danis <
frederic.danis@linux.intel.com> wrote:

> Hello Marcel,
>
> On 21/09/2013 19:14, Marcel Holtmann wrote:
>
>> Hi Fred,
>>
>>  Define local mapping to glib path, otherwise this has to be inside
>>> central
>>> place in the build repository.
>>>
>>> Retrieve Bluetooth version from configure.ac.
>>> ---
>>> .gitignore         |    2 +
>>> Android.mk         |    9 ++++
>>> Makefile.am        |    1 +
>>> Makefile.android   |    7 ++++
>>> android/Android.mk |   24 +++++++++++
>>> android/main.c     |  119 ++++++++++++++++++++++++++++++**
>>> ++++++++++++++++++++++
>>> configure.ac       |    5 +++
>>> 7 files changed, 167 insertions(+)
>>> create mode 100644 Android.mk
>>> create mode 100644 Makefile.android
>>> create mode 100644 android/Android.mk
>>> create mode 100644 android/main.c
>>>
>>
>> lets split this out a little bit. Code additions should not be intermixed
>> with additions to the build system and especially configure options.
>>
>> I rather not have a top-level Android.mk. It should be enough to provide
>> an android/Android.mk.
>>
>> BTW, do you expect to have only one Android.mk for the whole project or
this is OK for you to have smaller Android.mk in different subfolders like
/src/shared etc. Both ways are valid.

BR
Lukasz

[-- Attachment #2: Type: text/html, Size: 2206 bytes --]

^ permalink raw reply

* RE: [PATCH v5 1/2] Bluetooth: btmrvl: add setup handler
From: Bing Zhao @ 2013-09-23 19:18 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: linux-bluetooth@vger.kernel.org, Gustavo Padovan, Johan Hedberg,
	linux-wireless@vger.kernel.org, Mike Frysinger, Hyuckjoo Lee,
	Amitkumar Karwar
In-Reply-To: <18678858-E711-43E5-AFE6-E637D1CECFFB@holtmann.org>

Hi Marcel,

> > -	btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
> > +	hdev->setup =3D btmrvl_setup;
>=20
> just to make sure you guys understand how ->setup() works. It is only cal=
led once. Bringing the
> adapter down and up again does not call ->setup() a second time. So do yo=
u guys need this setup_done
> variable and if so, then you need to be a bit more verbose and help me un=
derstand why.

It's observed that sometimes the setup handler is called twice when Bluetoo=
th daemon is running in background. We will rebase to latest commit on blue=
tooth-next tree and test again. If the issue is gone with the latest code i=
n -next tree we will remove the setup_done flag.

Thanks,
Bing

^ permalink raw reply

* [PATCH 08/12] bluetooth: Remove extern from function prototypes
From: Joe Perches @ 2013-09-23 18:37 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, linux-kernel, Marcel Holtmann, Gustavo Padovan,
	Johan Hedberg, linux-bluetooth
In-Reply-To: <445209f8885ccd8234fa787c30d63e63fc7917d7.1379961014.git.joe@perches.com>

There are a mix of function prototypes with and without extern
in the kernel sources.  Standardize on not using extern for
function prototypes.

Function prototypes don't need to be written with extern.
extern is assumed by the compiler.  Its use is as unnecessary as
using auto to declare automatic/local variables in a block.

Signed-off-by: Joe Perches <joe@perches.com>
---
 include/net/bluetooth/bluetooth.h | 16 ++++++++--------
 include/net/bluetooth/hci_core.h  | 23 +++++++++++------------
 include/net/bluetooth/rfcomm.h    |  4 ++--
 3 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 10d43d8..13d6c39 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -331,16 +331,16 @@ out:
 
 int bt_to_errno(__u16 code);
 
-extern int hci_sock_init(void);
-extern void hci_sock_cleanup(void);
+int hci_sock_init(void);
+void hci_sock_cleanup(void);
 
-extern int bt_sysfs_init(void);
-extern void bt_sysfs_cleanup(void);
+int bt_sysfs_init(void);
+void bt_sysfs_cleanup(void);
 
-extern int  bt_procfs_init(struct net *net, const char *name,
-			   struct bt_sock_list* sk_list,
-			   int (* seq_show)(struct seq_file *, void *));
-extern void bt_procfs_cleanup(struct net *net, const char *name);
+int bt_procfs_init(struct net *net, const char *name,
+		   struct bt_sock_list *sk_list,
+		   int (*seq_show)(struct seq_file *, void *));
+void bt_procfs_cleanup(struct net *net, const char *name);
 
 extern struct dentry *bt_debugfs;
 
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3ede820..5769061 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -367,18 +367,17 @@ extern rwlock_t hci_dev_list_lock;
 extern rwlock_t hci_cb_list_lock;
 
 /* ----- HCI interface to upper protocols ----- */
-extern int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
-extern void l2cap_connect_cfm(struct hci_conn *hcon, u8 status);
-extern int l2cap_disconn_ind(struct hci_conn *hcon);
-extern void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason);
-extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt);
-extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb,
-			      u16 flags);
-
-extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags);
-extern void sco_connect_cfm(struct hci_conn *hcon, __u8 status);
-extern void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason);
-extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
+int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
+void l2cap_connect_cfm(struct hci_conn *hcon, u8 status);
+int l2cap_disconn_ind(struct hci_conn *hcon);
+void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason);
+int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt);
+int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags);
+
+int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags);
+void sco_connect_cfm(struct hci_conn *hcon, __u8 status);
+void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason);
+int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
 
 /* ----- Inquiry cache ----- */
 #define INQUIRY_CACHE_AGE_MAX   (HZ*30)   /* 30 seconds */
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 7afd419..b7f43e7 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -256,8 +256,8 @@ static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
 		rfcomm_dlc_free(d);
 }
 
-extern void __rfcomm_dlc_throttle(struct rfcomm_dlc *d);
-extern void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d);
+void __rfcomm_dlc_throttle(struct rfcomm_dlc *d);
+void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d);
 
 static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d)
 {
-- 
1.8.1.2.459.gbcd45b4.dirty

^ permalink raw reply related

* Re: [PATCH 1/2] android: Add skeleton of BlueZ Android daemon
From: Frederic Danis @ 2013-09-23  9:51 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <226042C8-264A-469E-8D6A-F41141DC0552@holtmann.org>

Hello Marcel,

On 21/09/2013 19:14, Marcel Holtmann wrote:
> Hi Fred,
>
>> Define local mapping to glib path, otherwise this has to be inside central
>> place in the build repository.
>>
>> Retrieve Bluetooth version from configure.ac.
>> ---
>> .gitignore         |    2 +
>> Android.mk         |    9 ++++
>> Makefile.am        |    1 +
>> Makefile.android   |    7 ++++
>> android/Android.mk |   24 +++++++++++
>> android/main.c     |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>> configure.ac       |    5 +++
>> 7 files changed, 167 insertions(+)
>> create mode 100644 Android.mk
>> create mode 100644 Makefile.android
>> create mode 100644 android/Android.mk
>> create mode 100644 android/main.c
>
> lets split this out a little bit. Code additions should not be intermixed with additions to the build system and especially configure options.
>
> I rather not have a top-level Android.mk. It should be enough to provide an android/Android.mk.
>
>> diff --git a/.gitignore b/.gitignore
>> index 8a25a3e..331a18b 100644
>> --- a/.gitignore
>> +++ b/.gitignore
>> @@ -98,3 +98,5 @@ unit/test-gobex-packet
>> unit/test-gobex-transfer
>> unit/test-*.log
>> unit/test-*.trs
>> +
>> +android/bluezd
>
> If we keep using prefix btd_ for certain set of functions, then it might be better if the daemon is build as android/bluetoothd or android/btd.

OK, I will rename it android/bluetoothd

>
> <snip>
>
>> +
>> +#ifdef HAVE_CONFIG_H
>> +#include <config.h>
>> +#endif
>> +
>> +#include <signal.h>
>> +#include <stdint.h>
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +
>> +#include <glib.h>
>> +
>> +#include "hcid.h"
>
> I do not think we need to include hcid.h here. If we for some reason still do, then please try to cleanup that first.

OK, I will remove it

>
>> +
>> +#define SHUTDOWN_GRACE_SECONDS 10
>> +
>> +static GMainLoop *event_loop;
>> +
>> +void btd_exit(void)
>> +{
>> +	g_main_loop_quit(event_loop);
>> +}
>> +
>> +static gboolean quit_eventloop(gpointer user_data)
>> +{
>> +	btd_exit();
>> +	return FALSE;
>> +}
>> +
>> +static void signal_handler(int sig)
>> +{
>> +	static unsigned int __terminated = 0;
>
> Make this static volatile bool __terminated = false instead. Remember that you are actually using signals here and not signalfd.

OK, I will do this.

>
>> +
>> +	switch (sig) {
>> +	case SIGINT:
>> +	case SIGTERM:
>> +		if (__terminated == 0) {
>> +			g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS,
>> +							quit_eventloop, NULL);
>> +		}
>> +
>> +		__terminated = 1;
>> +		break;
>> +	}
>> +}
>> +
>> +static gboolean option_detach = TRUE;
>> +static gboolean option_version = FALSE;
>> +
>> +static GOptionEntry options[] = {
>> +	{ "nodetach", 'n', G_OPTION_FLAG_REVERSE,
>> +				G_OPTION_ARG_NONE, &option_detach,
>> +				"Run with logging in foreground", NULL },
>
> Do we need this option at all. I think we should always run in foreground and the system manager need to make sure we are spawned.

I think this is useful when debugging in conjonction with debug option 
and logging to console.

>
>> +	{ "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
>> +				"Show version information and exit", NULL },
>> +	{ NULL }
>> +};
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +	GOptionContext *context;
>> +	GError *err = NULL;
>> +	struct sigaction sa;
>> +
>> +	context = g_option_context_new(NULL);
>> +	g_option_context_add_main_entries(context, options, NULL);
>> +
>> +	if (g_option_context_parse(context, &argc, &argv, &err) == FALSE) {
>> +		if (err != NULL) {
>> +			g_printerr("%s\n", err->message);
>> +			g_error_free(err);
>> +		} else
>> +			g_printerr("An unknown error occurred\n");
>> +		exit(1);
>> +	}
>> +
>> +	g_option_context_free(context);
>> +
>> +	if (option_version == TRUE) {
>> +		printf("%s\n", VERSION);
>> +		exit(0);
>
> I prefer if we start using return EXIT_SUCCESS and in error case EXIT_FAILURE.

OK, I will do this.

>
>> +	}
>> +
>> +	event_loop = g_main_loop_new(NULL, FALSE);
>> +
>> +	memset(&sa, 0, sizeof(sa));
>> +	sa.sa_handler = signal_handler;
>> +	sigaction(SIGINT, &sa, NULL);
>> +	sigaction(SIGTERM, &sa, NULL);
>> +
>> +	g_main_loop_run(event_loop);
>> +
>> +	g_main_loop_unref(event_loop);
>> +
>> +	return 0;
>> +}
>> diff --git a/configure.ac b/configure.ac
>> index 41c2935..3b7a5d9 100644
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -242,4 +242,9 @@ AC_DEFINE_UNQUOTED(CONFIGDIR, "${configdir}",
>> 			[Directory for the configuration files])
>> AC_SUBST(CONFIGDIR, "${configdir}")
>>
>> +AC_ARG_ENABLE(android-daemon, AC_HELP_STRING([--enable-android-daemon],
>> +			[enable BlueZ Android daemon]),
>> +					[android_daemon=${enableval}])
>> +AM_CONDITIONAL(ANDROID_DAEMON, test "${android_daemon}" = "yes")
>> +
>
> This needs to be a separate patch. And it should just say --enable-android.
>
> In addition it needs to be added to bootstrap-configure and distcheck handling.

OK

Regards

Fred

-- 
Frederic Danis                            Open Source Technology Center
frederic.danis@intel.com                              Intel Corporation

^ permalink raw reply

* [PATCH v2 4/4] obexd: Clarify the folder property of PushMessage
From: Christian Fetzer @ 2013-09-23  9:24 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1379928269-14651-1-git-send-email-christian.fetzer@oss.bmw-carit.de>

From: Christian Fetzer <christian.fetzer@bmw-carit.de>

The folder property of PushMessages does not accept path information,
it allows only to request the messages to be added to a subfolder of the
current folder.
---
 doc/obex-api.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/doc/obex-api.txt b/doc/obex-api.txt
index 28343f6..eda7cb9 100644
--- a/doc/obex-api.txt
+++ b/doc/obex-api.txt
@@ -638,8 +638,9 @@ Methods		void SetFolder(string name)
 			Transfer a message (in bMessage format) to the
 			remote device.
 
-			The message is transferred either to the given folder,
-			or to the current folder if folder is omitted.
+			The message is transferred either to the given
+			subfolder of the current folder, or to the current
+			folder if folder is empty.
 
 			Possible args: Transparent, Retry, Charset
 
-- 
1.8.3.4


^ permalink raw reply related

* [PATCH v2 3/4] obexd: Clarify the folder property of ListMessages
From: Christian Fetzer @ 2013-09-23  9:24 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1379928269-14651-1-git-send-email-christian.fetzer@oss.bmw-carit.de>

From: Christian Fetzer <christian.fetzer@bmw-carit.de>

The folder property of ListMessages does not accept path information,
it allows only to request the messages of a subfolder of the current
folder.
---
 doc/obex-api.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/doc/obex-api.txt b/doc/obex-api.txt
index 0a8e632..28343f6 100644
--- a/doc/obex-api.txt
+++ b/doc/obex-api.txt
@@ -538,7 +538,8 @@ Methods		void SetFolder(string name)
 		array{object, dict} ListMessages(string folder, dict filter)
 
 			Returns an array containing the messages found in the
-			given folder.
+			given subfolder of the current folder, or in the
+			current folder if folder is empty.
 
 			Possible Filters: Offset, MaxCount, SubjectLength, Fields,
 			Type, PeriodStart, PeriodEnd, Status, Recipient, Sender,
-- 
1.8.3.4


^ permalink raw reply related

* [PATCH v2 2/4] obexd: Fix setting message folder for relative folder in ListMessages
From: Christian Fetzer @ 2013-09-23  9:24 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1379928269-14651-1-git-send-email-christian.fetzer@oss.bmw-carit.de>

From: Christian Fetzer <christian.fetzer@bmw-carit.de>

The method ListMessages allows to specify a relative subfolder.
This subfolder needs to be added to the current path when registering
a new message interface.
---
 obexd/client/map.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/obexd/client/map.c b/obexd/client/map.c
index 131b140..45b4ef1 100644
--- a/obexd/client/map.c
+++ b/obexd/client/map.c
@@ -103,6 +103,7 @@ struct map_data {
 struct pending_request {
 	struct map_data *map;
 	DBusMessage *msg;
+	char *folder;
 };
 
 #define MAP_MSG_FLAG_PRIORITY	0x01
@@ -154,6 +155,7 @@ static void pending_request_free(struct pending_request *p)
 {
 	dbus_message_unref(p->msg);
 
+	g_free(p->folder);
 	g_free(p);
 }
 
@@ -1098,8 +1100,7 @@ static void msg_element(GMarkupParseContext *ctxt, const char *element,
 
 	msg = g_hash_table_lookup(data->messages, values[i]);
 	if (msg == NULL) {
-		msg = map_msg_create(data, values[i],
-					obc_session_get_folder(data->session));
+		msg = map_msg_create(data, values[i], parser->request->folder);
 		if (msg == NULL)
 			return;
 	}
@@ -1195,6 +1196,17 @@ done:
 	pending_request_free(request);
 }
 
+static char *get_absolute_folder(const char *root, const char *subfolder)
+{
+	if (!subfolder || strlen(subfolder) == 0)
+		return g_strdup(root);
+	else
+		if (g_str_has_suffix(root, "/"))
+			return g_strconcat(root, subfolder, NULL);
+		else
+			return g_strconcat(root, "/", subfolder, NULL);
+}
+
 static DBusMessage *get_message_listing(struct map_data *map,
 							DBusMessage *message,
 							const char *folder,
@@ -1214,6 +1226,8 @@ static DBusMessage *get_message_listing(struct map_data *map,
 	obc_transfer_set_apparam(transfer, apparam);
 
 	request = pending_request_new(map, message);
+	request->folder = get_absolute_folder(obc_session_get_folder(
+							map->session), folder);
 
 	if (!obc_session_queue(map->session, transfer, message_listing_cb,
 							request, &err)) {
-- 
1.8.3.4


^ permalink raw reply related

* [PATCH v2 1/4] obexd: Add folder property to map_msg_create
From: Christian Fetzer @ 2013-09-23  9:24 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1379928269-14651-1-git-send-email-christian.fetzer@oss.bmw-carit.de>

From: Christian Fetzer <christian.fetzer@bmw-carit.de>

Message interfaces are not necessarily created for the current folder,
therefore the folder needs to be specified in a parameter.

For example, messages can be created for sub folders when using the folder
parameter in ListMessages.
---
 obexd/client/map.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/obexd/client/map.c b/obexd/client/map.c
index 9fe872d..131b140 100644
--- a/obexd/client/map.c
+++ b/obexd/client/map.c
@@ -809,7 +809,8 @@ static const GDBusPropertyTable map_msg_properties[] = {
 	{ }
 };
 
-static struct map_msg *map_msg_create(struct map_data *data, const char *handle)
+static struct map_msg *map_msg_create(struct map_data *data, const char *handle,
+							const char *folder)
 {
 	struct map_msg *msg;
 
@@ -818,7 +819,7 @@ static struct map_msg *map_msg_create(struct map_data *data, const char *handle)
 	msg->path = g_strdup_printf("%s/message%s",
 					obc_session_get_path(data->session),
 					handle);
-	msg->folder = g_strdup(obc_session_get_folder(data->session));
+	msg->folder = g_strdup(folder);
 
 	if (!g_dbus_register_interface(conn, msg->path, MAP_MSG_INTERFACE,
 						map_msg_methods, NULL,
@@ -1097,7 +1098,8 @@ static void msg_element(GMarkupParseContext *ctxt, const char *element,
 
 	msg = g_hash_table_lookup(data->messages, values[i]);
 	if (msg == NULL) {
-		msg = map_msg_create(data, values[i]);
+		msg = map_msg_create(data, values[i],
+					obc_session_get_folder(data->session));
 		if (msg == NULL)
 			return;
 	}
-- 
1.8.3.4


^ permalink raw reply related

* [PATCH v2 0/4] obexd: Fix setting message folder
From: Christian Fetzer @ 2013-09-23  9:24 UTC (permalink / raw)
  To: linux-bluetooth

From: Christian Fetzer <christian.fetzer@bmw-carit.de>

This fixes an issue that the folder property for messages was set incorrectly
when ListMessages got called with a subfolder parameter.

Calling ListMessages within /telecom/msg for the subfolder inbox would set the
folder property to /telecom/msg instead of /telecom/msg/inbox.

The patchset therefore changes map_msg_create to not set the folder property
to the current folder, but to a folder given as parameter. This change will be
needed as well for new message notifications (that can indicate new messages
for any folder).

In addition I've updated the documentation to clarify that the folder property
for ListMessages and PushMessage can be used only for a subfolder of the
current folder. It's not possible to specify an absolute or relative path.

--
v2: Store folder in MAP pending request

Christian Fetzer (4):
  obexd: Add folder property to map_msg_create
  obexd: Fix setting message folder for relative folder in ListMessages
  obexd: Clarify the folder property of ListMessages
  obexd: Clarify the folder property of PushMessage

 doc/obex-api.txt   |  8 +++++---
 obexd/client/map.c | 22 +++++++++++++++++++---
 2 files changed, 24 insertions(+), 6 deletions(-)

-- 
1.8.3.4


^ permalink raw reply

* Problems with too many connections
From: Markus Roppelt @ 2013-09-23  9:04 UTC (permalink / raw)
  To: linux-bluetooth

[-- Attachment #1: Type: text/plain, Size: 684 bytes --]

Hi,

I want to write an application which repeats the following procedure
for several (100+) bluetooth (low energy) devices:

1. connect
2. read register values
3. disconnect

Therefore I modified the source code from /attrib/interactive.c.  For
testing purposes I am only looping  over one device. See attached
source code.

The code works fine. It connects, reads the values and disconnects.
However, after 1020 repetitions, the following error occurs:
(process:10205): GLib-WARNING **: poll(2) failed due to: Invalid argument.

I think the problem has to do with some sockets / file descriptors not
being closed properly.

Can someone help me to get this fixed?

Thank you
 Markus

[-- Attachment #2: loop.c --]
[-- Type: text/x-csrc, Size: 22672 bytes --]

/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2011  Nokia Corporation
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/signalfd.h>
#include <glib.h>

#include <readline/readline.h>
#include <readline/history.h>

#include "lib/uuid.h"
#include <btio/btio.h>
#include "att.h"
#include "gattrib.h"
#include "gatt.h"
#include "gatttool.h"
#include "client/display.h"

static GIOChannel *iochannel = NULL;
static GAttrib *attrib = NULL;
static GMainLoop *event_loop;
static GString *prompt;

static char *opt_src = NULL;
static char *opt_dst = NULL;
static char *opt_dst_type = NULL;
static char *opt_sec_level = NULL;
static int opt_psm = 0;
static int opt_mtu = 0;
static int start;
static int end;

static gboolean requested_read;
static gboolean done_read;

static void cmd_help(int argcp, char **argvp);

static enum state {
	STATE_DISCONNECTED,
	STATE_CONNECTING,
	STATE_CONNECTED
} conn_state;

static int loop_counter;

#define error(fmt, arg...) \
	rl_printf(COLOR_RED "Error: " COLOR_OFF fmt, ## arg)

#define failed(fmt, arg...) \
	rl_printf(COLOR_RED "Command Failed: " COLOR_OFF fmt, ## arg)

static char *get_prompt(void)
{
	if (conn_state == STATE_CONNECTED)
		g_string_assign(prompt, COLOR_BLUE);
	else
		g_string_assign(prompt, "");

	if (opt_dst)
		g_string_append_printf(prompt, "[%17s]", opt_dst);
	else
		g_string_append_printf(prompt, "[%17s]", "");

	if (conn_state == STATE_CONNECTED)
		g_string_append(prompt, COLOR_OFF);

	if (opt_psm)
		g_string_append(prompt, "[BR]");
	else
		g_string_append(prompt, "[LE]");

	g_string_append(prompt, "> ");

	return prompt->str;
}


static void set_state(enum state st)
{
	conn_state = st;
	rl_set_prompt(get_prompt());
}

static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
{
	uint8_t *opdu;
	uint16_t handle, i, olen;
	size_t plen;
	GString *s;

	handle = att_get_u16(&pdu[1]);

	switch (pdu[0]) {
	case ATT_OP_HANDLE_NOTIFY:
		s = g_string_new(NULL);
		g_string_printf(s, "Notification handle = 0x%04x value: ",
									handle);
		break;
	case ATT_OP_HANDLE_IND:
		s = g_string_new(NULL);
		g_string_printf(s, "Indication   handle = 0x%04x value: ",
									handle);
		break;
	default:
		error("Invalid opcode\n");
		return;
	}

	for (i = 3; i < len; i++)
		g_string_append_printf(s, "%02x ", pdu[i]);

	rl_printf("%s\n", s->str);
	g_string_free(s, TRUE);

	if (pdu[0] == ATT_OP_HANDLE_NOTIFY)
		return;

	opdu = g_attrib_get_buffer(attrib, &plen);
	olen = enc_confirmation(opdu, plen);

	if (olen > 0)
		g_attrib_send(attrib, 0, opdu, olen, NULL, NULL, NULL);
}

static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
{
	if (err) {
		set_state(STATE_DISCONNECTED);
		error("%s\n", err->message);
		return;
	}

	attrib = g_attrib_new(iochannel);
	g_attrib_register(attrib, ATT_OP_HANDLE_NOTIFY, GATTRIB_ALL_HANDLES,
						events_handler, attrib, NULL);
	g_attrib_register(attrib, ATT_OP_HANDLE_IND, GATTRIB_ALL_HANDLES,
						events_handler, attrib, NULL);
	set_state(STATE_CONNECTED);
	rl_printf("Connection successful\n");
}

static void disconnect_io()
{
	if (conn_state == STATE_DISCONNECTED)
		return;

	g_attrib_unref(attrib);
	attrib = NULL;
	opt_mtu = 0;

	g_io_channel_shutdown(iochannel, FALSE, NULL);
	g_io_channel_unref(iochannel);
	iochannel = NULL;

	set_state(STATE_DISCONNECTED);
}

static void primary_all_cb(GSList *services, guint8 status, gpointer user_data)
{
	GSList *l;

	if (status) {
		error("Discover all primary services failed: %s\n",
						att_ecode2str(status));
		return;
	}

	if (services == NULL) {
		error("No primary service found\n");
		return;
	}

	for (l = services; l; l = l->next) {
		struct gatt_primary *prim = l->data;
		rl_printf("attr handle: 0x%04x, end grp handle: 0x%04x uuid: %s\n",
				prim->range.start, prim->range.end, prim->uuid);
	}
}

static void primary_by_uuid_cb(GSList *ranges, guint8 status,
							gpointer user_data)
{
	GSList *l;

	if (status) {
		error("Discover primary services by UUID failed: %s\n",
							att_ecode2str(status));
		return;
	}

	if (ranges == NULL) {
		error("No service UUID found\n");
		return;
	}

	for (l = ranges; l; l = l->next) {
		struct att_range *range = l->data;
		rl_printf("Starting handle: 0x%04x Ending handle: 0x%04x\n",
						range->start, range->end);
	}
}

static void included_cb(GSList *includes, guint8 status, gpointer user_data)
{
	GSList *l;

	if (status) {
		error("Find included services failed: %s\n",
							att_ecode2str(status));
		return;
	}

	if (includes == NULL) {
		rl_printf("No included services found for this range\n");
		return;
	}

	for (l = includes; l; l = l->next) {
		struct gatt_included *incl = l->data;
		rl_printf("handle: 0x%04x, start handle: 0x%04x, "
					"end handle: 0x%04x uuid: %s\n",
					incl->handle, incl->range.start,
					incl->range.end, incl->uuid);
	}
}

static void char_cb(GSList *characteristics, guint8 status, gpointer user_data)
{
	GSList *l;

	if (status) {
		error("Discover all characteristics failed: %s\n",
							att_ecode2str(status));
		return;
	}

	for (l = characteristics; l; l = l->next) {
		struct gatt_char *chars = l->data;

		rl_printf("handle: 0x%04x, char properties: 0x%02x, char value "
				"handle: 0x%04x, uuid: %s\n", chars->handle,
				chars->properties, chars->value_handle,
				chars->uuid);
	}
}

static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	struct att_data_list *list;
	guint8 format;
	uint16_t handle = 0xffff;
	int i;

	if (status != 0) {
		rl_printf("Discover descriptors finished: %s\n",
						att_ecode2str(status));
		return;
	}

	list = dec_find_info_resp(pdu, plen, &format);
	if (list == NULL)
		return;

	for (i = 0; i < list->num; i++) {
		char uuidstr[MAX_LEN_UUID_STR];
		uint8_t *value;
		bt_uuid_t uuid;

		value = list->data[i];
		handle = att_get_u16(value);

		if (format == 0x01)
			uuid = att_get_uuid16(&value[2]);
		else
			uuid = att_get_uuid128(&value[2]);

		bt_uuid_to_string(&uuid, uuidstr, MAX_LEN_UUID_STR);
		rl_printf("handle: 0x%04x, uuid: %s\n", handle, uuidstr);
	}

	att_data_list_free(list);

	if (handle != 0xffff && handle < end)
		gatt_discover_char_desc(attrib, handle + 1, end, char_desc_cb,
									NULL);
}

static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	uint8_t value[plen];
	ssize_t vlen;
	int i;
	GString *s;

	if (status != 0) {
		error("Characteristic value/descriptor read failed: %s\n",
							att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		error("Protocol error\n");
		return;
	}

	s = g_string_new("Characteristic value/descriptor: ");
	for (i = 0; i < vlen; i++)
		g_string_append_printf(s, "%02x ", value[i]);

	rl_printf("%s\n", s->str);
	g_string_free(s, TRUE);
}

static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu,
					guint16 plen, gpointer user_data)
{
	struct att_data_list *list;
	int i;
	GString *s;

	if (status != 0) {
		error("Read characteristics by UUID failed: %s\n",
							att_ecode2str(status));
		return;
	}

	list = dec_read_by_type_resp(pdu, plen);
	if (list == NULL)
		return;

	s = g_string_new(NULL);
	for (i = 0; i < list->num; i++) {
		uint8_t *value = list->data[i];
		int j;

		g_string_printf(s, "handle: 0x%04x \t value: ",
							att_get_u16(value));
		value += 2;
		for (j = 0; j < list->len - 2; j++, value++)
			g_string_append_printf(s, "%02x ", *value);

		rl_printf("%s\n", s->str);
	}

	att_data_list_free(list);
	g_string_free(s, TRUE);
	
	done_read = 1;
}

static void cmd_exit(int argcp, char **argvp)
{
	rl_callback_handler_remove();
	g_main_loop_quit(event_loop);
}

static gboolean channel_watcher(GIOChannel *chan, GIOCondition cond,
				gpointer user_data)
{
	disconnect_io();

	return FALSE;
}

static void cmd_connect(int argcp, char **argvp)
{
	GError *gerr = NULL;

	if (conn_state != STATE_DISCONNECTED)
		return;

	if (argcp > 1) {
		g_free(opt_dst);
		opt_dst = g_strdup(argvp[1]);

		g_free(opt_dst_type);
		if (argcp > 2)
			opt_dst_type = g_strdup(argvp[2]);
		else
			opt_dst_type = g_strdup("public");
	}

	if (opt_dst == NULL) {
		error("Remote Bluetooth address required\n");
		return;
	}

	rl_printf("Attempting to connect to %s\n", opt_dst);
	set_state(STATE_CONNECTING);
	iochannel = gatt_connect(opt_src, opt_dst, opt_dst_type, opt_sec_level,
					opt_psm, opt_mtu, connect_cb, &gerr);
	if (iochannel == NULL) {
		set_state(STATE_DISCONNECTED);
		error("%s\n", gerr->message);
		g_error_free(gerr);
	} else
		g_io_add_watch(iochannel, G_IO_HUP, channel_watcher, NULL);
}

static void cmd_disconnect(int argcp, char **argvp)
{
	disconnect_io();
}

static void cmd_primary(int argcp, char **argvp)
{
	bt_uuid_t uuid;

	if (conn_state != STATE_CONNECTED) {
		failed("Disconnected\n");
		return;
	}

	if (argcp == 1) {
		gatt_discover_primary(attrib, NULL, primary_all_cb, NULL);
		return;
	}

	if (bt_string_to_uuid(&uuid, argvp[1]) < 0) {
		error("Invalid UUID\n");
		return;
	}

	gatt_discover_primary(attrib, &uuid, primary_by_uuid_cb, NULL);
}

static int strtohandle(const char *src)
{
	char *e;
	int dst;

	errno = 0;
	dst = strtoll(src, &e, 16);
	if (errno != 0 || *e != '\0')
		return -EINVAL;

	return dst;
}

static void cmd_included(int argcp, char **argvp)
{
	int start = 0x0001;
	int end = 0xffff;

	if (conn_state != STATE_CONNECTED) {
		failed("Disconnected\n");
		return;
	}

	if (argcp > 1) {
		start = strtohandle(argvp[1]);
		if (start < 0) {
			error("Invalid start handle: %s\n", argvp[1]);
			return;
		}
		end = start;
	}

	if (argcp > 2) {
		end = strtohandle(argvp[2]);
		if (end < 0) {
			error("Invalid end handle: %s\n", argvp[2]);
			return;
		}
	}

	gatt_find_included(attrib, start, end, included_cb, NULL);
}

static void cmd_char(int argcp, char **argvp)
{
	int start = 0x0001;
	int end = 0xffff;

	if (conn_state != STATE_CONNECTED) {
		failed("Disconnected\n");
		return;
	}

	if (argcp > 1) {
		start = strtohandle(argvp[1]);
		if (start < 0) {
			error("Invalid start handle: %s\n", argvp[1]);
			return;
		}
	}

	if (argcp > 2) {
		end = strtohandle(argvp[2]);
		if (end < 0) {
			error("Invalid end handle: %s\n", argvp[2]);
			return;
		}
	}

	if (argcp > 3) {
		bt_uuid_t uuid;

		if (bt_string_to_uuid(&uuid, argvp[3]) < 0) {
			error("Invalid UUID\n");
			return;
		}

		gatt_discover_char(attrib, start, end, &uuid, char_cb, NULL);
		return;
	}

	gatt_discover_char(attrib, start, end, NULL, char_cb, NULL);
}

static void cmd_char_desc(int argcp, char **argvp)
{
	if (conn_state != STATE_CONNECTED) {
		failed("Disconnected\n");
		return;
	}

	if (argcp > 1) {
		start = strtohandle(argvp[1]);
		if (start < 0) {
			error("Invalid start handle: %s\n", argvp[1]);
			return;
		}
	} else
		start = 0x0001;

	if (argcp > 2) {
		end = strtohandle(argvp[2]);
		if (end < 0) {
			error("Invalid end handle: %s\n", argvp[2]);
			return;
		}
	} else
		end = 0xffff;

	gatt_discover_char_desc(attrib, start, end, char_desc_cb, NULL);
}

static void cmd_read_hnd(int argcp, char **argvp)
{
	int handle;

	if (conn_state != STATE_CONNECTED) {
		failed("Disconnected\n");
		return;
	}

	if (argcp < 2) {
		error("Missing argument: handle\n");
		return;
	}

	handle = strtohandle(argvp[1]);
	if (handle < 0) {
		error("Invalid handle: %s\n", argvp[1]);
		return;
	}

	gatt_read_char(attrib, handle, char_read_cb, attrib);
}

static void cmd_read_uuid(int argcp, char **argvp)
{
	int start = 0x0001;
	int end = 0xffff;
	bt_uuid_t uuid;

	if (conn_state != STATE_CONNECTED) {
		failed("Disconnected\n");
		return;
	}

	if (argcp < 2) {
		error("Missing argument: UUID\n");
		return;
	}

	if (bt_string_to_uuid(&uuid, argvp[1]) < 0) {
		error("Invalid UUID\n");
		return;
	}

	if (argcp > 2) {
		start = strtohandle(argvp[2]);
		if (start < 0) {
			error("Invalid start handle: %s\n", argvp[1]);
			return;
		}
	}

	if (argcp > 3) {
		end = strtohandle(argvp[3]);
		if (end < 0) {
			error("Invalid end handle: %s\n", argvp[2]);
			return;
		}
	}

	gatt_read_char_by_uuid(attrib, start, end, &uuid, char_read_by_uuid_cb,
									NULL);
	
	requested_read = 1;
}

static void char_write_req_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	if (status != 0) {
		error("Characteristic Write Request failed: "
						"%s\n", att_ecode2str(status));
		return;
	}

	if (!dec_write_resp(pdu, plen) && !dec_exec_write_resp(pdu, plen)) {
		error("Protocol error\n");
		return;
	}

	rl_printf("Characteristic value was written successfully\n");
}

static void cmd_char_write(int argcp, char **argvp)
{
	uint8_t *value;
	size_t plen;
	int handle;

	if (conn_state != STATE_CONNECTED) {
		failed("Disconnected\n");
		return;
	}

	if (argcp < 3) {
		rl_printf("Usage: %s <handle> <new value>\n", argvp[0]);
		return;
	}

	handle = strtohandle(argvp[1]);
	if (handle <= 0) {
		error("A valid handle is required\n");
		return;
	}

	plen = gatt_attr_data_from_string(argvp[2], &value);
	if (plen == 0) {
		error("Invalid value\n");
		return;
	}

	if (g_strcmp0("char-write-req", argvp[0]) == 0)
		gatt_write_char(attrib, handle, value, plen,
					char_write_req_cb, NULL);
	else
		gatt_write_cmd(attrib, handle, value, plen, NULL, NULL);

	g_free(value);
}

static void cmd_sec_level(int argcp, char **argvp)
{
	GError *gerr = NULL;
	BtIOSecLevel sec_level;

	if (argcp < 2) {
		rl_printf("sec-level: %s\n", opt_sec_level);
		return;
	}

	if (strcasecmp(argvp[1], "medium") == 0)
		sec_level = BT_IO_SEC_MEDIUM;
	else if (strcasecmp(argvp[1], "high") == 0)
		sec_level = BT_IO_SEC_HIGH;
	else if (strcasecmp(argvp[1], "low") == 0)
		sec_level = BT_IO_SEC_LOW;
	else {
		rl_printf("Allowed values: low | medium | high\n");
		return;
	}

	g_free(opt_sec_level);
	opt_sec_level = g_strdup(argvp[1]);

	if (conn_state != STATE_CONNECTED)
		return;

	if (opt_psm) {
		rl_printf("Change will take effect on reconnection\n");
		return;
	}

	bt_io_set(iochannel, &gerr,
			BT_IO_OPT_SEC_LEVEL, sec_level,
			BT_IO_OPT_INVALID);
	if (gerr) {
		error("%s\n", gerr->message);
		g_error_free(gerr);
	}
}

static void exchange_mtu_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	uint16_t mtu;

	if (status != 0) {
		error("Exchange MTU Request failed: %s\n",
						att_ecode2str(status));
		return;
	}

	if (!dec_mtu_resp(pdu, plen, &mtu)) {
		error("Protocol error\n");
		return;
	}

	mtu = MIN(mtu, opt_mtu);
	/* Set new value for MTU in client */
	if (g_attrib_set_mtu(attrib, mtu))
		rl_printf("MTU was exchanged successfully: %d\n", mtu);
	else
		error("Error exchanging MTU\n");
}

static void cmd_mtu(int argcp, char **argvp)
{
	if (conn_state != STATE_CONNECTED) {
		failed("Disconnected\n");
		return;
	}

	if (opt_psm) {
		failed("Operation is only available for LE transport.\n");
		return;
	}

	if (argcp < 2) {
		rl_printf("Usage: mtu <value>\n");
		return;
	}

	if (opt_mtu) {
		failed("MTU exchange can only occur once per connection.\n");
		return;
	}

	errno = 0;
	opt_mtu = strtoll(argvp[1], NULL, 0);
	if (errno != 0 || opt_mtu < ATT_DEFAULT_LE_MTU) {
		error("Invalid value. Minimum MTU size is %d\n",
							ATT_DEFAULT_LE_MTU);
		return;
	}

	gatt_exchange_mtu(attrib, opt_mtu, exchange_mtu_cb, NULL);
}

static struct {
	const char *cmd;
	void (*func)(int argcp, char **argvp);
	const char *params;
	const char *desc;
} commands[] = {
	{ "help",		cmd_help,	"",
		"Show this help"},
	{ "exit",		cmd_exit,	"",
		"Exit interactive mode" },
	{ "quit",		cmd_exit,	"",
		"Exit interactive mode" },
	{ "connect",		cmd_connect,	"[address [address type]]",
		"Connect to a remote device" },
	{ "disconnect",		cmd_disconnect,	"",
		"Disconnect from a remote device" },
	{ "primary",		cmd_primary,	"[UUID]",
		"Primary Service Discovery" },
	{ "included",		cmd_included,	"[start hnd [end hnd]]",
		"Find Included Services" },
	{ "characteristics",	cmd_char,	"[start hnd [end hnd [UUID]]]",
		"Characteristics Discovery" },
	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
		"Characteristics Descriptor Discovery" },
	{ "char-read-hnd",	cmd_read_hnd,	"<handle>",
		"Characteristics Value/Descriptor Read by handle" },
	{ "char-read-uuid",	cmd_read_uuid,	"<UUID> [start hnd] [end hnd]",
		"Characteristics Value/Descriptor Read by UUID" },
	{ "char-write-req",	cmd_char_write,	"<handle> <new value>",
		"Characteristic Value Write (Write Request)" },
	{ "char-write-cmd",	cmd_char_write,	"<handle> <new value>",
		"Characteristic Value Write (No response)" },
	{ "sec-level",		cmd_sec_level,	"[low | medium | high]",
		"Set security level. Default: low" },
	{ "mtu",		cmd_mtu,	"<value>",
		"Exchange MTU for GATT/ATT" },
	{ NULL, NULL, NULL}
};

static void cmd_help(int argcp, char **argvp)
{
	int i;

	for (i = 0; commands[i].cmd; i++)
		rl_printf("%-15s %-30s %s\n", commands[i].cmd,
				commands[i].params, commands[i].desc);
}

static void parse_line(char *line_read)
{
	char **argvp;
	int argcp;
	int i;

	if (line_read == NULL) {
		rl_printf("\n");
		//cmd_exit(0, NULL);
		return;
	}

	line_read = g_strstrip(line_read);

	if (*line_read == '\0')
		goto done;

	add_history(line_read);

	if (g_shell_parse_argv(line_read, &argcp, &argvp, NULL) == FALSE)
		goto done;

	for (i = 0; commands[i].cmd; i++)
		if (strcasecmp(commands[i].cmd, argvp[0]) == 0)
			break;

	if (commands[i].cmd)
		commands[i].func(argcp, argvp);
	else
		error("%s: command not found\n", argvp[0]);

	g_strfreev(argvp);

done:
	;
	//free(line_read);
}

static gboolean prompt_read(GIOChannel *chan, GIOCondition cond,
							gpointer user_data)
{
	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
		g_io_channel_unref(chan);
		return FALSE;
	}

	rl_callback_read_char();

	return TRUE;
}

static char *completion_generator(const char *text, int state)
{
	static int index = 0, len = 0;
	const char *cmd = NULL;

	if (state == 0) {
		index = 0;
		len = strlen(text);
	}

	while ((cmd = commands[index].cmd) != NULL) {
		index++;
		if (strncmp(cmd, text, len) == 0)
			return strdup(cmd);
	}

	return NULL;
}

static char **commands_completion(const char *text, int start, int end)
{
	if (start == 0)
		return rl_completion_matches(text, &completion_generator);
	else
		return NULL;
}

static guint setup_standard_input(void)
{
	GIOChannel *channel;
	guint source;

	channel = g_io_channel_unix_new(fileno(stdin));

	source = g_io_add_watch(channel,
				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
				prompt_read, NULL);

	g_io_channel_unref(channel);

	return source;
}

static gboolean signal_handler(GIOChannel *channel, GIOCondition condition,
							gpointer user_data)
{
	static unsigned int __terminated = 0;
	struct signalfd_siginfo si;
	ssize_t result;
	int fd;

	if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
		g_main_loop_quit(event_loop);
		return FALSE;
	}

	fd = g_io_channel_unix_get_fd(channel);

	result = read(fd, &si, sizeof(si));
	if (result != sizeof(si))
		return FALSE;

	switch (si.ssi_signo) {
	case SIGINT:
		rl_replace_line("", 0);
		rl_crlf();
		rl_on_new_line();
		rl_redisplay();
		break;
	case SIGTERM:
		if (__terminated == 0) {
			rl_replace_line("", 0);
			rl_crlf();
			g_main_loop_quit(event_loop);
		}

		__terminated = 1;
		break;
	}

	return TRUE;
}

static guint setup_signalfd(void)
{
	GIOChannel *channel;
	guint source;
	sigset_t mask;
	int fd;

	sigemptyset(&mask);
	sigaddset(&mask, SIGINT);
	sigaddset(&mask, SIGTERM);

	if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
		perror("Failed to set signal mask");
		return 0;
	}

	fd = signalfd(-1, &mask, 0);
	if (fd < 0) {
		perror("Failed to create signal descriptor");
		return 0;
	}

	channel = g_io_channel_unix_new(fd);

	g_io_channel_set_close_on_unref(channel, TRUE);
	g_io_channel_set_encoding(channel, NULL, NULL);
	g_io_channel_set_buffered(channel, FALSE);

	source = g_io_add_watch(channel,
				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
				signal_handler, NULL);

	g_io_channel_unref(channel);

	return source;
}

gboolean callback_fastloop(GIOChannel *source, GIOCondition condition,gpointer data)
{
	if (conn_state == STATE_DISCONNECTED)
	{	
		if (conn_state != STATE_CONNECTING)
		{
		//request
		rl_printf("Requesting Connection \r\n");
		char cmdstring[] = "connect D1:83:15:3C:26:F0 random";
		parse_line((char *) &cmdstring);
		}	
		else
		{
		//wait for connection to be established
		usleep(1000);
		}
	}
	if (conn_state == STATE_CONNECTED)
	{
	// We are connected
		//if not connected 
		if (!requested_read)
		{
		rl_printf("Requesting Reading\r\n");
		//request read
		char cmdstring[] = "char-read-uuid 2a5b";
		parse_line((char *) &cmdstring);	
		requested_read = 1;		
		}	
		else
		{
		//wait until values are read
		usleep(1000);
		}
	}
	if (done_read)
	{
	rl_printf("Done Reading. Disconnecting\r\n");
	
	char cmdstring[] = "disconnect";
	parse_line((char *) &cmdstring);	
		
	//Reset values
	requested_read = 0;
	done_read = 0;
	
	rl_printf("Loop is %d\r\n",loop_counter);
	loop_counter += 1;
	}
    
	return 1;
}

int main(int argc, char *argv[]) {
    guint input;
    guint signal;

    opt_sec_level = g_strdup("low");

//	opt_src = g_strdup(src);
//	opt_dst = g_strdup(dst);
//	opt_dst_type = g_strdup(dst_type);
//	opt_psm = psm;

	conn_state = STATE_DISCONNECTED;
    prompt = g_string_new(NULL);

    event_loop = g_main_loop_new(NULL, FALSE);
	
	
	input = setup_standard_input();
    signal = setup_signalfd();
	
	requested_read = 0;
	done_read = 0;
	

	loop_counter = 0;
	
    g_timeout_add(1, (GSourceFunc) callback_fastloop, NULL);	
    g_main_loop_run(event_loop);
	

	rl_callback_handler_remove();
    cmd_disconnect(0, NULL);
    g_source_remove(input);
    g_source_remove(signal);
    g_main_loop_unref(event_loop);


    g_string_free(prompt, TRUE);

    g_free(opt_src);
    g_free(opt_dst);
    g_free(opt_sec_level);

    return 0;
}

^ permalink raw reply

* Re: [PATCH 1/2] android: Add skeleton of BlueZ Android daemon
From: Andrei Emeltchenko @ 2013-09-23  7:59 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Frederic Danis, linux-bluetooth
In-Reply-To: <226042C8-264A-469E-8D6A-F41141DC0552@holtmann.org>

On Sat, Sep 21, 2013 at 12:14:55PM -0500, Marcel Holtmann wrote:
> Hi Fred,
> 
> > Define local mapping to glib path, otherwise this has to be inside central
> > place in the build repository.
> > 
> > Retrieve Bluetooth version from configure.ac.
> > ---
> > .gitignore         |    2 +
> > Android.mk         |    9 ++++
> > Makefile.am        |    1 +
> > Makefile.android   |    7 ++++
> > android/Android.mk |   24 +++++++++++
> > android/main.c     |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > configure.ac       |    5 +++
> > 7 files changed, 167 insertions(+)
> > create mode 100644 Android.mk
> > create mode 100644 Makefile.android
> > create mode 100644 android/Android.mk
> > create mode 100644 android/main.c
> 
> lets split this out a little bit. Code additions should not be intermixed with additions to the build system and especially configure options.
> 
> I rather not have a top-level Android.mk. It should be enough to provide an android/Android.mk.
> 

I believe this way we cannot build our project.

Best regards 
Andrei Emeltchenko 

^ permalink raw reply

* Re: [PATCH 2/2] android: Android version of log.c
From: Andrei Emeltchenko @ 2013-09-23  7:48 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Frederic Danis, linux-bluetooth
In-Reply-To: <708DB870-5A40-4056-86C8-79092784757C@holtmann.org>

Hi all,

On Sat, Sep 21, 2013 at 12:20:52PM -0500, Marcel Holtmann wrote:
> Hi Fred,
> > +
> > +static void android_log(int pri, const char *fmt, va_list ap)
> > +{
> > +	char *msg;
> > +	struct iovec vec[3];
> > +
> > +	msg = g_strdup_vprintf(fmt, ap);
> > +
> > +	if (!detached) {
> > +		vec[0].iov_base = (void *) msg;
> > +		vec[0].iov_len = strlen(msg) + 1;
> > +		vec[1].iov_base = "\n";
> > +		vec[1].iov_len = 1;
> > +		writev(STDERR_FILENO, vec, 2);
> > +	}
> 
> Lets not worry about logging to stderr at all.

Then I believe this might be simplified a lot. We might use
__android_log_print - like functions in this case.

Best regards 
Andrei Emeltchenko 


^ permalink raw reply

* Re: [PATCH v2 0/8] decoupling adapter code from sdp
From: Johan Hedberg @ 2013-09-23  7:47 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1379599248-7923-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Thu, Sep 19, 2013, Szymon Janc wrote:
> This includes code removal from sdptool that is no longer fully usable
> with this serie.
> 
> Since Marcel had some objections about Device ID plugin patch it is moved
> to end to not interfere with rest of patches. This plugin now also handles
> setting proper DID values to adapter. Yet, main_opts are still accessed
> directly and that should be worked out later.
> 
> With those patches sdp server is fully controlled by adapters and there
> is no mutual adapter<->sdp code invocations.
> 
> BR
> Szymon
> 
> Szymon Janc (8):
>   adapter: Insert DeviceID record if setting DeviceID data to controller
>   adapter: Handle adding new SDP records
>   adapter: Handle removing of SDP records
>   Remove not needed sdp_init_services_list function
>   unit: Remove not needed functions from test-sdp
>   sdpd: Remove 'register' and 'remove' requests
>   sdptool: Remove support for adding and removing service records
>   sdp: Decouple Device ID profile implementation
> 
>  Makefile.plugins             |    3 +
>  plugins/gatt-example.c       |    2 +-
>  profiles/audio/a2dp.c        |   14 +-
>  profiles/audio/avrcp.c       |    8 +-
>  profiles/deviceid/deviceid.c |  187 +++
>  profiles/health/hdp.c        |    2 +-
>  profiles/health/hdp_util.c   |    6 +-
>  profiles/network/server.c    |    6 +-
>  profiles/sap/server.c        |    4 +-
>  src/adapter.c                |   59 +-
>  src/adapter.h                |    8 +-
>  src/attrib-server.c          |   12 +-
>  src/attrib-server.h          |    2 +-
>  src/profile.c                |    9 +-
>  src/sdpd-database.c          |   41 -
>  src/sdpd-request.c           |   14 -
>  src/sdpd-server.c            |    4 -
>  src/sdpd-service.c           |  158 ---
>  src/sdpd.h                   |    6 -
>  tools/sdptool.1              |   16 -
>  tools/sdptool.c              | 2595 +-----------------------------------------
>  unit/test-sdp.c              |   29 -
>  22 files changed, 321 insertions(+), 2864 deletions(-)
>  create mode 100644 profiles/deviceid/deviceid.c

Patches 1-5 have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 2/5] Bluetooth: Fix assignment of 0/1 to bool variables
From: Gustavo Padovan @ 2013-09-22 22:21 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: marcel, johan.hedberg, davem, linux-bluetooth, netdev,
	linux-kernel, kernel-janitors
In-Reply-To: <1379875453-20083-2-git-send-email-peter.senna@gmail.com>

Hi Peter,

2013-09-22 Peter Senna Tschudin <peter.senna@gmail.com>:

> Convert 0 to false and 1 to true when assigning values to bool
> variables. Inspired by commit 3db1cd5c05f35fb43eb134df6f321de4e63141f2.
> 
> The simplified semantic patch that find this problem is as
> follows (http://coccinelle.lip6.fr/):
> 
> @@
> bool b;
> @@
> (
> -b = 0
> +b = false
> |
> -b = 1
> +b = true
> )
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> 
> ---
>  net/bluetooth/l2cap_core.c |   16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)

Patch has been applied to bluetooth-next. Thanks.

	Gustavo

^ permalink raw reply

* Re: [PATCH 2/5] Bluetooth: Fix assignment of 0/1 to bool variables
From: Marcel Holtmann @ 2013-09-22 18:58 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: gustavo, johan.hedberg, davem, linux-bluetooth, netdev,
	linux-kernel, kernel-janitors
In-Reply-To: <1379875453-20083-2-git-send-email-peter.senna@gmail.com>

Hi Peter,

> Convert 0 to false and 1 to true when assigning values to bool
> variables. Inspired by commit 3db1cd5c05f35fb43eb134df6f321de4e63141f2.
> 
> The simplified semantic patch that find this problem is as
> follows (http://coccinelle.lip6.fr/):
> 
> @@
> bool b;
> @@
> (
> -b = 0
> +b = false
> |
> -b = 1
> +b = true
> )
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> 
> ---
> net/bluetooth/l2cap_core.c |   16 ++++++++--------
> 1 file changed, 8 insertions(+), 8 deletions(-)

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel


^ permalink raw reply

* [PATCH 2/5] Bluetooth: Fix assignment of 0/1 to bool variables
From: Peter Senna Tschudin @ 2013-09-22 18:44 UTC (permalink / raw)
  To: marcel
  Cc: gustavo, johan.hedberg, davem, linux-bluetooth, netdev,
	linux-kernel, kernel-janitors, Peter Senna Tschudin
In-Reply-To: <1379875453-20083-1-git-send-email-peter.senna@gmail.com>

Convert 0 to false and 1 to true when assigning values to bool
variables. Inspired by commit 3db1cd5c05f35fb43eb134df6f321de4e63141f2.

The simplified semantic patch that find this problem is as
follows (http://coccinelle.lip6.fr/):

@@
bool b;
@@
(
-b = 0
+b = false
|
-b = 1
+b = true
)

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

---
 net/bluetooth/l2cap_core.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff -u -p a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5797,7 +5797,7 @@ static int l2cap_rx_state_recv(struct l2
 			       struct sk_buff *skb, u8 event)
 {
 	int err = 0;
-	bool skb_in_use = 0;
+	bool skb_in_use = false;
 
 	BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
 	       event);
@@ -5818,7 +5818,7 @@ static int l2cap_rx_state_recv(struct l2
 							   control->txseq);
 
 			chan->buffer_seq = chan->expected_tx_seq;
-			skb_in_use = 1;
+			skb_in_use = true;
 
 			err = l2cap_reassemble_sdu(chan, skb, control);
 			if (err)
@@ -5854,7 +5854,7 @@ static int l2cap_rx_state_recv(struct l2
 			 * current frame is stored for later use.
 			 */
 			skb_queue_tail(&chan->srej_q, skb);
-			skb_in_use = 1;
+			skb_in_use = true;
 			BT_DBG("Queued %p (queue len %d)", skb,
 			       skb_queue_len(&chan->srej_q));
 
@@ -5932,7 +5932,7 @@ static int l2cap_rx_state_srej_sent(stru
 {
 	int err = 0;
 	u16 txseq = control->txseq;
-	bool skb_in_use = 0;
+	bool skb_in_use = false;
 
 	BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
 	       event);
@@ -5944,7 +5944,7 @@ static int l2cap_rx_state_srej_sent(stru
 			/* Keep frame for reassembly later */
 			l2cap_pass_to_tx(chan, control);
 			skb_queue_tail(&chan->srej_q, skb);
-			skb_in_use = 1;
+			skb_in_use = true;
 			BT_DBG("Queued %p (queue len %d)", skb,
 			       skb_queue_len(&chan->srej_q));
 
@@ -5955,7 +5955,7 @@ static int l2cap_rx_state_srej_sent(stru
 
 			l2cap_pass_to_tx(chan, control);
 			skb_queue_tail(&chan->srej_q, skb);
-			skb_in_use = 1;
+			skb_in_use = true;
 			BT_DBG("Queued %p (queue len %d)", skb,
 			       skb_queue_len(&chan->srej_q));
 
@@ -5970,7 +5970,7 @@ static int l2cap_rx_state_srej_sent(stru
 			 * the missing frames.
 			 */
 			skb_queue_tail(&chan->srej_q, skb);
-			skb_in_use = 1;
+			skb_in_use = true;
 			BT_DBG("Queued %p (queue len %d)", skb,
 			       skb_queue_len(&chan->srej_q));
 
@@ -5984,7 +5984,7 @@ static int l2cap_rx_state_srej_sent(stru
 			 * SREJ'd frames.
 			 */
 			skb_queue_tail(&chan->srej_q, skb);
-			skb_in_use = 1;
+			skb_in_use = true;
 			BT_DBG("Queued %p (queue len %d)", skb,
 			       skb_queue_len(&chan->srej_q));
 

^ permalink raw reply

* [PATCH] drivers: bluetooth: btusb: Added support for Belkin F8065bf usb bluetooth device
From: Ken O'Brien @ 2013-09-21 18:14 UTC (permalink / raw)
  To: marcel, gustavo, johan.hedberg
  Cc: linux-bluetooth, linux-kernel, Ken O'Brien

Adding generic rule on encountering Belkin bluetooth usb device F8065bf.

Relevant section from /sys/kernel/debug/usb/devices:

T:  Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12   MxCh= 0
D:  Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=050d ProdID=065a Rev= 1.12
S:  Manufacturer=Broadcom Corp
S:  Product=BCM20702A0
S:  SerialNumber=0002723E2D29
C:* #Ifs= 4 Cfg#= 1 Atr=a0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
I:  If#= 1 Alt= 2 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
I:  If#= 1 Alt= 3 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
I:  If#= 1 Alt= 4 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
I:  If#= 1 Alt= 5 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
E:  Ad=84(I) Atr=02(Bulk) MxPS=  32 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS=  32 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)

Signed-off-by: Ken O'Brien <kernel@kenobrien.org>
---
 drivers/bluetooth/btusb.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 8e16f0a..dbfbc12 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -111,7 +111,10 @@ static struct usb_device_id btusb_table[] = {
 
 	/*Broadcom devices with vendor specific id */
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },
-
+
+	/* Belkin F8065bf - Broadcom based */
+	{ USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) },
+
 	{ }	/* Terminating entry */
 };
 
-- 
1.8.1.4

^ permalink raw reply related

* Re: [PATCH 1/2] android: Add skeleton of BlueZ Android daemon
From: Johan Hedberg @ 2013-09-21 18:09 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Frederic Danis, linux-bluetooth
In-Reply-To: <226042C8-264A-469E-8D6A-F41141DC0552@holtmann.org>

Hi Marcel,

On Sat, Sep 21, 2013, Marcel Holtmann wrote:
> > Define local mapping to glib path, otherwise this has to be inside central
> > place in the build repository.
> > 
> > Retrieve Bluetooth version from configure.ac.
> > ---
> > .gitignore         |    2 +
> > Android.mk         |    9 ++++
> > Makefile.am        |    1 +
> > Makefile.android   |    7 ++++
> > android/Android.mk |   24 +++++++++++
> > android/main.c     |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > configure.ac       |    5 +++
> > 7 files changed, 167 insertions(+)
> > create mode 100644 Android.mk
> > create mode 100644 Makefile.android
> > create mode 100644 android/Android.mk
> > create mode 100644 android/main.c
> 
> lets split this out a little bit. Code additions should not be
> intermixed with additions to the build system and especially configure
> options.

I agree about keeping separate build system changes such as adding
completely new makefiles or adding configure options. However, what I
think doesn't hurt (and the guidance I've given) is to at least include
the matching build system change to the same commit that adds new c/h
files. This way you don't end up having "dead code" in the tree in
between commits that just lies around there but can't be compiled and
wont be included in any release tarballs.

Johan

^ permalink raw reply

* Re: [PATCH v2 7/8] sdptool: Remove support for adding and removing service records
From: Marcel Holtmann @ 2013-09-21 17:27 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1379599248-7923-8-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

> SDP database should now be controlled only by adapters. SDP code
> is no longer able to notify controllers about external changes to
> database. This results in services added/removed by sdptool being
> not updated properly in adapter structure.
> ---
> tools/sdptool.1 |   16 -
> tools/sdptool.c | 2595 ++-----------------------------------------------------
> 2 files changed, 54 insertions(+), 2557 deletions(-)

this is a bit dangerous. We still need sdptool for qualification purposes. So I rather keep it around.

Regards

Marcel

> 
> diff --git a/tools/sdptool.1 b/tools/sdptool.1
> index 88ad818..ee95e67 100644
> --- a/tools/sdptool.1
> +++ b/tools/sdptool.1
> @@ -82,18 +82,6 @@ Browse all available services on the device
> specified by a Bluetooth address as a parameter.
> .IP "\fBrecords [--tree] [--raw] [--xml] bdaddr\fP" 10
> Retrieve all possible service records.
> -.IP "\fBadd [ --handle=N --channel=N ]\fP" 10
> -Add a service to the local
> -SDP database.
> -.IP "" 10
> -You can specify a handle for this record using
> -the \fB--handle\fP option.
> -.IP "" 10
> -You can specify a channel to add the service on
> -using the \fB--channel\fP option.
> -.IP "\fBdel record_handle\fP" 10
> -Remove a service from the local
> -SDP database.
> .IP "\fBget [--tree] [--raw] [--xml] [--bdaddr bdaddr] record_handle\fP" 10
> Retrieve a service from the local
> SDP database.
> @@ -112,10 +100,6 @@ Displays help on using sdptool.
> sdptool browse 00:80:98:24:15:6D
> .PP
> sdptool browse local
> -.PP
> -sdptool add DUN
> -.PP
> -sdptool del 0x10000
> .SH "BUGS"
> .PP
> Documentation needs improving.
> diff --git a/tools/sdptool.c b/tools/sdptool.c
> index c241655..7d1121d 100644
> --- a/tools/sdptool.c
> +++ b/tools/sdptool.c
> @@ -1145,2148 +1145,30 @@ static void print_service_attr(sdp_record_t *rec)
> 	}
> }
> 
> -/*
> - * Support for Service (de)registration
> - */
> -typedef struct {
> -	uint32_t handle;
> -	char *name;
> -	char *provider;
> -	char *desc;
> -	unsigned int class;
> -	unsigned int profile;
> -	uint16_t psm;
> -	uint8_t channel;
> -	uint8_t network;
> -} svc_info_t;
> -
> -static int add_sp(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *apseq, *proto[2], *profiles, *root, *aproto;
> -	uuid_t root_uuid, sp_uuid, l2cap, rfcomm;
> -	sdp_profile_desc_t profile;
> -	sdp_record_t record;
> -	uint8_t u8 = si->channel ? si->channel : 1;
> -	sdp_data_t *channel;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -	sdp_list_free(root, 0);
> -
> -	sdp_uuid16_create(&sp_uuid, SERIAL_PORT_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &sp_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -	sdp_list_free(svclass_id, 0);
> -
> -	sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
> -	profile.version = 0x0100;
> -	profiles = sdp_list_append(0, &profile);
> -	sdp_set_profile_descs(&record, profiles);
> -	sdp_list_free(profiles, 0);
> -
> -	sdp_uuid16_create(&l2cap, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm);
> -	channel = sdp_data_alloc(SDP_UINT8, &u8);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_add_lang_attr(&record);
> -
> -	sdp_set_info_attr(&record, "Serial Port", "BlueZ", "COM Port");
> -
> -	sdp_set_url_attr(&record, "http://www.bluez.org/",
> -			"http://www.bluez.org/", "http://www.bluez.org/");
> -
> -	sdp_set_service_id(&record, sp_uuid);
> -	sdp_set_service_ttl(&record, 0xffff);
> -	sdp_set_service_avail(&record, 0xff);
> -	sdp_set_record_state(&record, 0x00001234);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("Serial Port service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_dun(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root, *aproto;
> -	uuid_t rootu, dun, gn, l2cap, rfcomm;
> -	sdp_profile_desc_t profile;
> -	sdp_list_t *proto[2];
> -	sdp_record_t record;
> -	uint8_t u8 = si->channel ? si->channel : 2;
> -	sdp_data_t *channel;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&rootu, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &rootu);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&dun, DIALUP_NET_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &dun);
> -	sdp_uuid16_create(&gn,  GENERIC_NETWORKING_SVCLASS_ID);
> -	svclass_id = sdp_list_append(svclass_id, &gn);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile.uuid, DIALUP_NET_PROFILE_ID);
> -	profile.version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm);
> -	channel = sdp_data_alloc(SDP_UINT8, &u8);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Dial-Up Networking", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("Dial-Up Networking service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_fax(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, fax_uuid, tel_uuid, l2cap_uuid, rfcomm_uuid;
> -	sdp_profile_desc_t profile;
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint8_t u8 = si->channel? si->channel : 3;
> -	sdp_data_t *channel;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&fax_uuid, FAX_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &fax_uuid);
> -	sdp_uuid16_create(&tel_uuid, GENERIC_TELEPHONY_SVCLASS_ID);
> -	svclass_id = sdp_list_append(svclass_id, &tel_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile.uuid, FAX_PROFILE_ID);
> -	profile.version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> -	channel = sdp_data_alloc(SDP_UINT8, &u8);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq  = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Fax", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -	printf("Fax service registered\n");
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -	return ret;
> -}
> -
> -static int add_lan(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
> -	sdp_profile_desc_t profile;
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint8_t u8 = si->channel ? si->channel : 4;
> -	sdp_data_t *channel;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&svclass_uuid, LAN_ACCESS_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &svclass_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile.uuid, LAN_ACCESS_PROFILE_ID);
> -	profile.version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> -	channel = sdp_data_alloc(SDP_UINT8, &u8);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "LAN Access over PPP", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("LAN Access service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_headset(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid;
> -	sdp_profile_desc_t profile;
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint8_t u8 = si->channel ? si->channel : 5;
> -	sdp_data_t *channel;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&svclass_uuid, HEADSET_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &svclass_uuid);
> -	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
> -	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID);
> -	profile.version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> -	channel = sdp_data_alloc(SDP_UINT8, &u8);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Headset", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("Headset service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_headset_ag(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid;
> -	sdp_profile_desc_t profile;
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint8_t u8 = si->channel ? si->channel : 7;
> -	sdp_data_t *channel;
> -	uint8_t netid = si->network ? si->network : 0x01; // ???? profile document
> -	sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&svclass_uuid, HEADSET_AGW_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &svclass_uuid);
> -	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
> -	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID);
> -	profile.version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> -	channel = sdp_data_alloc(SDP_UINT8, &u8);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Voice Gateway", 0, 0);
> -
> -	sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network);
> -
> -	if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("Headset AG service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_handsfree(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid;
> -	sdp_profile_desc_t profile;
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint8_t u8 = si->channel ? si->channel : 6;
> -	uint16_t u16 = 0x31;
> -	sdp_data_t *channel, *features;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&svclass_uuid, HANDSFREE_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &svclass_uuid);
> -	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
> -	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID);
> -	profile.version = 0x0101;
> -	pfseq = sdp_list_append(0, &profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> -	channel = sdp_data_alloc(SDP_UINT8, &u8);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	features = sdp_data_alloc(SDP_UINT16, &u16);
> -	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Handsfree", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("Handsfree service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_handsfree_ag(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid;
> -	sdp_profile_desc_t profile;
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint8_t u8 = si->channel ? si->channel : 7;
> -	uint16_t u16 = 0x17;
> -	sdp_data_t *channel, *features;
> -	uint8_t netid = si->network ? si->network : 0x01; // ???? profile document
> -	sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&svclass_uuid, HANDSFREE_AGW_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &svclass_uuid);
> -	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
> -	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID);
> -	profile.version = 0x0105;
> -	pfseq = sdp_list_append(0, &profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> -	channel = sdp_data_alloc(SDP_UINT8, &u8);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	features = sdp_data_alloc(SDP_UINT16, &u16);
> -	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Voice Gateway", 0, 0);
> -
> -	sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network);
> -
> -	if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("Handsfree AG service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_simaccess(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid;
> -	sdp_profile_desc_t profile;
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint8_t u8 = si->channel? si->channel : 8;
> -	uint16_t u16 = 0x31;
> -	sdp_data_t *channel, *features;
> -	int ret = 0;
> -
> -	memset((void *)&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&svclass_uuid, SAP_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &svclass_uuid);
> -	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_TELEPHONY_SVCLASS_ID);
> -	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile.uuid, SAP_PROFILE_ID);
> -	profile.version = 0x0101;
> -	pfseq = sdp_list_append(0, &profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> -	channel = sdp_data_alloc(SDP_UINT8, &u8);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	features = sdp_data_alloc(SDP_UINT16, &u16);
> -	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "SIM Access", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("SIM Access service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_opush(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, opush_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[3];
> -	sdp_record_t record;
> -	uint8_t chan = si->channel ? si->channel : 9;
> -	sdp_data_t *channel;
> -	uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xff };
> -	void *dtds[sizeof(formats)], *values[sizeof(formats)];
> -	unsigned int i;
> -	uint8_t dtd = SDP_UINT8;
> -	sdp_data_t *sflist;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&opush_uuid, OBEX_OBJPUSH_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &opush_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, OBEX_OBJPUSH_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> -	channel = sdp_data_alloc(SDP_UINT8, &chan);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
> -	proto[2] = sdp_list_append(0, &obex_uuid);
> -	apseq = sdp_list_append(apseq, proto[2]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	for (i = 0; i < sizeof(formats); i++) {
> -		dtds[i] = &dtd;
> -		values[i] = &formats[i];
> -	}
> -	sflist = sdp_seq_alloc(dtds, values, sizeof(formats));
> -	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FORMATS_LIST, sflist);
> -
> -	sdp_set_info_attr(&record, "OBEX Object Push", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("OBEX Object Push service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(proto[2], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_pbap(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, pbap_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[3];
> -	sdp_record_t record;
> -	uint8_t chan = si->channel ? si->channel : 19;
> -	sdp_data_t *channel;
> -	uint8_t formats[] = {0x01};
> -	uint8_t dtd = SDP_UINT8;
> -	sdp_data_t *sflist;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&pbap_uuid, PBAP_PSE_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &pbap_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, PBAP_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> -	channel = sdp_data_alloc(SDP_UINT8, &chan);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
> -	proto[2] = sdp_list_append(0, &obex_uuid);
> -	apseq = sdp_list_append(apseq, proto[2]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sflist = sdp_data_alloc(dtd,formats);
> -	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_REPOSITORIES, sflist);
> -
> -	sdp_set_info_attr(&record, "OBEX Phonebook Access Server", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record,
> -			SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("PBAP service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(proto[2], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_ftp(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, ftrn_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[3];
> -	sdp_record_t record;
> -	uint8_t u8 = si->channel ? si->channel: 10;
> -	sdp_data_t *channel;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&ftrn_uuid, OBEX_FILETRANS_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &ftrn_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, OBEX_FILETRANS_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile[0]);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> -	channel = sdp_data_alloc(SDP_UINT8, &u8);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
> -	proto[2] = sdp_list_append(0, &obex_uuid);
> -	apseq = sdp_list_append(apseq, proto[2]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "OBEX File Transfer", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("OBEX File Transfer service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(proto[2], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_directprint(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, opush_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[3];
> -	sdp_record_t record;
> -	uint8_t chan = si->channel ? si->channel : 12;
> -	sdp_data_t *channel;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&opush_uuid, DIRECT_PRINTING_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &opush_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, BASIC_PRINTING_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> -	channel = sdp_data_alloc(SDP_UINT8, &chan);
> -	proto[1] = sdp_list_append(proto[1], channel);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
> -	proto[2] = sdp_list_append(0, &obex_uuid);
> -	apseq = sdp_list_append(apseq, proto[2]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Direct Printing", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("Direct Printing service registered\n");
> -
> -end:
> -	sdp_data_free(channel);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(proto[2], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_nap(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint16_t lp = 0x000f, ver = 0x0100;
> -	sdp_data_t *psm, *version;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&ftrn_uuid, NAP_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &ftrn_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile[0]);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	psm = sdp_data_alloc(SDP_UINT16, &lp);
> -	proto[0] = sdp_list_append(proto[0], psm);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&bnep_uuid, BNEP_UUID);
> -	proto[1] = sdp_list_append(0, &bnep_uuid);
> -	version  = sdp_data_alloc(SDP_UINT16, &ver);
> -	proto[1] = sdp_list_append(proto[1], version);
> -
> -	{
> -		uint16_t ptype[4] = { 0x0010, 0x0020, 0x0030, 0x0040 };
> -		sdp_data_t *head, *pseq;
> -		int p;
> -
> -		for (p = 0, head = NULL; p < 4; p++) {
> -			sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]);
> -			head = sdp_seq_append(head, data);
> -		}
> -		pseq = sdp_data_alloc(SDP_SEQ16, head);
> -		proto[1] = sdp_list_append(proto[1], pseq);
> -	}
> -
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Network Access Point Service", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("NAP service registered\n");
> -
> -end:
> -	sdp_data_free(version);
> -	sdp_data_free(psm);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_gn(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint16_t lp = 0x000f, ver = 0x0100;
> -	sdp_data_t *psm, *version;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&ftrn_uuid, GN_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &ftrn_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile[0]);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap_uuid);
> -	psm = sdp_data_alloc(SDP_UINT16, &lp);
> -	proto[0] = sdp_list_append(proto[0], psm);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&bnep_uuid, BNEP_UUID);
> -	proto[1] = sdp_list_append(0, &bnep_uuid);
> -	version = sdp_data_alloc(SDP_UINT16, &ver);
> -	proto[1] = sdp_list_append(proto[1], version);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Group Network Service", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("GN service registered\n");
> -
> -end:
> -	sdp_data_free(version);
> -	sdp_data_free(psm);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_panu(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint16_t lp = 0x000f, ver = 0x0100;
> -	sdp_data_t *psm, *version;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -	sdp_list_free(root, NULL);
> -
> -	sdp_uuid16_create(&ftrn_uuid, PANU_SVCLASS_ID);
> -	svclass_id = sdp_list_append(NULL, &ftrn_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -	sdp_list_free(svclass_id, NULL);
> -
> -	sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(NULL, &profile[0]);
> -	sdp_set_profile_descs(&record, pfseq);
> -	sdp_list_free(pfseq, NULL);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[0] = sdp_list_append(NULL, &l2cap_uuid);
> -	psm = sdp_data_alloc(SDP_UINT16, &lp);
> -	proto[0] = sdp_list_append(proto[0], psm);
> -	apseq = sdp_list_append(NULL, proto[0]);
> -
> -	sdp_uuid16_create(&bnep_uuid, BNEP_UUID);
> -	proto[1] = sdp_list_append(NULL, &bnep_uuid);
> -	version = sdp_data_alloc(SDP_UINT16, &ver);
> -	proto[1] = sdp_list_append(proto[1], version);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(NULL, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "PAN User", NULL, NULL);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("PANU service registered\n");
> -
> -end:
> -	sdp_data_free(version);
> -	sdp_data_free(psm);
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_hid_keyb(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, hidkb_uuid, l2cap_uuid, hidp_uuid;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[3];
> -	sdp_data_t *psm, *lang_lst, *lang_lst2, *hid_spec_lst, *hid_spec_lst2;
> -	unsigned int i;
> -	uint8_t dtd = SDP_UINT16;
> -	uint8_t dtd2 = SDP_UINT8;
> -	uint8_t dtd_data = SDP_TEXT_STR8;
> -	void *dtds[2];
> -	void *values[2];
> -	void *dtds2[2];
> -	void *values2[2];
> -	int leng[2];
> -	uint8_t hid_spec_type = 0x22;
> -	uint16_t hid_attr_lang[] = { 0x409, 0x100 };
> -	static const uint16_t ctrl = 0x11;
> -	static const uint16_t intr = 0x13;
> -	static const uint16_t hid_attr[] = { 0x100, 0x111, 0x40, 0x0d, 0x01, 0x01 };
> -	static const uint16_t hid_attr2[] = { 0x0, 0x01, 0x100, 0x1f40, 0x01, 0x01 };
> -	const uint8_t hid_spec[] = {
> -		0x05, 0x01, // usage page
> -		0x09, 0x06, // keyboard
> -		0xa1, 0x01, // key codes
> -		0x85, 0x01, // minimum
> -		0x05, 0x07, // max
> -		0x19, 0xe0, // logical min
> -		0x29, 0xe7, // logical max
> -		0x15, 0x00, // report size
> -		0x25, 0x01, // report count
> -		0x75, 0x01, // input data variable absolute
> -		0x95, 0x08, // report count
> -		0x81, 0x02, // report size
> -		0x75, 0x08,
> -		0x95, 0x01,
> -		0x81, 0x01,
> -		0x75, 0x01,
> -		0x95, 0x05,
> -		0x05, 0x08,
> -		0x19, 0x01,
> -		0x29, 0x05,
> -		0x91, 0x02,
> -		0x75, 0x03,
> -		0x95, 0x01,
> -		0x91, 0x01,
> -		0x75, 0x08,
> -		0x95, 0x06,
> -		0x15, 0x00,
> -		0x26, 0xff,
> -		0x00, 0x05,
> -		0x07, 0x19,
> -		0x00, 0x2a,
> -		0xff, 0x00,
> -		0x81, 0x00,
> -		0x75, 0x01,
> -		0x95, 0x01,
> -		0x15, 0x00,
> -		0x25, 0x01,
> -		0x05, 0x0c,
> -		0x09, 0xb8,
> -		0x81, 0x06,
> -		0x09, 0xe2,
> -		0x81, 0x06,
> -		0x09, 0xe9,
> -		0x81, 0x02,
> -		0x09, 0xea,
> -		0x81, 0x02,
> -		0x75, 0x01,
> -		0x95, 0x04,
> -		0x81, 0x01,
> -		0xc0         // end tag
> -	};
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_add_lang_attr(&record);
> -
> -	sdp_uuid16_create(&hidkb_uuid, HID_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &hidkb_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, HID_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	/* protocols */
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[1] = sdp_list_append(0, &l2cap_uuid);
> -	psm = sdp_data_alloc(SDP_UINT16, &ctrl);
> -	proto[1] = sdp_list_append(proto[1], psm);
> -	apseq = sdp_list_append(0, proto[1]);
> -
> -	sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
> -	proto[2] = sdp_list_append(0, &hidp_uuid);
> -	apseq = sdp_list_append(apseq, proto[2]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	/* additional protocols */
> -	proto[1] = sdp_list_append(0, &l2cap_uuid);
> -	psm = sdp_data_alloc(SDP_UINT16, &intr);
> -	proto[1] = sdp_list_append(proto[1], psm);
> -	apseq = sdp_list_append(0, proto[1]);
> -
> -	sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
> -	proto[2] = sdp_list_append(0, &hidp_uuid);
> -	apseq = sdp_list_append(apseq, proto[2]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_add_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "HID Keyboard", NULL, NULL);
> -
> -	for (i = 0; i < sizeof(hid_attr) / 2; i++)
> -		sdp_attr_add_new(&record,
> -					SDP_ATTR_HID_DEVICE_RELEASE_NUMBER + i,
> -					SDP_UINT16, &hid_attr[i]);
> -
> -	dtds[0] = &dtd2;
> -	values[0] = &hid_spec_type;
> -	dtds[1] = &dtd_data;
> -	values[1] = (uint8_t *) hid_spec;
> -	leng[0] = 0;
> -	leng[1] = sizeof(hid_spec);
> -	hid_spec_lst = sdp_seq_alloc_with_length(dtds, values, leng, 2);
> -	hid_spec_lst2 = sdp_data_alloc(SDP_SEQ8, hid_spec_lst);
> -	sdp_attr_add(&record, SDP_ATTR_HID_DESCRIPTOR_LIST, hid_spec_lst2);
> -
> -	for (i = 0; i < sizeof(hid_attr_lang) / 2; i++) {
> -		dtds2[i] = &dtd;
> -		values2[i] = &hid_attr_lang[i];
> -	}
> -
> -	lang_lst = sdp_seq_alloc(dtds2, values2, sizeof(hid_attr_lang) / 2);
> -	lang_lst2 = sdp_data_alloc(SDP_SEQ8, lang_lst);
> -	sdp_attr_add(&record, SDP_ATTR_HID_LANG_ID_BASE_LIST, lang_lst2);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_SDP_DISABLE, SDP_UINT16, &hid_attr2[0]);
> -
> -	for (i = 0; i < sizeof(hid_attr2) / 2 - 1; i++)
> -		sdp_attr_add_new(&record, SDP_ATTR_HID_REMOTE_WAKEUP + i,
> -						SDP_UINT16, &hid_attr2[i + 1]);
> -
> -	if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("HID keyboard service registered\n");
> -
> -	return 0;
> -}
> -
> -static int add_hid_wiimote(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, hid_uuid, l2cap_uuid, hidp_uuid;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[3];
> -	sdp_data_t *psm, *lang_lst, *lang_lst2, *hid_spec_lst, *hid_spec_lst2;
> -	unsigned int i;
> -	uint8_t dtd = SDP_UINT16;
> -	uint8_t dtd2 = SDP_UINT8;
> -	uint8_t dtd_data = SDP_TEXT_STR8;
> -	void *dtds[2];
> -	void *values[2];
> -	void *dtds2[2];
> -	void *values2[2];
> -	int leng[2];
> -	uint8_t hid_spec_type = 0x22;
> -	uint16_t hid_attr_lang[] = { 0x409, 0x100 };
> -	uint16_t ctrl = 0x11, intr = 0x13;
> -	uint16_t hid_release = 0x0100, parser_version = 0x0111;
> -	uint8_t subclass = 0x04, country = 0x33;
> -	uint8_t virtual_cable = 0, reconnect = 1, sdp_disable = 0;
> -	uint8_t battery = 1, remote_wakeup = 1;
> -	uint16_t profile_version = 0x0100, superv_timeout = 0x0c80;
> -	uint8_t norm_connect = 0, boot_device = 0;
> -	const uint8_t hid_spec[] = {
> -		0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x10,
> -		0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
> -		0x01, 0x06, 0x00, 0xff, 0x09, 0x01, 0x91, 0x00,
> -		0x85, 0x11, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
> -		0x85, 0x12, 0x95, 0x02, 0x09, 0x01, 0x91, 0x00,
> -		0x85, 0x13, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
> -		0x85, 0x14, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
> -		0x85, 0x15, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
> -		0x85, 0x16, 0x95, 0x15, 0x09, 0x01, 0x91, 0x00,
> -		0x85, 0x17, 0x95, 0x06, 0x09, 0x01, 0x91, 0x00,
> -		0x85, 0x18, 0x95, 0x15, 0x09, 0x01, 0x91, 0x00,
> -		0x85, 0x19, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
> -		0x85, 0x1a, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
> -		0x85, 0x20, 0x95, 0x06, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x21, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x22, 0x95, 0x04, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x30, 0x95, 0x02, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x31, 0x95, 0x05, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x32, 0x95, 0x0a, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x33, 0x95, 0x11, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x34, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x35, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x36, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x37, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x3d, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x3e, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
> -		0x85, 0x3f, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
> -		0xc0, 0x00
> -	};
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&hid_uuid, HID_SVCLASS_ID);
> -	svclass_id = sdp_list_append(NULL, &hid_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, HID_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(NULL, profile);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto[1] = sdp_list_append(0, &l2cap_uuid);
> -	psm = sdp_data_alloc(SDP_UINT16, &ctrl);
> -	proto[1] = sdp_list_append(proto[1], psm);
> -	apseq = sdp_list_append(0, proto[1]);
> -
> -	sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
> -	proto[2] = sdp_list_append(0, &hidp_uuid);
> -	apseq = sdp_list_append(apseq, proto[2]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	proto[1] = sdp_list_append(0, &l2cap_uuid);
> -	psm = sdp_data_alloc(SDP_UINT16, &intr);
> -	proto[1] = sdp_list_append(proto[1], psm);
> -	apseq = sdp_list_append(0, proto[1]);
> -
> -	sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
> -	proto[2] = sdp_list_append(0, &hidp_uuid);
> -	apseq = sdp_list_append(apseq, proto[2]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_add_access_protos(&record, aproto);
> -
> -	sdp_add_lang_attr(&record);
> -
> -	sdp_set_info_attr(&record, "Nintendo RVL-CNT-01",
> -					"Nintendo", "Nintendo RVL-CNT-01");
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_DEVICE_RELEASE_NUMBER,
> -						SDP_UINT16, &hid_release);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_PARSER_VERSION,
> -						SDP_UINT16, &parser_version);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_DEVICE_SUBCLASS,
> -						SDP_UINT8, &subclass);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_COUNTRY_CODE,
> -						SDP_UINT8, &country);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_VIRTUAL_CABLE,
> -						SDP_BOOL, &virtual_cable);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_RECONNECT_INITIATE,
> -						SDP_BOOL, &reconnect);
> -
> -	dtds[0] = &dtd2;
> -	values[0] = &hid_spec_type;
> -	dtds[1] = &dtd_data;
> -	values[1] = (uint8_t *) hid_spec;
> -	leng[0] = 0;
> -	leng[1] = sizeof(hid_spec);
> -	hid_spec_lst = sdp_seq_alloc_with_length(dtds, values, leng, 2);
> -	hid_spec_lst2 = sdp_data_alloc(SDP_SEQ8, hid_spec_lst);
> -	sdp_attr_add(&record, SDP_ATTR_HID_DESCRIPTOR_LIST, hid_spec_lst2);
> -
> -	for (i = 0; i < sizeof(hid_attr_lang) / 2; i++) {
> -		dtds2[i] = &dtd;
> -		values2[i] = &hid_attr_lang[i];
> -	}
> -
> -	lang_lst = sdp_seq_alloc(dtds2, values2, sizeof(hid_attr_lang) / 2);
> -	lang_lst2 = sdp_data_alloc(SDP_SEQ8, lang_lst);
> -	sdp_attr_add(&record, SDP_ATTR_HID_LANG_ID_BASE_LIST, lang_lst2);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_SDP_DISABLE,
> -						SDP_BOOL, &sdp_disable);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_BATTERY_POWER,
> -						SDP_BOOL, &battery);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_REMOTE_WAKEUP,
> -						SDP_BOOL, &remote_wakeup);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_PROFILE_VERSION,
> -						SDP_UINT16, &profile_version);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_SUPERVISION_TIMEOUT,
> -						SDP_UINT16, &superv_timeout);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_NORMALLY_CONNECTABLE,
> -						SDP_BOOL, &norm_connect);
> -
> -	sdp_attr_add_new(&record, SDP_ATTR_HID_BOOT_DEVICE,
> -						SDP_BOOL, &boot_device);
> -
> -	if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("Wii-Mote service registered\n");
> -
> -	return 0;
> -}
> -
> -static int add_cip(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, l2cap, cmtp, cip;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint16_t psm = si->psm ? si->psm : 0x1001;
> -	uint8_t netid = si->network ? si->network : 0x02; // 0x02 = ISDN, 0x03 = GSM
> -	sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&cip, CIP_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &cip);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, CIP_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile[0]);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap);
> -	apseq = sdp_list_append(0, proto[0]);
> -	proto[0] = sdp_list_append(proto[0], sdp_data_alloc(SDP_UINT16, &psm));
> -	apseq = sdp_list_append(apseq, proto[0]);
> -
> -	sdp_uuid16_create(&cmtp, CMTP_UUID);
> -	proto[1] = sdp_list_append(0, &cmtp);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network);
> -
> -	sdp_set_info_attr(&record, "Common ISDN Access", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("CIP service registered\n");
> -
> -end:
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -	sdp_data_free(network);
> -
> -	return ret;
> -}
> -
> -static int add_ctp(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, l2cap, tcsbin, ctp;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	uint8_t netid = si->network ? si->network : 0x02; // 0x01-0x07 cf. p120 profile document
> -	sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&ctp, CORDLESS_TELEPHONY_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &ctp);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, CORDLESS_TELEPHONY_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile[0]);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&tcsbin, TCS_BIN_UUID);
> -	proto[1] = sdp_list_append(0, &tcsbin);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network);
> -
> -	sdp_set_info_attr(&record, "Cordless Telephony", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto end;
> -	}
> -
> -	printf("CTP service registered\n");
> -
> -end:
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -	sdp_data_free(network);
> -
> -	return ret;
> -}
> -
> -static int add_a2source(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, l2cap, avdtp, a2src;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	sdp_data_t *psm, *version;
> -	uint16_t lp = 0x0019, ver = 0x0100;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &a2src);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile[0]);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap);
> -	psm = sdp_data_alloc(SDP_UINT16, &lp);
> -	proto[0] = sdp_list_append(proto[0], psm);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&avdtp, AVDTP_UUID);
> -	proto[1] = sdp_list_append(0, &avdtp);
> -	version = sdp_data_alloc(SDP_UINT16, &ver);
> -	proto[1] = sdp_list_append(proto[1], version);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Audio Source", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto done;
> -	}
> -
> -	printf("Audio source service registered\n");
> -
> -done:
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_a2sink(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, l2cap, avdtp, a2snk;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	sdp_data_t *psm, *version;
> -	uint16_t lp = 0x0019, ver = 0x0100;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&a2snk, AUDIO_SINK_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &a2snk);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile[0]);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap);
> -	psm = sdp_data_alloc(SDP_UINT16, &lp);
> -	proto[0] = sdp_list_append(proto[0], psm);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&avdtp, AVDTP_UUID);
> -	proto[1] = sdp_list_append(0, &avdtp);
> -	version = sdp_data_alloc(SDP_UINT16, &ver);
> -	proto[1] = sdp_list_append(proto[1], version);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Audio Sink", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto done;
> -	}
> -
> -	printf("Audio sink service registered\n");
> -
> -done:
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_avrct(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, l2cap, avctp, avrct;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	sdp_data_t *psm, *version, *features;
> -	uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&avrct, AV_REMOTE_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &avrct);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile[0]);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap);
> -	psm = sdp_data_alloc(SDP_UINT16, &lp);
> -	proto[0] = sdp_list_append(proto[0], psm);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&avctp, AVCTP_UUID);
> -	proto[1] = sdp_list_append(0, &avctp);
> -	version = sdp_data_alloc(SDP_UINT16, &ver);
> -	proto[1] = sdp_list_append(proto[1], version);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	features = sdp_data_alloc(SDP_UINT16, &feat);
> -	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
> -
> -	sdp_set_info_attr(&record, "AVRCP CT", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto done;
> -	}
> -
> -	printf("Remote control service registered\n");
> -
> -done:
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_avrtg(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> -	uuid_t root_uuid, l2cap, avctp, avrtg;
> -	sdp_profile_desc_t profile[1];
> -	sdp_list_t *aproto, *proto[2];
> -	sdp_record_t record;
> -	sdp_data_t *psm, *version, *features;
> -	uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f;
> -	int ret = 0;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(0, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&avrtg, AV_REMOTE_TARGET_SVCLASS_ID);
> -	svclass_id = sdp_list_append(0, &avrtg);
> -	sdp_set_service_classes(&record, svclass_id);
> -
> -	sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
> -	profile[0].version = 0x0100;
> -	pfseq = sdp_list_append(0, &profile[0]);
> -	sdp_set_profile_descs(&record, pfseq);
> -
> -	sdp_uuid16_create(&l2cap, L2CAP_UUID);
> -	proto[0] = sdp_list_append(0, &l2cap);
> -	psm = sdp_data_alloc(SDP_UINT16, &lp);
> -	proto[0] = sdp_list_append(proto[0], psm);
> -	apseq = sdp_list_append(0, proto[0]);
> -
> -	sdp_uuid16_create(&avctp, AVCTP_UUID);
> -	proto[1] = sdp_list_append(0, &avctp);
> -	version = sdp_data_alloc(SDP_UINT16, &ver);
> -	proto[1] = sdp_list_append(proto[1], version);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(0, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	features = sdp_data_alloc(SDP_UINT16, &feat);
> -	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
> -
> -	sdp_set_info_attr(&record, "AVRCP TG", 0, 0);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		ret = -1;
> -		goto done;
> -	}
> -
> -	printf("Remote target service registered\n");
> -
> -done:
> -	sdp_list_free(proto[0], 0);
> -	sdp_list_free(proto[1], 0);
> -	sdp_list_free(apseq, 0);
> -	sdp_list_free(aproto, 0);
> -
> -	return ret;
> -}
> -
> -static int add_udi_ue(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *root, *svclass, *proto;
> -	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
> -	uint8_t channel = si->channel ? si->channel: 18;
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -	sdp_list_free(root, NULL);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto = sdp_list_append(proto, sdp_list_append(
> -		sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
> -
> -	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
> -
> -	sdp_uuid16_create(&svclass_uuid, UDI_MT_SVCLASS_ID);
> -	svclass = sdp_list_append(NULL, &svclass_uuid);
> -	sdp_set_service_classes(&record, svclass);
> -	sdp_list_free(svclass, NULL);
> -
> -	sdp_set_info_attr(&record, "UDI UE", NULL, NULL);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("UDI UE service registered\n");
> -
> -	return 0;
> -}
> -
> -static int add_udi_te(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *root, *svclass, *proto;
> -	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
> -	uint8_t channel = si->channel ? si->channel: 19;
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -	sdp_list_free(root, NULL);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto = sdp_list_append(proto, sdp_list_append(
> -		sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
> -
> -	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
> -
> -	sdp_uuid16_create(&svclass_uuid, UDI_TA_SVCLASS_ID);
> -	svclass = sdp_list_append(NULL, &svclass_uuid);
> -	sdp_set_service_classes(&record, svclass);
> -	sdp_list_free(svclass, NULL);
> -
> -	sdp_set_info_attr(&record, "UDI TE", NULL, NULL);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("UDI TE service registered\n");
> -
> -	return 0;
> -}
> -
> static unsigned char sr1_uuid[] = {	0xbc, 0x19, 0x9c, 0x24, 0x95, 0x8b, 0x4c, 0xc0,
> 					0xa2, 0xcb, 0xfd, 0x8a, 0x30, 0xbf, 0x32, 0x06 };
> 
> -static int add_sr1(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *root, *svclass;
> -	uuid_t root_uuid, svclass_uuid;
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid128_create(&svclass_uuid, (void *) sr1_uuid);
> -	svclass = sdp_list_append(NULL, &svclass_uuid);
> -	sdp_set_service_classes(&record, svclass);
> -
> -	sdp_set_info_attr(&record, "TOSHIBA SR-1", NULL, NULL);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("Toshiba Speech Recognition SR-1 service record registered\n");
> -
> -	return 0;
> -}
> -
> static unsigned char syncmls_uuid[] = {	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00,
> 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 };
> 
> static unsigned char syncmlc_uuid[] = {	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00,
> 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 };
> 
> -static int add_syncml(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *root, *svclass, *proto;
> -	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
> -	uint8_t channel = si->channel ? si->channel: 15;
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid128_create(&svclass_uuid, (void *) syncmlc_uuid);
> -	svclass = sdp_list_append(NULL, &svclass_uuid);
> -	sdp_set_service_classes(&record, svclass);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto = sdp_list_append(proto, sdp_list_append(
> -		sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
> -
> -	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
> -	proto = sdp_list_append(proto, sdp_list_append(NULL, &obex_uuid));
> -
> -	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
> -
> -	sdp_set_info_attr(&record, "SyncML Client", NULL, NULL);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("SyncML Client service record registered\n");
> -
> -	return 0;
> -}
> -
> static unsigned char async_uuid[] = {	0x03, 0x50, 0x27, 0x8F, 0x3D, 0xCA, 0x4E, 0x62,
> 					0x83, 0x1D, 0xA4, 0x11, 0x65, 0xFF, 0x90, 0x6C };
> 
> -static int add_activesync(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *root, *svclass, *proto;
> -	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
> -	uint8_t channel = si->channel ? si->channel: 21;
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto = sdp_list_append(proto, sdp_list_append(
> -	sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
> -
> -	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
> -
> -	sdp_uuid128_create(&svclass_uuid, (void *) async_uuid);
> -	svclass = sdp_list_append(NULL, &svclass_uuid);
> -	sdp_set_service_classes(&record, svclass);
> -
> -	sdp_set_info_attr(&record, "Microsoft ActiveSync", NULL, NULL);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("ActiveSync service record registered\n");
> -
> -	return 0;
> -}
> -
> static unsigned char hotsync_uuid[] = {	0xD8, 0x0C, 0xF9, 0xEA, 0x13, 0x4C, 0x11, 0xD5,
> 					0x83, 0xCE, 0x00, 0x30, 0x65, 0x7C, 0x54, 0x3C };
> 
> -static int add_hotsync(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *root, *svclass, *proto;
> -	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
> -	uint8_t channel = si->channel ? si->channel: 22;
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto = sdp_list_append(proto, sdp_list_append(
> -	sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
> -
> -	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
> -
> -	sdp_uuid128_create(&svclass_uuid, (void *) hotsync_uuid);
> -	svclass = sdp_list_append(NULL, &svclass_uuid);
> -	sdp_set_service_classes(&record, svclass);
> -
> -	sdp_set_info_attr(&record, "PalmOS HotSync", NULL, NULL);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("HotSync service record registered\n");
> -
> -	return 0;
> -}
> -
> static unsigned char palmos_uuid[] = {	0xF5, 0xBE, 0xB6, 0x51, 0x41, 0x71, 0x40, 0x51,
> 					0xAC, 0xF5, 0x6C, 0xA7, 0x20, 0x22, 0x42, 0xF0 };
> 
> -static int add_palmos(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *root, *svclass;
> -	uuid_t root_uuid, svclass_uuid;
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid128_create(&svclass_uuid, (void *) palmos_uuid);
> -	svclass = sdp_list_append(NULL, &svclass_uuid);
> -	sdp_set_service_classes(&record, svclass);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("PalmOS service record registered\n");
> -
> -	return 0;
> -}
> -
> static unsigned char nokid_uuid[] = {	0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x10, 0x00,
> 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 };
> 
> -static int add_nokiaid(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *root, *svclass;
> -	uuid_t root_uuid, svclass_uuid;
> -	uint16_t verid = 0x005f;
> -	sdp_data_t *version = sdp_data_alloc(SDP_UINT16, &verid);
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid128_create(&svclass_uuid, (void *) nokid_uuid);
> -	svclass = sdp_list_append(NULL, &svclass_uuid);
> -	sdp_set_service_classes(&record, svclass);
> -
> -	sdp_attr_add(&record, SDP_ATTR_SERVICE_VERSION, version);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		sdp_data_free(version);
> -		return -1;
> -	}
> -
> -	printf("Nokia ID service record registered\n");
> -
> -	return 0;
> -}
> -
> static unsigned char pcsuite_uuid[] = {	0x00, 0x00, 0x50, 0x02, 0x00, 0x00, 0x10, 0x00,
> 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 };
> 
> -static int add_pcsuite(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *root, *svclass, *proto;
> -	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
> -	uint8_t channel = si->channel ? si->channel: 14;
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto = sdp_list_append(proto, sdp_list_append(
> -		sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
> -
> -	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
> -
> -	sdp_uuid128_create(&svclass_uuid, (void *) pcsuite_uuid);
> -	svclass = sdp_list_append(NULL, &svclass_uuid);
> -	sdp_set_service_classes(&record, svclass);
> -
> -	sdp_set_info_attr(&record, "Nokia PC Suite", NULL, NULL);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("Nokia PC Suite service registered\n");
> -
> -	return 0;
> -}
> -
> static unsigned char nftp_uuid[] = {	0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x10, 0x00,
> 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 };
> 
> @@ -3302,436 +1184,69 @@ static unsigned char apple_uuid[] = {	0xf0, 0x72, 0x2e, 0x20, 0x0f, 0x8b, 0x4e,
> static unsigned char iap_uuid[] = {	0x00, 0x00, 0x00, 0x00, 0xde, 0xca, 0xfa, 0xde,
> 					0xde, 0xca, 0xde, 0xaf, 0xde, 0xca, 0xca, 0xfe };
> 
> -static int add_apple(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *root;
> -	uuid_t root_uuid;
> -	uint32_t attr783 = 0x00000000;
> -	uint32_t attr785 = 0x00000002;
> -	uint16_t attr786 = 0x1234;
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_attr_add_new(&record, 0x0780, SDP_UUID128, (void *) apple_uuid);
> -	sdp_attr_add_new(&record, 0x0781, SDP_TEXT_STR8, (void *) "Macmini");
> -	sdp_attr_add_new(&record, 0x0782, SDP_TEXT_STR8, (void *) "PowerMac10,1");
> -	sdp_attr_add_new(&record, 0x0783, SDP_UINT32, (void *) &attr783);
> -	sdp_attr_add_new(&record, 0x0784, SDP_TEXT_STR8, (void *) "1.6.6f22");
> -	sdp_attr_add_new(&record, 0x0785, SDP_UINT32, (void *) &attr785);
> -	sdp_attr_add_new(&record, 0x0786, SDP_UUID16, (void *) &attr786);
> -
> -	sdp_set_info_attr(&record, "Apple Macintosh Attributes", NULL, NULL);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("Apple attribute service registered\n");
> -
> -	return 0;
> -}
> -
> -static int add_isync(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_list_t *root, *svclass, *proto;
> -	uuid_t root_uuid, svclass_uuid, serial_uuid, l2cap_uuid, rfcomm_uuid;
> -	uint8_t channel = si->channel ? si->channel : 16;
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
> -
> -	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> -	proto = sdp_list_append(proto, sdp_list_append(
> -		sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
> -
> -	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
> -
> -	sdp_uuid16_create(&serial_uuid, SERIAL_PORT_SVCLASS_ID);
> -	svclass = sdp_list_append(NULL, &serial_uuid);
> -
> -	sdp_uuid16_create(&svclass_uuid, APPLE_AGENT_SVCLASS_ID);
> -	svclass = sdp_list_append(svclass, &svclass_uuid);
> -
> -	sdp_set_service_classes(&record, svclass);
> -
> -	sdp_set_info_attr(&record, "AppleAgent", "Bluetooth acceptor", "Apple Computer Ltd.");
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	printf("Apple iSync service registered\n");
> -
> -	return 0;
> -}
> -
> -static int add_semchla(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_record_t record;
> -	sdp_profile_desc_t profile;
> -	sdp_list_t *root, *svclass, *proto, *profiles;
> -	uuid_t root_uuid, service_uuid, l2cap_uuid, semchla_uuid;
> -	uint16_t psm = 0xf0f9;
> -
> -	memset(&record, 0, sizeof(record));
> -	record.handle = si->handle;
> -
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -
> -	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> -	proto = sdp_list_append(NULL, sdp_list_append(
> -		sdp_list_append(NULL, &l2cap_uuid), sdp_data_alloc(SDP_UINT16, &psm)));
> -
> -	sdp_uuid32_create(&semchla_uuid, 0x8e770300);
> -	proto = sdp_list_append(proto, sdp_list_append(NULL, &semchla_uuid));
> -
> -	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
> -
> -	sdp_uuid32_create(&service_uuid, 0x8e771301);
> -	svclass = sdp_list_append(NULL, &service_uuid);
> -
> -	sdp_set_service_classes(&record, svclass);
> -
> -	sdp_uuid32_create(&profile.uuid, 0x8e771302);	// Headset
> -	//sdp_uuid32_create(&profile.uuid, 0x8e771303);	// Phone
> -	profile.version = 0x0100;
> -	profiles = sdp_list_append(NULL, &profile);
> -	sdp_set_profile_descs(&record, profiles);
> -
> -	sdp_set_info_attr(&record, "SEMC HLA", NULL, NULL);
> -
> -	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
> -		printf("Service Record registration failed\n");
> -		return -1;
> -	}
> -
> -	/* SEMC High Level Authentication */
> -	printf("SEMC HLA service registered\n");
> -
> -	return 0;
> -}
> -
> -static int add_gatt(sdp_session_t *session, svc_info_t *si)
> -{
> -	sdp_list_t *svclass_id, *apseq, *proto[2], *profiles, *root, *aproto;
> -	uuid_t root_uuid, proto_uuid, gatt_uuid, l2cap;
> -	sdp_profile_desc_t profile;
> -	sdp_record_t record;
> -	sdp_data_t *psm, *sh, *eh;
> -	uint16_t att_psm = 27, start = 0x0001, end = 0x000f;
> -	int ret;
> -
> -	memset(&record, 0, sizeof(sdp_record_t));
> -	record.handle = si->handle;
> -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> -	root = sdp_list_append(NULL, &root_uuid);
> -	sdp_set_browse_groups(&record, root);
> -	sdp_list_free(root, NULL);
> -
> -	sdp_uuid16_create(&gatt_uuid, GENERIC_ATTRIB_SVCLASS_ID);
> -	svclass_id = sdp_list_append(NULL, &gatt_uuid);
> -	sdp_set_service_classes(&record, svclass_id);
> -	sdp_list_free(svclass_id, NULL);
> -
> -	sdp_uuid16_create(&profile.uuid, GENERIC_ATTRIB_PROFILE_ID);
> -	profile.version = 0x0100;
> -	profiles = sdp_list_append(NULL, &profile);
> -	sdp_set_profile_descs(&record, profiles);
> -	sdp_list_free(profiles, NULL);
> -
> -	sdp_uuid16_create(&l2cap, L2CAP_UUID);
> -	proto[0] = sdp_list_append(NULL, &l2cap);
> -	psm = sdp_data_alloc(SDP_UINT16, &att_psm);
> -	proto[0] = sdp_list_append(proto[0], psm);
> -	apseq = sdp_list_append(NULL, proto[0]);
> -
> -	sdp_uuid16_create(&proto_uuid, ATT_UUID);
> -	proto[1] = sdp_list_append(NULL, &proto_uuid);
> -	sh = sdp_data_alloc(SDP_UINT16, &start);
> -	proto[1] = sdp_list_append(proto[1], sh);
> -	eh = sdp_data_alloc(SDP_UINT16, &end);
> -	proto[1] = sdp_list_append(proto[1], eh);
> -	apseq = sdp_list_append(apseq, proto[1]);
> -
> -	aproto = sdp_list_append(NULL, apseq);
> -	sdp_set_access_protos(&record, aproto);
> -
> -	sdp_set_info_attr(&record, "Generic Attribute Profile", "BlueZ", NULL);
> -
> -	sdp_set_url_attr(&record, "http://www.bluez.org/",
> -			"http://www.bluez.org/", "http://www.bluez.org/");
> -
> -	sdp_set_service_id(&record, gatt_uuid);
> -
> -	ret = sdp_device_record_register(session, &interface, &record,
> -							SDP_RECORD_PERSIST);
> -	if (ret < 0)
> -		printf("Service Record registration failed\n");
> -	else
> -		printf("Generic Attribute Profile Service registered\n");
> -
> -	sdp_data_free(psm);
> -	sdp_data_free(sh);
> -	sdp_data_free(eh);
> -	sdp_list_free(proto[0], NULL);
> -	sdp_list_free(proto[1], NULL);
> -	sdp_list_free(apseq, NULL);
> -	sdp_list_free(aproto, NULL);
> -
> -	return ret;
> -}
> -
> struct {
> 	char		*name;
> 	uint32_t	class;
> -	int		(*add)(sdp_session_t *sess, svc_info_t *si);
> 	unsigned char *uuid;
> } service[] = {
> -	{ "DID",	PNP_INFO_SVCLASS_ID,		NULL,		},
> -
> -	{ "SP",		SERIAL_PORT_SVCLASS_ID,		add_sp		},
> -	{ "DUN",	DIALUP_NET_SVCLASS_ID,		add_dun		},
> -	{ "LAN",	LAN_ACCESS_SVCLASS_ID,		add_lan		},
> -	{ "FAX",	FAX_SVCLASS_ID,			add_fax		},
> -	{ "OPUSH",	OBEX_OBJPUSH_SVCLASS_ID,	add_opush	},
> -	{ "FTP",	OBEX_FILETRANS_SVCLASS_ID,	add_ftp		},
> -	{ "PRINT",	DIRECT_PRINTING_SVCLASS_ID,	add_directprint	},
> -
> -	{ "HS",		HEADSET_SVCLASS_ID,		add_headset	},
> -	{ "HSAG",	HEADSET_AGW_SVCLASS_ID,		add_headset_ag	},
> -	{ "HF",		HANDSFREE_SVCLASS_ID,		add_handsfree	},
> -	{ "HFAG",	HANDSFREE_AGW_SVCLASS_ID,	add_handsfree_ag},
> -	{ "SAP",	SAP_SVCLASS_ID,			add_simaccess	},
> -	{ "PBAP",	PBAP_SVCLASS_ID,		add_pbap,	},
> -
> -	{ "NAP",	NAP_SVCLASS_ID,			add_nap		},
> -	{ "GN",		GN_SVCLASS_ID,			add_gn		},
> -	{ "PANU",	PANU_SVCLASS_ID,		add_panu	},
> -
> -	{ "HCRP",	HCR_SVCLASS_ID,			NULL		},
> -	{ "HID",	HID_SVCLASS_ID,			NULL		},
> -	{ "KEYB",	HID_SVCLASS_ID,			add_hid_keyb	},
> -	{ "WIIMOTE",	HID_SVCLASS_ID,			add_hid_wiimote	},
> -	{ "CIP",	CIP_SVCLASS_ID,			add_cip		},
> -	{ "CTP",	CORDLESS_TELEPHONY_SVCLASS_ID,	add_ctp		},
> -
> -	{ "A2SRC",	AUDIO_SOURCE_SVCLASS_ID,	add_a2source	},
> -	{ "A2SNK",	AUDIO_SINK_SVCLASS_ID,		add_a2sink	},
> -	{ "AVRCT",	AV_REMOTE_SVCLASS_ID,		add_avrct	},
> -	{ "AVRTG",	AV_REMOTE_TARGET_SVCLASS_ID,	add_avrtg	},
> -
> -	{ "UDIUE",	UDI_MT_SVCLASS_ID,		add_udi_ue	},
> -	{ "UDITE",	UDI_TA_SVCLASS_ID,		add_udi_te	},
> -
> -	{ "SEMCHLA",	0x8e771301,			add_semchla	},
> -
> -	{ "SR1",	0,				add_sr1,	sr1_uuid	},
> -	{ "SYNCML",	0,				add_syncml,	syncmlc_uuid	},
> -	{ "SYNCMLSERV",	0,				NULL,		syncmls_uuid	},
> -	{ "ACTIVESYNC",	0,				add_activesync,	async_uuid	},
> -	{ "HOTSYNC",	0,				add_hotsync,	hotsync_uuid	},
> -	{ "PALMOS",	0,				add_palmos,	palmos_uuid	},
> -	{ "NOKID",	0,				add_nokiaid,	nokid_uuid	},
> -	{ "PCSUITE",	0,				add_pcsuite,	pcsuite_uuid	},
> -	{ "NFTP",	0,				NULL,		nftp_uuid	},
> -	{ "NSYNCML",	0,				NULL,		nsyncml_uuid	},
> -	{ "NGAGE",	0,				NULL,		ngage_uuid	},
> -	{ "APPLE",	0,				add_apple,	apple_uuid	},
> -	{ "IAP",	0,				NULL,		iap_uuid	},
> -
> -	{ "ISYNC",	APPLE_AGENT_SVCLASS_ID,		add_isync,	},
> -	{ "GATT",	GENERIC_ATTRIB_SVCLASS_ID,	add_gatt,	},
> +	{ "DID",	PNP_INFO_SVCLASS_ID		},
> +
> +	{ "SP",		SERIAL_PORT_SVCLASS_ID		},
> +	{ "DUN",	DIALUP_NET_SVCLASS_ID		},
> +	{ "LAN",	LAN_ACCESS_SVCLASS_ID		},
> +	{ "FAX",	FAX_SVCLASS_ID			},
> +	{ "OPUSH",	OBEX_OBJPUSH_SVCLASS_ID		},
> +	{ "FTP",	OBEX_FILETRANS_SVCLASS_ID	},
> +	{ "PRINT",	DIRECT_PRINTING_SVCLASS_ID	},
> +
> +	{ "HS",		HEADSET_SVCLASS_ID		},
> +	{ "HSAG",	HEADSET_AGW_SVCLASS_ID		},
> +	{ "HF",		HANDSFREE_SVCLASS_ID		},
> +	{ "HFAG",	HANDSFREE_AGW_SVCLASS_ID	},
> +	{ "SAP",	SAP_SVCLASS_ID			},
> +	{ "PBAP",	PBAP_SVCLASS_ID			},
> +
> +	{ "NAP",	NAP_SVCLASS_ID			},
> +	{ "GN",		GN_SVCLASS_ID			},
> +	{ "PANU",	PANU_SVCLASS_ID			},
> +
> +	{ "HCRP",	HCR_SVCLASS_ID			},
> +	{ "HID",	HID_SVCLASS_ID			},
> +	{ "KEYB",	HID_SVCLASS_ID			},
> +	{ "WIIMOTE",	HID_SVCLASS_ID			},
> +	{ "CIP",	CIP_SVCLASS_ID			},
> +	{ "CTP",	CORDLESS_TELEPHONY_SVCLASS_ID	},
> +
> +	{ "A2SRC",	AUDIO_SOURCE_SVCLASS_ID		},
> +	{ "A2SNK",	AUDIO_SINK_SVCLASS_ID		},
> +	{ "AVRCT",	AV_REMOTE_SVCLASS_ID		},
> +	{ "AVRTG",	AV_REMOTE_TARGET_SVCLASS_ID	},
> +
> +	{ "UDIUE",	UDI_MT_SVCLASS_ID		},
> +	{ "UDITE",	UDI_TA_SVCLASS_ID		},
> +
> +	{ "SEMCHLA",	0x8e771301			},
> +
> +	{ "SR1",	0,				sr1_uuid	},
> +	{ "SYNCML",	0,				syncmlc_uuid	},
> +	{ "SYNCMLSERV",	0,				syncmls_uuid	},
> +	{ "ACTIVESYNC",	0,				async_uuid	},
> +	{ "HOTSYNC",	0,				hotsync_uuid	},
> +	{ "PALMOS",	0,				palmos_uuid	},
> +	{ "NOKID",	0,				nokid_uuid	},
> +	{ "PCSUITE",	0,				pcsuite_uuid	},
> +	{ "NFTP",	0,				nftp_uuid	},
> +	{ "NSYNCML",	0,				nsyncml_uuid	},
> +	{ "NGAGE",	0,				ngage_uuid	},
> +	{ "APPLE",	0,				apple_uuid	},
> +	{ "IAP",	0,				iap_uuid	},
> +
> +	{ "ISYNC",	APPLE_AGENT_SVCLASS_ID		},
> +	{ "GATT",	GENERIC_ATTRIB_SVCLASS_ID	},
> 
> 	{ 0 }
> };
> 
> -/* Add local service */
> -static int add_service(bdaddr_t *bdaddr, svc_info_t *si)
> -{
> -	sdp_session_t *sess;
> -	int i, ret = -1;
> -
> -	if (!si->name)
> -		return -1;
> -
> -	sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
> -	if (!sess)
> -		return -1;
> -
> -	for (i = 0; service[i].name; i++)
> -		if (!strcasecmp(service[i].name, si->name)) {
> -			if (service[i].add)
> -				ret = service[i].add(sess, si);
> -			goto done;
> -		}
> -
> -	printf("Unknown service name: %s\n", si->name);
> -
> -done:
> -	free(si->name);
> -	sdp_close(sess);
> -
> -	return ret;
> -}
> -
> -static struct option add_options[] = {
> -	{ "help",	0, 0, 'h' },
> -	{ "handle",	1, 0, 'r' },
> -	{ "psm",	1, 0, 'p' },
> -	{ "channel",	1, 0, 'c' },
> -	{ "network",	1, 0, 'n' },
> -	{ 0, 0, 0, 0 }
> -};
> -
> -static const char *add_help =
> -	"Usage:\n"
> -	"\tadd [--handle=RECORD_HANDLE --channel=CHANNEL] service\n";
> -
> -static int cmd_add(int argc, char **argv)
> -{
> -	svc_info_t si;
> -	int opt;
> -
> -	memset(&si, 0, sizeof(si));
> -	si.handle = 0xffffffff;
> -
> -	for_each_opt(opt, add_options, 0) {
> -		switch (opt) {
> -		case 'r':
> -			if (strncasecmp(optarg, "0x", 2))
> -				si.handle = atoi(optarg);
> -			else
> -				si.handle = strtol(optarg + 2, NULL, 16);
> -			break;
> -		case 'p':
> -			if (strncasecmp(optarg, "0x", 2))
> -				si.psm = atoi(optarg);
> -			else
> -				si.psm = strtol(optarg + 2, NULL, 16);
> -			break;
> -		case 'c':
> -			if (strncasecmp(optarg, "0x", 2))
> -				si.channel = atoi(optarg);
> -			else
> -				si.channel = strtol(optarg + 2, NULL, 16);
> -			break;
> -		case 'n':
> -			if (strncasecmp(optarg, "0x", 2))
> -				si.network = atoi(optarg);
> -			else
> -				si.network = strtol(optarg + 2, NULL, 16);
> -			break;
> -		default:
> -			printf("%s", add_help);
> -			return -1;
> -		}
> -	}
> -
> -	argc -= optind;
> -	argv += optind;
> -
> -	if (argc < 1) {
> -		printf("%s", add_help);
> -		return -1;
> -	}
> -
> -	si.name = strdup(argv[0]);
> -
> -	return add_service(0, &si);
> -}
> -
> -/* Delete local service */
> -static int del_service(bdaddr_t *bdaddr, void *arg)
> -{
> -	uint32_t handle, range = 0x0000ffff;
> -	sdp_list_t *attr;
> -	sdp_session_t *sess;
> -	sdp_record_t *rec;
> -
> -	if (!arg) {
> -		printf("Record handle was not specified.\n");
> -		return -1;
> -	}
> -
> -	sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
> -	if (!sess) {
> -		printf("No local SDP server!\n");
> -		return -1;
> -	}
> -
> -	handle = strtoul((char *)arg, 0, 16);
> -	attr = sdp_list_append(0, &range);
> -	rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attr);
> -	sdp_list_free(attr, 0);
> -
> -	if (!rec) {
> -		printf("Service Record not found.\n");
> -		sdp_close(sess);
> -		return -1;
> -	}
> -
> -	if (sdp_device_record_unregister(sess, &interface, rec)) {
> -		printf("Failed to unregister service record: %s\n", strerror(errno));
> -		sdp_close(sess);
> -		return -1;
> -	}
> -
> -	printf("Service Record deleted.\n");
> -	sdp_close(sess);
> -
> -	return 0;
> -}
> -
> -static struct option del_options[] = {
> -	{ "help",	0, 0, 'h' },
> -	{ 0, 0, 0, 0 }
> -};
> -
> -static const char *del_help =
> -	"Usage:\n"
> -	"\tdel record_handle\n";
> -
> -static int cmd_del(int argc, char **argv)
> -{
> -	int opt;
> -
> -	for_each_opt(opt, del_options, 0) {
> -		switch (opt) {
> -		default:
> -			printf("%s", del_help);
> -			return -1;
> -		}
> -	}
> -
> -	argc -= optind;
> -	argv += optind;
> -
> -	if (argc < 1) {
> -		printf("%s", del_help);
> -		return -1;
> -	}
> -
> -	return del_service(NULL, argv[0]);
> -}
> -
> /*
>  * Perform an inquiry and search/browse all peer found.
>  */
> @@ -4203,8 +1718,6 @@ static struct {
> 	{ "search",  cmd_search,      "Search for a service"          },
> 	{ "browse",  cmd_browse,      "Browse all available services" },
> 	{ "records", cmd_records,     "Request all records"           },
> -	{ "add",     cmd_add,         "Add local service"             },
> -	{ "del",     cmd_del,         "Delete local service"          },
> 	{ "get",     cmd_get,         "Get local service"             },
> 	{ "setattr", cmd_setattr,     "Set/Add attribute to a SDP record"          },
> 	{ "setseq",  cmd_setseq,      "Set/Add attribute sequence to a SDP record" },
> -- 
> 1.8.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply

* Re: [PATCH v2 6/8] sdpd: Remove 'register' and 'remove' requests
From: Marcel Holtmann @ 2013-09-21 17:25 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1379599248-7923-7-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

> sdpd is now controlled by adapters and should not be modified with
> other means.
> ---
> src/sdpd-request.c |  14 --------
> src/sdpd-service.c | 100 -----------------------------------------------------
> src/sdpd.h         |   2 --
> 3 files changed, 116 deletions(-)
> 
> diff --git a/src/sdpd-request.c b/src/sdpd-request.c
> index fbeb488..5b88a10 100644
> --- a/src/sdpd-request.c
> +++ b/src/sdpd-request.c
> @@ -997,13 +997,6 @@ static void process_request(sdp_req_t *req)
> 		rsphdr->pdu_id = SDP_SVC_SEARCH_ATTR_RSP;
> 		break;
> 	/* Following requests are allowed only for local connections */
> -	case SDP_SVC_REGISTER_REQ:
> -		SDPDBG("Service register request");
> -		if (req->local) {
> -			status = service_register_req(req, &rsp);
> -			rsphdr->pdu_id = SDP_SVC_REGISTER_RSP;
> -		}
> -		break;
> 	case SDP_SVC_UPDATE_REQ:
> 		SDPDBG("Service update request");
> 		if (req->local) {
> @@ -1011,13 +1004,6 @@ static void process_request(sdp_req_t *req)
> 			rsphdr->pdu_id = SDP_SVC_UPDATE_RSP;
> 		}
> 		break;
> -	case SDP_SVC_REMOVE_REQ:
> -		SDPDBG("Service removal request");
> -		if (req->local) {
> -			status = service_remove_req(req, &rsp);
> -			rsphdr->pdu_id = SDP_SVC_REMOVE_RSP;
> -		}
> -		break;

we can not take these out. We need a way to pass qualification.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH v3 8/8] sdp: Decouple Device ID profile implementation
From: Marcel Holtmann @ 2013-09-21 17:23 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1379599910-8666-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

> Make DeviceID profile similar to other profiles implementations. Use
> btd_profile for handling DeviceID profile while adding/removing
> adapters. The nice drawback is that SDP code no longer depends on
> main_opts.
> ---
> 
> Fixed missing g_slist_remove.
> 
> Makefile.plugins             |   3 +
> profiles/deviceid/deviceid.c | 189 +++++++++++++++++++++++++++++++++++++++++++
> src/adapter.c                |  26 +++---
> src/adapter.h                |   3 +
> src/sdpd-server.c            |   4 -
> src/sdpd-service.c           |  58 -------------
> src/sdpd.h                   |   2 -
> 7 files changed, 206 insertions(+), 79 deletions(-)
> create mode 100644 profiles/deviceid/deviceid.c

please do not intermix profiles/ code with src/ code in the same commit.

Regards

Marcel


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox