Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH 00/11] Use devm_kzalloc in bluetooth drivers
From: Marcel Holtmann @ 2012-08-06 16:37 UTC (permalink / raw)
  To: Sachin Kamat; +Cc: linux-bluetooth, gustavo, johan.hedberg, patches
In-Reply-To: <CAK9yfHynuNNqYccAp4BC9zAtWE_Ni27tEK-Pq2Ngt6N2PZukRw@mail.gmail.com>

Hi Sachin,

> Any comments regarding this patch set?

I am fine with it.

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

Regards

Marcel



^ permalink raw reply

* Re: [RFCv0 06/21] Bluetooth: Channel move request handling
From: Mat Martineau @ 2012-08-06 16:33 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth, gustavo, pkrystad
In-Reply-To: <20120806084435.GA2819@aemeltch-MOBL1>


On Mon, 6 Aug 2012, Andrei Emeltchenko wrote:

> Hi Mat,
>
> On Fri, Jul 27, 2012 at 09:54:03AM -0700, Mat Martineau wrote:
>
> ...
>
>>>> +	if (chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY) {
>>>> +		result = L2CAP_MR_NOT_ALLOWED;
>>>> +		goto send_move_response;
>>>> +	}
>>>> +
>>>> +	chan->move_cmd_ident = cmd->ident;
>>>
>>> BTW: Why do we handle ident in a special way for channel move?
>>
>> At the time I wrote the code, I thought that chan->ident was only
>> used to store idents of sent requests, not received requests.  But
>> it does look like it is also used for storing received idents for
>> use in sending responses.  chan->ident could be used as long as move
>> collisions are handled correctly (where a move request is received
>> when a move response is expected).
>
> So can we use chan->ident instead of chan->move_cmd_ident? Is the channel
> move somehow different from other L2CAP request / response sequence?

Yes, chan->ident can be used.  It doesn't seem necessary to assign 
chan->ident when sending a move request, just when receiving one.

Connect and create requests also assign chan->ident when they are 
sent, but I'm not sure why.

--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum


^ permalink raw reply

* Re: [PATCH 00/11] Use devm_kzalloc in bluetooth drivers
From: Sachin Kamat @ 2012-08-06 16:08 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, johan.hedberg, sachin.kamat, patches
In-Reply-To: <1343372921-18780-1-git-send-email-sachin.kamat@linaro.org>

Hi,

Any comments regarding this patch set?

On 27 July 2012 12:38, Sachin Kamat <sachin.kamat@linaro.org> wrote:
> devm_kzalloc() is a device managed function which eliminates the need
> to free memory explicitly thereby saving some cleanup code and making
> the exit code simpler.
>
> This series is based on the following tree and is compile tested.
> git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git
>
> Sachin Kamat (11):
>   Bluetooth: Use devm_kzalloc in bcm203x.c file.
>   Bluetooth: Use devm_kzalloc in bfusb.c file
>   Bluetooth: Use devm_kzalloc in bluecard_cs.c file
>   Bluetooth: Use devm_kzalloc in bpa10x.c file
>   Bluetooth: Use devm_kzalloc in bt3c_cs.c file
>   Bluetooth: Use devm_kzalloc in btmrvl_sdio.c file
>   Bluetooth: Use devm_kzalloc in btsdio.c file
>   Bluetooth: Use devm_kzalloc in btuart_cs.c file
>   Bluetooth: Use devm_kzalloc in btusb.c file
>   Bluetooth: Use devm_kzalloc in btwilink.c file
>   Bluetooth: Use devm_kzalloc in dtl1_cs.c file
>
>  drivers/bluetooth/bcm203x.c     |    8 +-------
>  drivers/bluetooth/bfusb.c       |   12 ++++--------
>  drivers/bluetooth/bluecard_cs.c |    5 +----
>  drivers/bluetooth/bpa10x.c      |    8 ++------
>  drivers/bluetooth/bt3c_cs.c     |    5 +----
>  drivers/bluetooth/btmrvl_sdio.c |   15 ++++-----------
>  drivers/bluetooth/btsdio.c      |    8 ++------
>  drivers/bluetooth/btuart_cs.c   |    5 +----
>  drivers/bluetooth/btusb.c       |   13 +++----------
>  drivers/bluetooth/btwilink.c    |    8 ++------
>  drivers/bluetooth/dtl1_cs.c     |    3 +--
>  11 files changed, 22 insertions(+), 68 deletions(-)
>
> --
> 1.7.4.1
>



-- 
With warm regards,
Sachin

^ permalink raw reply

* Re: [PATCH] Bluetooth: debug: Correct the PSM printing
From: Andrei Emeltchenko @ 2012-08-06  9:46 UTC (permalink / raw)
  To: Syam Sidhardhan; +Cc: linux-bluetooth, jaganath.k
In-Reply-To: <1343413282-8901-2-git-send-email-s.syam@samsung.com>

Hi Syam,

On Fri, Jul 27, 2012 at 11:51:22PM +0530, Syam Sidhardhan wrote:
> Earlier we were printing chan->psm before assigning any value.
> 
> Signed-off-by: Syam Sidhardhan <s.syam@samsung.com>

Acked-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com> 

> ---
>  net/bluetooth/l2cap_core.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index bedc960..0912a63 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -1447,7 +1447,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
>  	int err;
>  
>  	BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
> -	       dst_type, __le16_to_cpu(chan->psm));
> +	       dst_type, __le16_to_cpu(psm));
>  
>  	hdev = hci_get_route(dst, src);
>  	if (!hdev)
> -- 
> 1.7.4.1
> 
> --
> 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 BlueZ V2 2/5] AVRCP: Rename variables used for control
From: Vani-dineshbhai PATEL X @ 2012-08-06  8:47 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: User Name, Lucas De Marchi, Joohi RASTOGI, Vani
In-Reply-To: <CABBYNZLY4msobcmFXW+u1gzwrBC-7KgED0VDaJ_2gqF5PZE_kw@mail.gmail.com>

Hi Luiz,

> -----Original Message-----
> From: Luiz Augusto von Dentz [mailto:luiz.dentz@gmail.com]
> Sent: Monday, August 06, 2012 1:51 PM
> To: Vani-dineshbhai PATEL X
> Cc: User Name; Lucas De Marchi; Joohi RASTOGI; Vani
> Subject: Re: [PATCH BlueZ V2 2/5] AVRCP: Rename variables used for control
> 
> Hi Vani,
> 
> On Fri, Aug 3, 2012 at 9:44 AM, Vani-dineshbhai PATEL
> <vani.patel@stericsson.com> wrote:
> > -       err = avctp_send_vendordep(player->session, player-
> >transaction_events[id],
> > +       err = avctp_send_vendordep(player->session,
> > +
> > + player->transaction_events[id],
> >                                         AVC_CTYPE_CHANGED, AVC_SUBUNIT_PANEL,
> >                                         buf, size +
> > AVRCP_HEADER_LENGTH);
> 
> Git complain about this line, apparently you are leaving a whitespace:
> 
> Applying: AVRCP: Rename variables used for control
> /home/vudentz/git/bluez/.git/rebase-apply/patch:390: trailing whitespace.
> 	err = avctp_send_vendordep(player->session,
> fatal: 1 line adds whitespace errors.

Fixed and re-sent the patch.
> 
> >         if (err < 0)
> > @@ -914,7 +915,7 @@ static uint8_t avrcp_handle_get_play_status(struct
> > avrcp_player *player,
> >
> >         memcpy(&pdu->params[0], &duration, 4);
> >         memcpy(&pdu->params[4], &position, 4);
> > -       pdu->params[8] = player->cb->get_status(player->user_data);;
> > +       pdu->params[8] = player->cb->get_status(player->user_data);
> 
> This one should be fixed in separate, it has nothing to do with other changes
> you are introducing and could probably be applied very quickly.
> 

I have removed such changes and re-sent the patch. Will create new patch with such formatting errors.

> --
> Luiz Augusto von Dentz

Thanks & Regards,
Vani

^ permalink raw reply

* [PATCH BlueZ V3 2/5] AVRCP: Rename variables used for control channel to improve  redability
From: Vani-dineshbhai PATEL @ 2012-08-06  8:45 UTC (permalink / raw)
  To: User Name, Luiz Augusto, Lucas De Marchi; +Cc: Vani, Joohi, Vani

From: Vani Patel <vani.patel@stericsson.com>

Prefix "control" is added to variables used for
control channel. This will improve redability
when Browsing channel is implemented
---
 audio/avctp.c |   83 +++++++++++++++++++++++++++++----------------------------
 audio/avctp.h |    5 ++-
 audio/avrcp.c |   54 ++++++++++++++++++------------------
 3 files changed, 72 insertions(+), 70 deletions(-)

diff --git a/audio/avctp.c b/audio/avctp.c
index a20dba9..3bd021c 100644
--- a/audio/avctp.c
+++ b/audio/avctp.c
@@ -118,7 +118,7 @@ struct avctp_state_callback {
 
 struct avctp_server {
 	bdaddr_t src;
-	GIOChannel *io;
+	GIOChannel *control_io;
 	GSList *sessions;
 };
 
@@ -136,10 +136,10 @@ struct avctp {
 
 	int uinput;
 
-	GIOChannel *io;
-	guint io_id;
+	GIOChannel *control_io;
+	guint control_io_id;
 
-	uint16_t mtu;
+	uint16_t control_mtu;
 
 	uint8_t key_quirks[256];
 	GSList *handlers;
@@ -147,7 +147,7 @@ struct avctp {
 
 struct avctp_pdu_handler {
 	uint8_t opcode;
-	avctp_pdu_cb cb;
+	avctp_control_pdu_cb cb;
 	void *user_data;
 	unsigned int id;
 };
@@ -169,7 +169,7 @@ static struct {
 
 static GSList *callbacks = NULL;
 static GSList *servers = NULL;
-static GSList *handlers = NULL;
+static GSList *control_handlers = NULL;
 static uint8_t id = 0;
 
 static void auth_cb(DBusError *derr, void *user_data);
@@ -326,15 +326,15 @@ static void avctp_disconnected(struct avctp *session)
 	if (!session)
 		return;
 
-	if (session->io) {
-		g_io_channel_shutdown(session->io, TRUE, NULL);
-		g_io_channel_unref(session->io);
-		session->io = NULL;
+	if (session->control_io) {
+		g_io_channel_shutdown(session->control_io, TRUE, NULL);
+		g_io_channel_unref(session->control_io);
+		session->control_io = NULL;
 	}
 
-	if (session->io_id) {
-		g_source_remove(session->io_id);
-		session->io_id = 0;
+	if (session->control_io_id) {
+		g_source_remove(session->control_io_id);
+		session->control_io_id = 0;
 
 		if (session->state == AVCTP_STATE_CONNECTING) {
 			struct audio_device *dev;
@@ -445,7 +445,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
 		goto failed;
 
-	sock = g_io_channel_unix_get_fd(session->io);
+	sock = g_io_channel_unix_get_fd(session->control_io);
 
 	ret = read(sock, buf, sizeof(buf));
 	if (ret <= 0)
@@ -503,7 +503,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 		goto done;
 	}
 
-	handler = find_handler(handlers, avc->opcode);
+	handler = find_handler(control_handlers, avc->opcode);
 	if (!handler) {
 		DBG("handler not found for 0x%02x", avc->opcode);
 		packet_size += avrcp_handle_vendor_reject(&code, operands);
@@ -639,14 +639,14 @@ static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)
 
 	DBG("AVCTP: connected to %s", address);
 
-	if (!session->io)
-		session->io = g_io_channel_ref(chan);
+	if (!session->control_io)
+		session->control_io = g_io_channel_ref(chan);
 
 	init_uinput(session);
 
 	avctp_set_state(session, AVCTP_STATE_CONNECTED);
-	session->mtu = imtu;
-	session->io_id = g_io_add_watch(chan,
+	session->control_mtu = imtu;
+	session->control_io_id = g_io_add_watch(chan,
 				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
 				(GIOFunc) session_cb, session);
 }
@@ -656,9 +656,9 @@ static void auth_cb(DBusError *derr, void *user_data)
 	struct avctp *session = user_data;
 	GError *err = NULL;
 
-	if (session->io_id) {
-		g_source_remove(session->io_id);
-		session->io_id = 0;
+	if (session->control_io_id) {
+		g_source_remove(session->control_io_id);
+		session->control_io_id = 0;
 	}
 
 	if (derr && dbus_error_is_set(derr)) {
@@ -667,7 +667,7 @@ static void auth_cb(DBusError *derr, void *user_data)
 		return;
 	}
 
-	if (!bt_io_accept(session->io, avctp_connect_cb, session,
+	if (!bt_io_accept(session->control_io, avctp_connect_cb, session,
 								NULL, &err)) {
 		error("bt_io_accept: %s", err->message);
 		g_error_free(err);
@@ -771,24 +771,24 @@ static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
 			goto drop;
 	}
 
-	if (session->io) {
+	if (session->control_io) {
 		error("Refusing unexpected connect from %s", address);
 		goto drop;
 	}
 
 	avctp_set_state(session, AVCTP_STATE_CONNECTING);
-	session->io = g_io_channel_ref(chan);
+	session->control_io = g_io_channel_ref(chan);
 
 	if (audio_device_request_authorization(dev, AVRCP_TARGET_UUID,
 						auth_cb, session) < 0)
 		goto drop;
 
-	session->io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-							session_cb, session);
+	session->control_io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP |
+						G_IO_NVAL, session_cb, session);
 	return;
 
 drop:
-	if (!session || !session->io)
+	if (!session || !session->control_io)
 		g_io_channel_shutdown(chan, TRUE, NULL);
 	if (session)
 		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
@@ -824,8 +824,8 @@ int avctp_register(const bdaddr_t *src, gboolean master)
 
 	server = g_new0(struct avctp_server, 1);
 
-	server->io = avctp_server_socket(src, master);
-	if (!server->io) {
+	server->control_io = avctp_server_socket(src, master);
+	if (!server->control_io) {
 		g_free(server);
 		return -1;
 	}
@@ -862,8 +862,8 @@ void avctp_unregister(const bdaddr_t *src)
 
 	servers = g_slist_remove(servers, server);
 
-	g_io_channel_shutdown(server->io, TRUE, NULL);
-	g_io_channel_unref(server->io);
+	g_io_channel_shutdown(server->control_io, TRUE, NULL);
+	g_io_channel_unref(server->control_io);
 	g_free(server);
 
 	if (servers)
@@ -910,7 +910,7 @@ int avctp_send_passthrough(struct avctp *session, uint8_t op)
 	operands[0] = op & 0x7f;
 	operands[1] = 0;
 
-	sk = g_io_channel_unix_get_fd(session->io);
+	sk = g_io_channel_unix_get_fd(session->control_io);
 
 	if (write(sk, buf, sizeof(buf)) < 0)
 		return -errno;
@@ -939,7 +939,7 @@ static int avctp_send(struct avctp *session, uint8_t transaction, uint8_t cr,
 	if (session->state != AVCTP_STATE_CONNECTED)
 		return -ENOTCONN;
 
-	sk = g_io_channel_unix_get_fd(session->io);
+	sk = g_io_channel_unix_get_fd(session->control_io);
 
 	memset(buf, 0, sizeof(buf));
 
@@ -1034,13 +1034,13 @@ gboolean avctp_remove_state_cb(unsigned int id)
 	return FALSE;
 }
 
-unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_pdu_cb cb,
+unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_control_pdu_cb cb,
 							void *user_data)
 {
 	struct avctp_pdu_handler *handler;
 	static unsigned int id = 0;
 
-	handler = find_handler(handlers, opcode);
+	handler = find_handler(control_handlers, opcode);
 	if (handler)
 		return 0;
 
@@ -1050,7 +1050,7 @@ unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_pdu_cb cb,
 	handler->user_data = user_data;
 	handler->id = ++id;
 
-	handlers = g_slist_append(handlers, handler);
+	control_handlers = g_slist_append(control_handlers, handler);
 
 	return handler->id;
 }
@@ -1059,11 +1059,12 @@ gboolean avctp_unregister_pdu_handler(unsigned int id)
 {
 	GSList *l;
 
-	for (l = handlers; l != NULL; l = l->next) {
+	for (l = control_handlers; l != NULL; l = l->next) {
 		struct avctp_pdu_handler *handler = l->data;
 
 		if (handler->id == id) {
-			handlers = g_slist_remove(handlers, handler);
+			control_handlers = g_slist_remove(control_handlers,
+								handler);
 			g_free(handler);
 			return TRUE;
 		}
@@ -1099,14 +1100,14 @@ struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst)
 		return NULL;
 	}
 
-	session->io = io;
+	session->control_io = io;
 
 	return session;
 }
 
 void avctp_disconnect(struct avctp *session)
 {
-	if (!session->io)
+	if (!session->control_io)
 		return;
 
 	avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
diff --git a/audio/avctp.h b/audio/avctp.h
index 34b0c1c..b80e300 100644
--- a/audio/avctp.h
+++ b/audio/avctp.h
@@ -75,7 +75,8 @@ typedef void (*avctp_state_cb) (struct audio_device *dev,
 				avctp_state_t new_state,
 				void *user_data);
 
-typedef size_t (*avctp_pdu_cb) (struct avctp *session, uint8_t transaction,
+typedef size_t (*avctp_control_pdu_cb) (struct avctp *session,
+					uint8_t transaction,
 					uint8_t *code, uint8_t *subunit,
 					uint8_t *operands, size_t operand_count,
 					void *user_data);
@@ -93,7 +94,7 @@ struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst);
 struct avctp *avctp_get(const bdaddr_t *src, const bdaddr_t *dst);
 void avctp_disconnect(struct avctp *session);
 
-unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_pdu_cb cb,
+unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_control_pdu_cb cb,
 							void *user_data);
 gboolean avctp_unregister_pdu_handler(unsigned int id);
 
diff --git a/audio/avrcp.c b/audio/avrcp.c
index ca40c1e..9d29073 100644
--- a/audio/avrcp.c
+++ b/audio/avrcp.c
@@ -162,7 +162,7 @@ struct avrcp_player {
 	struct avctp *session;
 	struct audio_device *dev;
 
-	unsigned int handler;
+	unsigned int control_handler;
 	uint16_t registered_events;
 	uint8_t transaction_events[AVRCP_EVENT_LAST + 1];
 	struct pending_pdu *pending_pdu;
@@ -255,9 +255,9 @@ static sdp_record_t *avrcp_tg_record(void)
 	sdp_list_t *svclass_id, *pfseq, *apseq, *root, *apseq_browsing;
 	uuid_t root_uuid, l2cap, avctp, avrtg;
 	sdp_profile_desc_t profile[1];
-	sdp_list_t *aproto, *proto[2];
+	sdp_list_t *aproto_control, *proto_control[2];
 	sdp_record_t *record;
-	sdp_data_t *psm, *version, *features, *psm_browsing;
+	sdp_data_t *psm_control, *version, *features, *psm_browsing;
 	sdp_list_t *aproto_browsing, *proto_browsing[2] = {0};
 	uint16_t lp = AVCTP_CONTROL_PSM;
 	uint16_t lp_browsing = AVCTP_BROWSING_PSM;
@@ -283,19 +283,19 @@ static sdp_record_t *avrcp_tg_record(void)
 
 	/* Protocol Descriptor List */
 	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]);
+	proto_control[0] = sdp_list_append(0, &l2cap);
+	psm_control = sdp_data_alloc(SDP_UINT16, &lp);
+	proto_control[0] = sdp_list_append(proto_control[0], psm_control);
+	apseq = sdp_list_append(0, proto_control[0]);
 
 	sdp_uuid16_create(&avctp, AVCTP_UUID);
-	proto[1] = sdp_list_append(0, &avctp);
+	proto_control[1] = sdp_list_append(0, &avctp);
 	version = sdp_data_alloc(SDP_UINT16, &avctp_ver);
-	proto[1] = sdp_list_append(proto[1], version);
-	apseq = sdp_list_append(apseq, proto[1]);
+	proto_control[1] = sdp_list_append(proto_control[1], version);
+	apseq = sdp_list_append(apseq, proto_control[1]);
 
-	aproto = sdp_list_append(0, apseq);
-	sdp_set_access_protos(record, aproto);
+	aproto_control = sdp_list_append(0, apseq);
+	sdp_set_access_protos(record, aproto_control);
 	proto_browsing[0] = sdp_list_append(0, &l2cap);
 	psm_browsing = sdp_data_alloc(SDP_UINT16, &lp_browsing);
 	proto_browsing[0] = sdp_list_append(proto_browsing[0], psm_browsing);
@@ -323,12 +323,12 @@ static sdp_record_t *avrcp_tg_record(void)
 	sdp_list_free(proto_browsing[0], 0);
 	sdp_list_free(proto_browsing[1], 0);
 	sdp_list_free(aproto_browsing, 0);
-	free(psm);
+	free(psm_control);
 	free(version);
-	sdp_list_free(proto[0], 0);
-	sdp_list_free(proto[1], 0);
+	sdp_list_free(proto_control[0], 0);
+	sdp_list_free(proto_control[1], 0);
 	sdp_list_free(apseq, 0);
-	sdp_list_free(aproto, 0);
+	sdp_list_free(aproto_control, 0);
 	sdp_list_free(pfseq, 0);
 	sdp_list_free(root, 0);
 	sdp_list_free(svclass_id, 0);
@@ -1037,13 +1037,13 @@ err:
 	return AVC_CTYPE_REJECTED;
 }
 
-static struct pdu_handler {
+static struct control_pdu_handler {
 	uint8_t pdu_id;
 	uint8_t code;
 	uint8_t (*func) (struct avrcp_player *player,
 					struct avrcp_header *pdu,
 					uint8_t transaction);
-} handlers[] = {
+} control_handlers[] = {
 		{ AVRCP_GET_CAPABILITIES, AVC_CTYPE_STATUS,
 					avrcp_handle_get_capabilities },
 		{ AVRCP_LIST_PLAYER_ATTRIBUTES, AVC_CTYPE_STATUS,
@@ -1082,7 +1082,7 @@ static size_t handle_vendordep_pdu(struct avctp *session, uint8_t transaction,
 					void *user_data)
 {
 	struct avrcp_player *player = user_data;
-	struct pdu_handler *handler;
+	struct control_pdu_handler *handler;
 	struct avrcp_header *pdu = (void *) operands;
 	uint32_t company_id = get_company_id(pdu->company_id);
 
@@ -1102,7 +1102,7 @@ static size_t handle_vendordep_pdu(struct avctp *session, uint8_t transaction,
 		goto err_metadata;
 	}
 
-	for (handler = handlers; handler; handler++) {
+	for (handler = control_handlers; handler; handler++) {
 		if (handler->pdu_id == pdu->pdu_id)
 			break;
 	}
@@ -1229,9 +1229,9 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
 		player->dev = NULL;
 		player->registered_events = 0;
 
-		if (player->handler) {
-			avctp_unregister_pdu_handler(player->handler);
-			player->handler = 0;
+		if (player->control_handler) {
+			avctp_unregister_pdu_handler(player->control_handler);
+			player->control_handler = 0;
 		}
 
 		break;
@@ -1239,8 +1239,8 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
 		player->session = avctp_connect(&dev->src, &dev->dst);
 		player->dev = dev;
 
-		if (!player->handler)
-			player->handler = avctp_register_pdu_handler(
+		if (!player->control_handler)
+			player->control_handler = avctp_register_pdu_handler(
 							AVC_OP_VENDORDEP,
 							handle_vendordep_pdu,
 							player);
@@ -1358,8 +1358,8 @@ static void player_destroy(gpointer data)
 
 	player_abort_pending_pdu(player);
 
-	if (player->handler)
-		avctp_unregister_pdu_handler(player->handler);
+	if (player->control_handler)
+		avctp_unregister_pdu_handler(player->control_handler);
 
 	g_free(player);
 }
-- 
1.7.5.4

-Regards,
Vani

^ permalink raw reply related

* Re: [RFCv0 06/21] Bluetooth: Channel move request handling
From: Andrei Emeltchenko @ 2012-08-06  8:44 UTC (permalink / raw)
  To: Mat Martineau; +Cc: linux-bluetooth, gustavo, pkrystad
In-Reply-To: <alpine.DEB.2.02.1207270758080.6052@mathewm-linux>

Hi Mat,

On Fri, Jul 27, 2012 at 09:54:03AM -0700, Mat Martineau wrote:

...

> >>+	if (chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY) {
> >>+		result = L2CAP_MR_NOT_ALLOWED;
> >>+		goto send_move_response;
> >>+	}
> >>+
> >>+	chan->move_cmd_ident = cmd->ident;
> >
> >BTW: Why do we handle ident in a special way for channel move?
> 
> At the time I wrote the code, I thought that chan->ident was only
> used to store idents of sent requests, not received requests.  But
> it does look like it is also used for storing received idents for
> use in sending responses.  chan->ident could be used as long as move
> collisions are handled correctly (where a move request is received
> when a move response is expected).

So can we use chan->ident instead of chan->move_cmd_ident? Is the channel
move somehow different from other L2CAP request / response sequence?

Best regards 
Andrei Emeltchenko 


^ permalink raw reply

* Re: [PATCH BlueZ V2 4/5]AVRCP: Register/Unregister Browsing handler
From: Luiz Augusto von Dentz @ 2012-08-06  8:42 UTC (permalink / raw)
  To: Vani-dineshbhai PATEL; +Cc: User Name, Lucas De Marchi, Joohi, Vani
In-Reply-To: <1343987003-17309-1-git-send-email-vani.patel@stericsson.com>

Hi Vani,

On Fri, Aug 3, 2012 at 12:43 PM, Vani-dineshbhai PATEL
<vani.patel@stericsson.com> wrote:
> +unsigned int avctp_register_browsing_pdu_handler(avctp_browsing_pdu_cb cb,
> +                                                       void *user_data)
> +{
> +       static unsigned int id = 0;
> +
> +       browsing_handler = g_new(struct avctp_browsing_pdu_handler, 1);
> +       browsing_handler->cb = cb;
> +       browsing_handler->user_data = user_data;
> +       browsing_handler->id = ++id;
> +
> +       return browsing_handler->id;
> +}

If we can only have a single pdu handler there is probably no need to
have an id assigned, but I thought the idea was to reuse
avctp_register_pdu_handler with something outside of the range of
control opcodes e.g. > 0xFF.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH BlueZ V2 2/5] AVRCP: Rename variables used for control
From: Luiz Augusto von Dentz @ 2012-08-06  8:20 UTC (permalink / raw)
  To: Vani-dineshbhai PATEL; +Cc: User Name, Lucas De Marchi, Joohi, Vani
In-Reply-To: <1343976273-13448-1-git-send-email-vani.patel@stericsson.com>

Hi Vani,

On Fri, Aug 3, 2012 at 9:44 AM, Vani-dineshbhai PATEL
<vani.patel@stericsson.com> wrote:
> -       err = avctp_send_vendordep(player->session, player->transaction_events[id],
> +       err = avctp_send_vendordep(player->session,
> +                                       player->transaction_events[id],
>                                         AVC_CTYPE_CHANGED, AVC_SUBUNIT_PANEL,
>                                         buf, size + AVRCP_HEADER_LENGTH);

Git complain about this line, apparently you are leaving a whitespace:

Applying: AVRCP: Rename variables used for control
/home/vudentz/git/bluez/.git/rebase-apply/patch:390: trailing whitespace.
	err = avctp_send_vendordep(player->session,
fatal: 1 line adds whitespace errors.

>         if (err < 0)
> @@ -914,7 +915,7 @@ static uint8_t avrcp_handle_get_play_status(struct avrcp_player *player,
>
>         memcpy(&pdu->params[0], &duration, 4);
>         memcpy(&pdu->params[4], &position, 4);
> -       pdu->params[8] = player->cb->get_status(player->user_data);;
> +       pdu->params[8] = player->cb->get_status(player->user_data);

This one should be fixed in separate, it has nothing to do with other
changes you are introducing and could probably be applied very
quickly.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH v2 0/9] Add GATT Client Battery Service
From: Chen Ganir @ 2012-08-06  5:52 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <CAKT1EBdUCSLZm=_FodNeT1UuquYVQVx8oZTOJw9ei2ca8WCrqA@mail.gmail.com>

Claudio,

On 08/03/2012 03:57 PM, Claudio Takahasi wrote:
> Hi Chen Ganir:
>
> On Wed, Aug 1, 2012 at 3:40 AM, Chen Ganir <chen.ganir@ti.com> wrote:
>> On 07/25/2012 08:42 AM, Chen Ganir wrote:
>>>
>>> Add suupport for LE GATT Client Battery Service.
>>>
>>> This plugin adds battery list to the btd_device, exposes DBUS API to list
>>> the
>>> device batteries, and allows querying for battery information. In addition
>>> this
>>> patch allows getting notifications for battery level changes.
>>>
>>> Look at doc/device-api.txt and doc/battery-api.txt for more information.
>>>
>>> This is version 2 of this patch set, rebased on top of the latest sources
>>> and
>>> fixes some issues found during testing and in the ML comments.
>>>
>>> Chen Ganir (9):
>>>     Battery: Add Battery Service GATT Client
>>>     Battery: Add connection logic
>>>     Battery: Discover Characteristic Descriptors
>>>     Battery: Get Battery ID
>>>     Battery: Add Battery list to btd_device
>>>     Battery: Add Battery D-BUS API
>>>     Battery: Read Battery level characteristic
>>>     Battery: Add support for notifications
>>>     Battery: Emit property changed on first read
>>>
>>>    Makefile.am                          |   10 +-
>>>    doc/battery-api.txt                  |   38 +++
>>>    doc/device-api.txt                   |    5 +
>>>    profiles/batterystate/batterystate.c |  518
>>> ++++++++++++++++++++++++++++++++++
>>>    profiles/batterystate/batterystate.h |   24 ++
>>>    profiles/batterystate/main.c         |   67 +++++
>>>    profiles/batterystate/manager.c      |   93 ++++++
>>>    profiles/batterystate/manager.h      |   24 ++
>>>    src/device.c                         |   66 +++++
>>>    src/device.h                         |    3 +
>>>    10 files changed, 846 insertions(+), 2 deletions(-)
>>>    create mode 100644 doc/battery-api.txt
>>>    create mode 100644 profiles/batterystate/batterystate.c
>>>    create mode 100644 profiles/batterystate/batterystate.h
>>>    create mode 100644 profiles/batterystate/main.c
>>>    create mode 100644 profiles/batterystate/manager.c
>>>    create mode 100644 profiles/batterystate/manager.h
>>>
>>
>> Ping anyone ? Did anyone get to review this ?
>>
>> Thanks,
>> Chen Ganir
>
>
> not yet.
> We have an INTERNAL release in two weeks, next week we will send
> comments in the ML.
>
Thanks. I'll be waiting.


> BR,
> Claudio
>

Chen Ganir.

^ permalink raw reply

* Re: [PATCH] Bluetooth: Add support for Sony Vaio T-Series
From: Mohammed Shafi Shajakhan @ 2012-08-06  5:52 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth, gustavo, Yevgeniy Melnichuk
In-Reply-To: <1343934984.2083.3.camel@aeonflux>

Hi Marcel/Yevgeniy,

>
>> Add Sony Vaio T-Series Bluetooth Module( 0x489:0xE036) to
>> the blacklist of btusb module and add it to the ath3k module.
>
> include part of /sys/kernel/debug/usb/devices in the commit message.
> This is nothing new to you guys. I requested it multiple times.
>

I don't have this exact device to be sure, was just helping Yevgeniy to 
send the patch and he has it.

Yevgeniy, please provide the data Marcel had asked for us.


-- 
thanks,
shafi

^ permalink raw reply

* Re: [PATCH v17 01/15] doc: Add telephony interface documents
From: Marcel Holtmann @ 2012-08-05  4:37 UTC (permalink / raw)
  To: Frédéric Danis; +Cc: linux-bluetooth
In-Reply-To: <1343995640-19784-2-git-send-email-frederic.danis@linux.intel.com>

Hi Fred,

>  Makefile.am                    |    2 +-
>  doc/audio-api.txt              |   87 +++++++++++++++++++++++++++++++++
>  doc/audio-telephony-design.txt |  106 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 194 insertions(+), 1 deletion(-)
>  create mode 100644 doc/audio-telephony-design.txt

I looked at this, and we should split this into two patches as well. And
it should be leading with the design document.

> diff --git a/doc/audio-telephony-design.txt b/doc/audio-telephony-design.txt
> new file mode 100644
> index 0000000..a5936f6
> --- /dev/null
> +++ b/doc/audio-telephony-design.txt
> @@ -0,0 +1,106 @@

Can we please get a proper design document. Something that introduces
the problem, describes the goal and how we are trying to achieve it.

> +The org.bluez.Telephony interface will simplify BlueZ code by focusing on
> +the Bluetooth communication part and by letting the external application (i.e.
> +oFono) take charge of the Telephony tasks (AT parsing and modem specific code).
> +So, it becomes simpler, easier to maintain and debug.
> +
> +External applications, which should implement AT parsing and telephony
> +part of HeadSet or HandsFree Profiles, will have to register an

Please use Headset and Handsfree in writing. And unless part of the
profile name itself, it is lower case profiles.

> +org.bluez.TelephonyAgent using this new interface. This will setup a SDP record
> +for the profile and a RFCOMM server listening for incoming connection.
> +
> +When a new device is connected, NewConnection method of TelephonyAgent is
> +called. The telephony agent should reply to it after proper communication
> +establishment (directly for HSP or after SLC setup completes for HFP).

We need to describe on how HFP 1.6 with wideband speech is handled as
well.

> +Interaction with the audio component (i.e. PulseAudio) will be done through the
> +MediaTransport object (passed to telephony agent during NewConnection call).

This is the one thing that is really unclear to me. How does this
actually help. The MediaTransport and TelephonyAgent should be
independent.

> +Here is some flowcharts of interactions between BlueZ, telephony agent (oFono)
> +and audio component (PulseAudio):
> +
> +        .....>  Bluetooth communication between headset and phone
> +        ----->  Dbus messages and signals
> +
> +SCO connection - AG initiated
> +
> +	PulseAudio              BlueZ             HF
> +	|                         |               |
> +	|    transport acquire    |               |
> +	|------------------------>|               |
> +	|                         |  connect SCO  |
> +	|                         |<.............>|
> +	|      return SCO fd      |               |
> +	|<------------------------|               |
> +	|                         |               |

For every diagram it needs to have some sort of description.

> +
> +SCO connection - HF initiated
> +
> +	PulseAudio              BlueZ             HF
> +	|                         |               |
> +	|                         |  connect SCO  |
> +	|                         |<.............>|
> +	|  state changed signal   |               |
> +	|<------------------------|               |
> +	|                         |               |
> +	|    transport acquire    |               |
> +	|------------------------>|               |
> +	|                         |               |
> +	|      return SCO fd      |               |
> +	|<------------------------|               |
> +	|                         |               |
> +
> +AT+NREC
> +
> +	HF              oFono           BlueZ           PulseAudio
> +	|     AT+NREC     |               |                  |
> +	|................>|               |                  |
> +	|                 |  SetProperty  |                  |
> +	|                 |-------------->|                  |
> +	|                 |               | property changed |
> +	|                 |               |      signal      |
> +	|                 |               |----------------->|
> +
> +
> ++BSIR
> +
> +	HF          oFono         BlueZ        PulseAudio        app
> +	|             |             |               |             |
> +	|             |             |               |<------------|
> +	|             |             |  SetProperty  |             |
> +	|             |             |<--------------|             |
> +	|             |             |               |             |
> +	|             |   property changed signal   |             |
> +	|             |<------------*-------------->|             |
> +	|   +BSIR:x   |             |               |             |
> +	|<............|             |               |             |
> +	|             |             |               |             |
> +
> +
> +AT+VGS,AT+VGM
> +
> +	HF          oFono         BlueZ        PulseAudio        app
> +	|             |             |               |             |
> +	|  AT+VGS=xx  |             |               |             |
> +	|............>|             |               |             |
> +	|             | SetProperty |               |             |
> +	|             |------------>|               |             |
> +	|             |             |               |             |
> +	|             |   property changed signal   |             |
> +	|             |<------------*-------------->|             |
> +	|             |             |               |------------>|
> +	|             |             |               |             |
> +
> +
> ++VGS,+VGM
> +
> +	HF          oFono         BlueZ        PulseAudio        app
> +	|             |             |               |             |
> +	|             |             |               |<------------|
> +	|             |             |  SetProperty  |             |
> +	|             |             |<--------------|             |
> +	|             |             |               |             |
> +	|             |   property changed signal   |             |
> +	|             |<------------*-------------->|             |
> +	|   +VGS:xx   |             |               |             |
> +	|<............|             |               |------------>|
> +	|             |             |               |             |

Regards

Marcel



^ permalink raw reply

* [PATCH BlueZ] mgmt: Add LE scanning callback
From: João Paulo Rechi Vita @ 2012-08-03 16:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <CAJdJm_PyZa_0K-5nZOo_D796x5cwiZ6GKMb7-Jey48CYPys88Q@mail.gmail.com>

From: Claudio Takahasi <claudio.takahasi@openbossa.org>

This patch adds a new callback to allow the adapter to control LE
scanning. The current approach uses the active scanning with default
windows and intervals defined by the core spec without any filtering.
---
 src/mgmt.c | 32 ++++++++++++++++++++++++++++++++
 src/mgmt.h |  1 +
 2 files changed, 33 insertions(+)

diff --git a/src/mgmt.c b/src/mgmt.c
index 8ae86d3..5ceeaa8 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -1999,6 +1999,38 @@ int mgmt_start_discovery(int index)
 	return 0;
 }
 
+int mgmt_start_scanning(int index)
+{
+	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_start_discovery)];
+	struct mgmt_hdr *hdr = (void *) buf;
+	struct mgmt_cp_start_discovery *cp = (void *) &buf[sizeof(*hdr)];
+	struct controller_info *info = &controllers[index];
+
+	DBG("index %d", index);
+
+	info->discov_type = 0;
+
+	if (mgmt_low_energy(info->current_settings)) {
+		hci_set_bit(BDADDR_LE_PUBLIC, &info->discov_type);
+		hci_set_bit(BDADDR_LE_RANDOM, &info->discov_type);
+	}
+
+	memset(buf, 0, sizeof(buf));
+	hdr->opcode = htobs(MGMT_OP_START_DISCOVERY);
+	hdr->len = htobs(sizeof(*cp));
+	hdr->index = htobs(index);
+
+	cp->type = info->discov_type;
+
+	if (write(mgmt_sock, buf, sizeof(buf)) < 0) {
+		int err = -errno;
+		error("failed to write to MGMT socket: %s", strerror(-err));
+		return err;
+	}
+
+	return 0;
+}
+
 int mgmt_stop_discovery(int index)
 {
 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_start_discovery)];
diff --git a/src/mgmt.h b/src/mgmt.h
index 0658198..ed47b40 100644
--- a/src/mgmt.h
+++ b/src/mgmt.h
@@ -33,6 +33,7 @@ int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor);
 int mgmt_set_fast_connectable(int index, gboolean enable);
 
 int mgmt_start_discovery(int index);
+int mgmt_start_scanning(int index);
 int mgmt_stop_discovery(int index);
 
 int mgmt_read_clock(int index, bdaddr_t *bdaddr, int which, int timeout,
-- 
1.7.11.2


^ permalink raw reply related

* [PATCH BlueZ] mgmt: print error message when start_discovery fails
From: João Paulo Rechi Vita @ 2012-08-03 14:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: João Paulo Rechi Vita
In-Reply-To: <CAJdJm_N6R5C_EPpK985mYajc7i+R=5T44AvTF_C7-5giR1Z8XQ@mail.gmail.com>

If we fail to communicate with the MGMT socket is better to print the
error message on the mgmtops plugin, where it really happened, instead
of leaving this job to its users.
---
 src/adapter.c | 6 +-----
 src/mgmt.c    | 7 +++++--
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 9e69b50..fa06cd2 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1002,13 +1002,9 @@ struct btd_device *adapter_get_device(DBusConnection *conn,
 static gboolean discovery_cb(gpointer user_data)
 {
 	struct btd_adapter *adapter = user_data;
-	int err;
 
 	adapter->discov_id = 0;
-
-	err = mgmt_start_discovery(adapter->dev_id);
-	if (err < 0)
-		error("start_discovery: %s (%d)", strerror(-err), -err);
+	mgmt_start_discovery(adapter->dev_id);
 
 	return FALSE;
 }
diff --git a/src/mgmt.c b/src/mgmt.c
index c893972..8ae86d3 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -1990,8 +1990,11 @@ int mgmt_start_discovery(int index)
 
 	cp->type = info->discov_type;
 
-	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
-		return -errno;
+	if (write(mgmt_sock, buf, sizeof(buf)) < 0) {
+		int err = -errno;
+		error("failed to write to MGMT socket: %s", strerror(-err));
+		return err;
+	}
 
 	return 0;
 }
-- 
1.7.11.2


^ permalink raw reply related

* Re: [PATCH v2 0/9] Add GATT Client Battery Service
From: Claudio Takahasi @ 2012-08-03 12:57 UTC (permalink / raw)
  To: Chen Ganir; +Cc: linux-bluetooth
In-Reply-To: <5018CF41.6020906@ti.com>

Hi Chen Ganir:

On Wed, Aug 1, 2012 at 3:40 AM, Chen Ganir <chen.ganir@ti.com> wrote:
> On 07/25/2012 08:42 AM, Chen Ganir wrote:
>>
>> Add suupport for LE GATT Client Battery Service.
>>
>> This plugin adds battery list to the btd_device, exposes DBUS API to list
>> the
>> device batteries, and allows querying for battery information. In addition
>> this
>> patch allows getting notifications for battery level changes.
>>
>> Look at doc/device-api.txt and doc/battery-api.txt for more information.
>>
>> This is version 2 of this patch set, rebased on top of the latest sources
>> and
>> fixes some issues found during testing and in the ML comments.
>>
>> Chen Ganir (9):
>>    Battery: Add Battery Service GATT Client
>>    Battery: Add connection logic
>>    Battery: Discover Characteristic Descriptors
>>    Battery: Get Battery ID
>>    Battery: Add Battery list to btd_device
>>    Battery: Add Battery D-BUS API
>>    Battery: Read Battery level characteristic
>>    Battery: Add support for notifications
>>    Battery: Emit property changed on first read
>>
>>   Makefile.am                          |   10 +-
>>   doc/battery-api.txt                  |   38 +++
>>   doc/device-api.txt                   |    5 +
>>   profiles/batterystate/batterystate.c |  518
>> ++++++++++++++++++++++++++++++++++
>>   profiles/batterystate/batterystate.h |   24 ++
>>   profiles/batterystate/main.c         |   67 +++++
>>   profiles/batterystate/manager.c      |   93 ++++++
>>   profiles/batterystate/manager.h      |   24 ++
>>   src/device.c                         |   66 +++++
>>   src/device.h                         |    3 +
>>   10 files changed, 846 insertions(+), 2 deletions(-)
>>   create mode 100644 doc/battery-api.txt
>>   create mode 100644 profiles/batterystate/batterystate.c
>>   create mode 100644 profiles/batterystate/batterystate.h
>>   create mode 100644 profiles/batterystate/main.c
>>   create mode 100644 profiles/batterystate/manager.c
>>   create mode 100644 profiles/batterystate/manager.h
>>
>
> Ping anyone ? Did anyone get to review this ?
>
> Thanks,
> Chen Ganir


not yet.
We have an INTERNAL release in two weeks, next week we will send
comments in the ML.

BR,
Claudio

^ permalink raw reply

* Re: RFCOMM disconnection problem
From: Frederic Danis @ 2012-08-03 12:22 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <501BC0D5.8080403@linux.intel.com>

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

On 03/08/2012 14:15, Frederic Danis wrote:
> Hello,
>
> When I try to disconnect Blue Stereo 200 headset (from mrhandsfree) from
> my PC, if headset was the initiator of the connection, the low level
> (ACL) is not disconnected.
> The device is still visible whith "hcitool con".
>
> This happens with BlueZ 4.98 or from git upstream, and kernel 3.4.6.
> There is no disconnection problem with kernel 3.2.
>
> I also try to revert change "Bluetooth: Fix RFCOMM session reference
> counting issue" (commit cf33e7 in linux-stable.git) from Octavian
> Purdila in kernel 3.4.6.
> With this kernel I do not get disconnection problem.
>
> You can find attached hcidump traces.

Make a mistake, this was kernel log for l2cap and rfcomm.
Find attached hcidump traces.

Fred


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


[-- Attachment #2: hcidump.txt --]
[-- Type: text/plain, Size: 20090 bytes --]

HCI sniffer - Bluetooth packet analyzer ver 2.2
device: hci0 snap_len: 1028 filter: 0xffffffffffffffff
> HCI Event: Connect Request (0x04) plen 10
    bdaddr 10:04:14:D1:96:1C class 0x240404 type ACL
< HCI Command: Accept Connection Request (0x01|0x0009) plen 7
    bdaddr 10:04:14:D1:96:1C role 0x00
    Role: Master
> HCI Event: Command Status (0x0f) plen 4
    Accept Connection Request (0x01|0x0009) status 0x00 ncmd 1
> HCI Event: Role Change (0x12) plen 8
    status 0x00 bdaddr 10:04:14:D1:96:1C role 0x00
    Role: Master
> HCI Event: Connect Complete (0x03) plen 11
    status 0x00 handle 11 bdaddr 10:04:14:D1:96:1C type ACL encrypt 0x00
< HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2
    handle 11
> HCI Event: Command Status (0x0f) plen 4
    Read Remote Supported Features (0x01|0x001b) status 0x00 ncmd 1
> HCI Event: Read Remote Supported Features (0x0b) plen 11
    status 0x00 handle 11
    Features: 0xbf 0xff 0xff 0xfe 0x88 0x3d 0x19 0x82
< HCI Command: Read Remote Extended Features (0x01|0x001c) plen 3
    handle 11 page 1
> HCI Event: Max Slots Change (0x1b) plen 3
    handle 11 slots 5
> HCI Event: Command Status (0x0f) plen 4
    Read Remote Extended Features (0x01|0x001c) status 0x00 ncmd 1
> HCI Event: Read Remote Extended Features (0x23) plen 13
    status 0x00 handle 11 page 1 max 1
    Features: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
< HCI Command: Remote Name Request (0x01|0x0019) plen 10
    bdaddr 10:04:14:D1:96:1C mode 2 clkoffset 0x0000
> HCI Event: Command Status (0x0f) plen 4
    Remote Name Request (0x01|0x0019) status 0x00 ncmd 1
> HCI Event: Remote Name Req Complete (0x07) plen 255
    status 0x00 bdaddr 10:04:14:D1:96:1C name 'Blue STEREO 200'
> HCI Event: Link Key Request (0x17) plen 6
    bdaddr 10:04:14:D1:96:1C
< HCI Command: Link Key Request Reply (0x01|0x000b) plen 22
    bdaddr 10:04:14:D1:96:1C key 9EF4BDFA68C543865043E004E35D0277
> HCI Event: Command Complete (0x0e) plen 10
    Link Key Request Reply (0x01|0x000b) ncmd 1
    status 0x00 bdaddr 10:04:14:D1:96:1C
> HCI Event: Encrypt Change (0x08) plen 4
    status 0x00 handle 11 encrypt 0x01
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Connect req: psm 1 scid 0x0040
< ACL data: handle 11 flags 0x00 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 1 status 0
      Connection pending - No futher information available
< ACL data: handle 11 flags 0x00 dlen 10
    L2CAP(s): Info req: type 2
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Info rsp: type 2 result 1
      Not supported
< ACL data: handle 11 flags 0x00 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 0 status 0
      Connection successful
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 0
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 4
      MTU 512 
< ACL data: handle 11 flags 0x00 dlen 18
    L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 4
      MTU 512 
> ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 0
      Success
> ACL data: handle 11 flags 0x02 dlen 17
    L2CAP(d): cid 0x0040 len 13 [psm 1]
        SDP SS Req: tid 0x1 len 0x8
          pat uuid-16 0x111f (Handsfree AG)
          max 3
          cont 00
< ACL data: handle 11 flags 0x00 dlen 18
    L2CAP(d): cid 0x0040 len 14 [psm 1]
        SDP SS Rsp: tid 0x1 len 0x9
          count 1
          handle 0x10002
          cont 00
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 21
    L2CAP(d): cid 0x0040 len 17 [psm 1]
        SDP SA Req: tid 0x2 len 0xc
          handle 0x10002
          max 1016
          aid(s) 0x0004 (ProtocolDescList)
          cont 00
< ACL data: handle 11 flags 0x00 dlen 31
    L2CAP(d): cid 0x0040 len 27 [psm 1]
        SDP SA Rsp: tid 0x2 len 0x16
          count 19
          aid 0x0004 (ProtocolDescList)
             < < uuid-16 0x0100 (L2CAP) > <
             uuid-16 0x0003 (RFCOMM) uint 0xd > >
          cont 00
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Disconn req: dcid 0x0040 scid 0x0040
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Disconn rsp: dcid 0x0040 scid 0x0040
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Connect req: psm 3 scid 0x0041
< ACL data: handle 11 flags 0x00 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0041 result 0 status 0
      Connection successful
< ACL data: handle 11 flags 0x00 dlen 16
    L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 4
      MTU 1013 
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 4
      MTU 512 
< ACL data: handle 11 flags 0x00 dlen 18
    L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 4
      MTU 512 
> ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 0
      Success
> ACL data: handle 11 flags 0x02 dlen 8
    L2CAP(d): cid 0x0040 len 4 [psm 3]
      RFCOMM(s): SABM: cr 1 dlci 0 pf 1 ilen 0 fcs 0x1c 
< ACL data: handle 11 flags 0x00 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): UA: cr 1 dlci 0 pf 1 ilen 0 fcs 0xd7 
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 19
    L2CAP(d): cid 0x0040 len 15 [psm 3]
      RFCOMM(s): PN CMD: cr 1 dlci 0 pf 0 ilen 10 fcs 0x70 mcc_len 8
      dlci 26 frame_type 0 credit_flow 15 pri 7 ack_timer 0
      frame_size 400 max_retrans 0 credits 7
< ACL data: handle 11 flags 0x00 dlen 18
    L2CAP(d): cid 0x0041 len 14 [psm 3]
      RFCOMM(s): PN RSP: cr 0 dlci 0 pf 0 ilen 10 fcs 0xaa mcc_len 8
      dlci 26 frame_type 0 credit_flow 14 pri 7 ack_timer 0
      frame_size 400 max_retrans 0 credits 7
> ACL data: handle 11 flags 0x02 dlen 8
    L2CAP(d): cid 0x0040 len 4 [psm 3]
      RFCOMM(s): SABM: cr 1 dlci 26 pf 1 ilen 0 fcs 0xe7 
< HCI Command: Authentication Requested (0x01|0x0011) plen 2
    handle 11
> HCI Event: Command Status (0x0f) plen 4
    Authentication Requested (0x01|0x0011) status 0x00 ncmd 1
> HCI Event: Link Key Request (0x17) plen 6
    bdaddr 10:04:14:D1:96:1C
< HCI Command: Link Key Request Reply (0x01|0x000b) plen 22
    bdaddr 10:04:14:D1:96:1C key 9EF4BDFA68C543865043E004E35D0277
> HCI Event: Command Complete (0x0e) plen 10
    Link Key Request Reply (0x01|0x000b) ncmd 1
    status 0x00 bdaddr 10:04:14:D1:96:1C
> HCI Event: Auth Complete (0x06) plen 3
    status 0x00 handle 11
< HCI Command: Set Connection Encryption (0x01|0x0013) plen 3
    handle 11 encrypt 0x01
> HCI Event: Command Status (0x0f) plen 4
    Set Connection Encryption (0x01|0x0013) status 0x00 ncmd 1
> HCI Event: Encryption Key Refresh Complete (0x30) plen 3
    status 0x00 handle 11
> HCI Event: Command Status (0x0f) plen 4
    Set Connection Encryption (0x01|0x0013) status 0x00 ncmd 1
> HCI Event: Encrypt Change (0x08) plen 4
    status 0x00 handle 11 encrypt 0x01
< ACL data: handle 11 flags 0x00 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): UA: cr 1 dlci 26 pf 1 ilen 0 fcs 0x2c 
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(d): cid 0x0041 len 8 [psm 3]
      RFCOMM(s): MSC CMD: cr 0 dlci 0 pf 0 ilen 4 fcs 0xaa mcc_len 2
      dlci 26 fc 0 rtc 1 rtr 1 ic 0 dv 1 b1 0 b2 1 b3 0 len 0
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 13
    L2CAP(d): cid 0x0040 len 9 [psm 3]
      RFCOMM(s): MSC CMD: cr 1 dlci 0 pf 0 ilen 4 fcs 0x70 mcc_len 2
      dlci 26 fc 0 rtc 1 rtr 1 ic 0 dv 1 b1 1 b2 0 b3 0 len 14
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(d): cid 0x0041 len 8 [psm 3]
      RFCOMM(s): MSC RSP: cr 0 dlci 0 pf 0 ilen 4 fcs 0xaa mcc_len 2
      dlci 26 fc 0 rtc 1 rtr 1 ic 0 dv 1 b1 0 b2 1 b3 0 len 0
> ACL data: handle 11 flags 0x02 dlen 13
    L2CAP(d): cid 0x0040 len 9 [psm 3]
      RFCOMM(s): MSC RSP: cr 1 dlci 0 pf 0 ilen 4 fcs 0x70 mcc_len 2
      dlci 26 fc 0 rtc 1 rtr 1 ic 0 dv 1 b1 1 b2 0 b3 0 len 14
< ACL data: handle 11 flags 0x00 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 1 ilen 0 fcs 0x22 credits 33
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 21
    L2CAP(d): cid 0x0040 len 17 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 11 fcs 0xf8 credits 8
      0000: 41 54 2b 42 52 53 46 3d  33 30 0d                 AT+BRSF=30.
< ACL data: handle 11 flags 0x00 dlen 22
    L2CAP(d): cid 0x0041 len 18 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 14 fcs 0x3e 
      0000: 0d 0a 2b 42 52 53 46 3a  20 33 35 32 0d 0a        ..+BRSF: 352..
< ACL data: handle 11 flags 0x00 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 1
> ACL data: handle 11 flags 0x02 dlen 20
    L2CAP(d): cid 0x0040 len 16 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 10 fcs 0xf8 credits 2
      0000: 41 54 2b 43 49 4e 44 3d  3f 0d                    AT+CIND=?.
< ACL data: handle 11 flags 0x00 dlen 141
    L2CAP(d): cid 0x0041 len 137 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 132 fcs 0x3e 
      0000: 0d 0a 2b 43 49 4e 44 3a  20 28 22 62 61 74 74 63  ..+CIND: ("battc
      0010: 68 67 22 2c 28 30 2d 35  29 29 2c 28 22 73 69 67  hg",(0-5)),("sig
      0020: 6e 61 6c 22 2c 28 30 2d  35 29 29 2c 28 22 73 65  nal",(0-5)),("se
      0030: 72 76 69 63 65 22 2c 28  30 2c 31 29 29 2c 28 22  rvice",(0,1)),("
      0040: 63 61 6c 6c 22 2c 28 30  2c 31 29 29 2c 28 22 63  call",(0,1)),("c
      0050: 61 6c 6c 73 65 74 75 70  22 2c 28 30 2d 33 29 29  allsetup",(0-3))
      0060: 2c 28 22 63 61 6c 6c 68  65 6c 64 22 2c 28 30 2d  ,("callheld",(0-
      0070: 32 29 29 2c 28 22 72 6f  61 6d 22 2c 28 30 2c 31  2)),("roam",(0,1
      0080: 29 29 0d 0a                                       ))..
< ACL data: handle 11 flags 0x00 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 19
    L2CAP(d): cid 0x0040 len 15 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 9 fcs 0xf8 credits 2
      0000: 41 54 2b 43 49 4e 44 3f  0d                       AT+CIND?.
< ACL data: handle 11 flags 0x00 dlen 32
    L2CAP(d): cid 0x0041 len 28 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 24 fcs 0x3e 
      0000: 0d 0a 2b 43 49 4e 44 3a  20 35 2c 35 2c 31 2c 30  ..+CIND: 5,5,1,0
      0010: 2c 30 2c 30 2c 30 0d 0a                           ,0,0,0..
< ACL data: handle 11 flags 0x00 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 26
    L2CAP(d): cid 0x0040 len 22 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 16 fcs 0xf8 credits 2
      0000: 41 54 2b 43 4d 45 52 3d  33 2c 30 2c 30 2c 31 0d  AT+CMER=3,0,0,1.
< ACL data: handle 11 flags 0x00 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 1
> HCI Event: Max Slots Change (0x1b) plen 3
    handle 11 slots 1
> ACL data: handle 11 flags 0x02 dlen 20
    L2CAP(d): cid 0x0040 len 16 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 10 fcs 0xf8 credits 1
      0000: 41 54 2b 43 4c 49 50 3d  31 0d                    AT+CLIP=1.
< ACL data: handle 11 flags 0x00 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> ACL data: handle 11 flags 0x02 dlen 19
    L2CAP(d): cid 0x0040 len 15 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 9 fcs 0xf8 credits 1
      0000: 41 54 2b 56 47 53 3d 39  0d                       AT+VGS=9.
< ACL data: handle 11 flags 0x00 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 20
    L2CAP(d): cid 0x0040 len 16 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 10 fcs 0xf8 credits 1
      0000: 41 54 2b 56 47 4d 3d 31  30 0d                    AT+VGM=10.
< ACL data: handle 11 flags 0x00 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 1
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Connect req: psm 25 scid 0x0041
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0042 scid 0x0041 result 0 status 0
      Connection successful
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Config req: dcid 0x0042 flags 0x00 clen 0
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 4
      MTU 672 
< ACL data: handle 11 flags 0x00 dlen 18
    L2CAP(s): Config rsp: scid 0x0042 flags 0x00 result 0 clen 4
      MTU 672 
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 0
      Success
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Connect req: psm 23 scid 0x0042
< ACL data: handle 11 flags 0x00 dlen 6
    L2CAP(d): cid 0x0042 len 2 [psm 25]
      AVDTP(s): Discover cmd: transaction 10 nsp 0x00
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> HCI Event: Max Slots Change (0x1b) plen 3
    handle 11 slots 5
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0043 scid 0x0042 result 0 status 0
      Connection successful
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Config req: dcid 0x0043 flags 0x00 clen 0
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Config req: dcid 0x0042 flags 0x00 clen 4
      MTU 512 
< ACL data: handle 11 flags 0x00 dlen 18
    L2CAP(s): Config rsp: scid 0x0043 flags 0x00 result 0 clen 4
      MTU 512 
> ACL data: handle 11 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 25]
      AVDTP(s): Discover rsp: transaction 10 nsp 0x00
        ACP SEID 1 - Audio Sink
< ACL data: handle 11 flags 0x00 dlen 7
    L2CAP(d): cid 0x0042 len 3 [psm 25]
      AVDTP(s): Capabilities cmd: transaction 11 nsp 0x00
        ACP SEID 1
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 3
> ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(s): Config rsp: scid 0x0042 flags 0x00 result 0 clen 0
      Success
> ACL data: handle 11 flags 0x02 dlen 20
    L2CAP(d): cid 0x0041 len 16 [psm 25]
      AVDTP(s): Capabilities rsp: transaction 11 nsp 0x00
        Media Transport
        Content Protection
          02 00 
        Media Codec - SBC
          16kHz 32kHz 44.1kHz 48kHz 
          Mono DualChannel Stereo JointStereo 
          4 8 12 16 Blocks
          4 8 Subbands
          SNR Loudness 
          Bitpool Range 2-38
< ACL data: handle 11 flags 0x00 dlen 18
    L2CAP(d): cid 0x0042 len 14 [psm 25]
      AVDTP(s): Set config cmd: transaction 12 nsp 0x00
        ACP SEID 1 - INT SEID 1
        Media Transport
        Media Codec - SBC
          44.1kHz 
          JointStereo 
          16 Blocks
          8 Subbands
          Loudness 
          Bitpool Range 2-38
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 6
    L2CAP(d): cid 0x0041 len 2 [psm 25]
      AVDTP(s): Set config rsp: transaction 12 nsp 0x00
< ACL data: handle 11 flags 0x00 dlen 7
    L2CAP(d): cid 0x0042 len 3 [psm 25]
      AVDTP(s): Open cmd: transaction 13 nsp 0x00
        ACP SEID 1
> ACL data: handle 11 flags 0x02 dlen 6
    L2CAP(d): cid 0x0041 len 2 [psm 25]
      AVDTP(s): Open rsp: transaction 13 nsp 0x00
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Connect req: psm 25 scid 0x0043
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0044 scid 0x0043 result 0 status 0
      Connection successful
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Config req: dcid 0x0044 flags 0x00 clen 0
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Config req: dcid 0x0043 flags 0x00 clen 4
      MTU 672 
< ACL data: handle 11 flags 0x00 dlen 18
    L2CAP(s): Config rsp: scid 0x0044 flags 0x00 result 0 clen 4
      MTU 672 
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(s): Config rsp: scid 0x0043 flags 0x00 result 0 clen 0
      Success


< ACL data: handle 11 flags 0x00 dlen 7
    L2CAP(d): cid 0x0042 len 3 [psm 25]
      AVDTP(s): Close cmd: transaction 14 nsp 0x00
        ACP SEID 1
> ACL data: handle 11 flags 0x02 dlen 6
    L2CAP(d): cid 0x0041 len 2 [psm 25]
      AVDTP(s): Close rsp: transaction 14 nsp 0x00
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Disconn req: dcid 0x0044 scid 0x0043
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Disconn rsp: dcid 0x0044 scid 0x0043
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Disconn req: dcid 0x0042 scid 0x0041
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Disconn req: dcid 0x0043 scid 0x0042
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Disconn rsp: dcid 0x0042 scid 0x0041
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Disconn rsp: dcid 0x0043 scid 0x0042
> HCI Event: Max Slots Change (0x1b) plen 3
    handle 11 slots 1
> HCI Event: Mode Change (0x14) plen 6
    status 0x00 handle 11 mode 0x02 interval 2048
    Mode: Sniff


< ACL data: handle 11 flags 0x00 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): DISC: cr 0 dlci 26 pf 1 ilen 0 fcs 0x67 
< HCI Command: Exit Sniff Mode (0x02|0x0004) plen 2
    handle 11
> HCI Event: Command Status (0x0f) plen 4
    Exit Sniff Mode (0x02|0x0004) status 0x00 ncmd 1
> ACL data: handle 11 flags 0x02 dlen 8
    L2CAP(d): cid 0x0040 len 4 [psm 3]
      RFCOMM(s): UA: cr 0 dlci 26 pf 1 ilen 0 fcs 0x4d 
< ACL data: handle 11 flags 0x00 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): DISC: cr 0 dlci 0 pf 1 ilen 0 fcs 0x9c 
> HCI Event: Max Slots Change (0x1b) plen 3
    handle 11 slots 5
> HCI Event: Mode Change (0x14) plen 6
    status 0x00 handle 11 mode 0x00 interval 0
    Mode: Active
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 8
    L2CAP(d): cid 0x0040 len 4 [psm 3]
      RFCOMM(s): UA: cr 0 dlci 0 pf 1 ilen 0 fcs 0xb6 
> HCI Event: Max Slots Change (0x1b) plen 3
    handle 11 slots 1
> HCI Event: Mode Change (0x14) plen 6
    status 0x00 handle 11 mode 0x02 interval 2048
    Mode: Sniff



^ permalink raw reply

* RFCOMM disconnection problem
From: Frederic Danis @ 2012-08-03 12:15 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org

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

Hello,

When I try to disconnect Blue Stereo 200 headset (from mrhandsfree) from 
my PC, if headset was the initiator of the connection, the low level 
(ACL) is not disconnected.
The device is still visible whith "hcitool con".

This happens with BlueZ 4.98 or from git upstream, and kernel 3.4.6.
There is no disconnection problem with kernel 3.2.

I also try to revert change "Bluetooth: Fix RFCOMM session reference 
counting issue" (commit cf33e7 in linux-stable.git) from Octavian 
Purdila in kernel 3.4.6.
With this kernel I do not get disconnection problem.

You can find attached hcidump traces.

Fred

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



[-- Attachment #2: hcidump.txt --]
[-- Type: text/plain, Size: 66033 bytes --]

Aug  3 11:02:35 fdanis-linux kernel: [ 6342.783813] l2cap_connect_ind: hdev hci0, bdaddr 10:04:14:D1:96:1C
Aug  3 11:02:35 fdanis-linux kernel: [ 6343.145829] l2cap_connect_cfm: hcon ffff88000c006800 bdaddr 10:04:14:D1:96:1C status 0
Aug  3 11:02:35 fdanis-linux kernel: [ 6343.145840] l2cap_conn_add: hcon ffff88000c006800 conn ffff880081914a00 hchan ffff88011007f380
Aug  3 11:02:35 fdanis-linux kernel: [ 6343.145845] l2cap_conn_ready: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.604676] l2cap_security_cfm: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.604685] rfcomm_security_cfm: conn ffff88000c006800 status 0x00 encrypt 0x01
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.610998] l2cap_recv_acldata: conn ffff880081914a00 len 12 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611004] l2cap_recv_frame: len 8, cid 0x0001
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611008] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611011] l2cap_sig_channel: code 0x02 len 4 id 0x02
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611015] l2cap_connect_req: psm 0x01 scid 0x0040
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611026] l2cap_chan_create: sk ffff88010e7ac400 chan ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611030] l2cap_sock_init: sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611034] __l2cap_chan_add: conn ffff880081914a00, psm 0x01, dcid 0x0040
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611041] __l2cap_state_change: chan ffff88010e7aec00 BT_OPEN -> BT_CONNECT2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611046] l2cap_build_cmd: conn ffff880081914a00, code 0x03, ident 0x02, len 8
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611050] l2cap_send_cmd: code 0x03
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611059] l2cap_build_cmd: conn ffff880081914a00, code 0x0a, ident 0x01, len 2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.611064] l2cap_send_cmd: code 0x0a
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617213] l2cap_recv_acldata: conn ffff880081914a00 len 12 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617218] l2cap_recv_frame: len 8, cid 0x0001
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617220] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617223] l2cap_sig_channel: code 0x0b len 4 id 0x01
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617226] l2cap_information_rsp: type 0x0002 result 0x01
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617229] l2cap_conn_start: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617233] __l2cap_state_change: chan ffff88010e7aec00 BT_CONNECT2 -> BT_CONFIG
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617236] l2cap_build_cmd: conn ffff880081914a00, code 0x03, ident 0x02, len 8
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617239] l2cap_send_cmd: code 0x03
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617244] l2cap_build_conf_req: chan ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617247] l2cap_build_cmd: conn ffff880081914a00, code 0x04, ident 0x02, len 4
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.617250] l2cap_send_cmd: code 0x04
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.623465] l2cap_recv_acldata: conn ffff880081914a00 len 16 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.623471] l2cap_recv_frame: len 12, cid 0x0001
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.623474] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.623478] l2cap_sig_channel: code 0x04 len 8 id 0x03
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.623483] l2cap_config_req: dcid 0x0040 flags 0x00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.623487] l2cap_parse_conf_req: chan ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.623490] l2cap_get_conf_opt: type 0x01 len 2 val 0x200
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.623495] l2cap_add_conf_opt: type 0x01 len 2 val 0x200
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.623498] l2cap_build_cmd: conn ffff880081914a00, code 0x05, ident 0x03, len 10
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.623502] l2cap_send_cmd: code 0x05
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624796] l2cap_recv_acldata: conn ffff880081914a00 len 14 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624801] l2cap_recv_frame: len 10, cid 0x0001
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624805] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624809] l2cap_sig_channel: code 0x05 len 6 id 0x02
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624814] l2cap_config_rsp: scid 0x0040 flags 0x00 result 0x00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624819] l2cap_conf_rfc_get: chan ffff88010e7aec00, rsp ffff88000c00401a, len 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624825] __l2cap_state_change: chan ffff88010e7aec00 BT_CONFIG -> BT_CONNECTED
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624830] l2cap_chan_ready: sk ffff88010e7ac400, parent ffff880110121000
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624835] __l2cap_state_change: chan ffff88010e7aec00 BT_CONNECTED -> BT_CONNECTED
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624916] l2cap_sock_accept: sk ffff880110121000 timeo 9223372036854775807
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624920] l2cap_sock_accept: new socket ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.624921] l2cap_sock_getname: sock ffff8800c1cf0500, sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.629788] l2cap_recv_acldata: conn ffff880081914a00 len 17 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.629794] l2cap_recv_frame: len 13, cid 0x0040
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.629799] l2cap_data_channel: chan ffff88010e7aec00, len 13
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.629843] l2cap_sock_getname: sock ffff8800c1cf0500, sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.629851] l2cap_sock_getsockopt: sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.629855] l2cap_sock_getsockopt_old: sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.629860] l2cap_sock_getname: sock ffff8800c1cf0500, sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.629916] l2cap_sock_sendmsg: sock ffff8800c1cf0500, sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.629920] l2cap_create_basic_pdu: chan ffff88010e7aec00 len 14
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.629925] l2cap_do_send: chan ffff88010e7aec00, skb ffff88003f90d500 len 18 priority 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.635994] l2cap_recv_acldata: conn ffff880081914a00 len 21 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.636000] l2cap_recv_frame: len 17, cid 0x0040
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.636003] l2cap_data_channel: chan ffff88010e7aec00, len 17
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.636051] l2cap_sock_getname: sock ffff8800c1cf0500, sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.636056] l2cap_sock_getsockopt: sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.636058] l2cap_sock_getsockopt_old: sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.636062] l2cap_sock_getname: sock ffff8800c1cf0500, sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.636093] l2cap_sock_sendmsg: sock ffff8800c1cf0500, sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.636097] l2cap_create_basic_pdu: chan ffff88010e7aec00 len 27
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.636102] l2cap_do_send: chan ffff88010e7aec00, skb ffff880061c71700 len 31 priority 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670857] l2cap_recv_acldata: conn ffff880081914a00 len 12 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670863] l2cap_recv_frame: len 8, cid 0x0001
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670866] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670868] l2cap_sig_channel: code 0x06 len 4 id 0x04
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670871] l2cap_disconnect_req: scid 0x0040 dcid 0x0040
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670874] l2cap_build_cmd: conn ffff880081914a00, code 0x07, ident 0x04, len 4
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670877] l2cap_send_cmd: code 0x07
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670886] l2cap_chan_del: chan ffff88010e7aec00, conn ffff880081914a00, err 104
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670892] __l2cap_state_change: chan ffff88010e7aec00 BT_CONNECTED -> BT_CLOSED
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670967] l2cap_sock_release: sock ffff8800c1cf0500, sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670970] l2cap_sock_shutdown: sock ffff8800c1cf0500, sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670973] l2cap_sock_kill: sk ffff88010e7ac400 state BT_CLOSED
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.670976] l2cap_sock_destruct: sk ffff88010e7ac400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717006] l2cap_recv_acldata: conn ffff880081914a00 len 12 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717013] l2cap_recv_frame: len 8, cid 0x0001
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717017] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717021] l2cap_sig_channel: code 0x02 len 4 id 0x05
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717025] l2cap_connect_req: psm 0x03 scid 0x0041
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717035] l2cap_chan_create: sk ffff88010e7aec00 chan ffff88010e7a9000
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717039] l2cap_sock_init: sk ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717044] __l2cap_chan_add: conn ffff880081914a00, psm 0x03, dcid 0x0041
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717051] __l2cap_state_change: chan ffff88010e7a9000 BT_OPEN -> BT_CONFIG
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717056] l2cap_build_cmd: conn ffff880081914a00, code 0x03, ident 0x05, len 8
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717060] l2cap_send_cmd: code 0x03
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717067] l2cap_build_conf_req: chan ffff88010e7a9000
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717073] l2cap_add_conf_opt: type 0x01 len 2 val 0x3f5
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717078] l2cap_build_cmd: conn ffff880081914a00, code 0x04, ident 0x03, len 8
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.717084] l2cap_send_cmd: code 0x04
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.723217] l2cap_recv_acldata: conn ffff880081914a00 len 16 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.723222] l2cap_recv_frame: len 12, cid 0x0001
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.723226] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.723229] l2cap_sig_channel: code 0x04 len 8 id 0x06
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.723233] l2cap_config_req: dcid 0x0040 flags 0x00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.723237] l2cap_parse_conf_req: chan ffff88010e7a9000
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.723241] l2cap_get_conf_opt: type 0x01 len 2 val 0x200
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.723244] l2cap_add_conf_opt: type 0x01 len 2 val 0x200
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.723248] l2cap_build_cmd: conn ffff880081914a00, code 0x05, ident 0x06, len 10
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.723252] l2cap_send_cmd: code 0x05
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724551] l2cap_recv_acldata: conn ffff880081914a00 len 14 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724557] l2cap_recv_frame: len 10, cid 0x0001
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724560] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724564] l2cap_sig_channel: code 0x05 len 6 id 0x03
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724569] l2cap_config_rsp: scid 0x0040 flags 0x00 result 0x00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724574] l2cap_conf_rfc_get: chan ffff88010e7a9000, rsp ffff88000c00481a, len 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724579] __l2cap_state_change: chan ffff88010e7a9000 BT_CONFIG -> BT_CONNECTED
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724585] l2cap_chan_ready: sk ffff88010e7aec00, parent ffff88010e7a8400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724589] __l2cap_state_change: chan ffff88010e7a9000 BT_CONNECTED -> BT_CONNECTED
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724595] rfcomm_l2data_ready: ffff88010e7a8400 bytes 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724616] rfcomm_accept_connection: session ffff8801101c2180
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724628] l2cap_sock_accept: sk ffff88010e7a8400 timeo 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724635] l2cap_sock_accept: new socket ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724640] rfcomm_session_add: session ffff880110b72000 sock ffff8800c7792800
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724649] rfcomm_process_rx: session ffff880110b72000 state 2 qlen 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.724654] rfcomm_process_dlcs: session ffff880110b72000 state 2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729591] l2cap_recv_acldata: conn ffff880081914a00 len 8 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729596] l2cap_recv_frame: len 4, cid 0x0040
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729599] l2cap_data_channel: chan ffff88010e7a9000, len 4
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729603] rfcomm_l2data_ready: ffff88010e7aec00 bytes 4
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729637] rfcomm_process_rx: session ffff880110b72000 state 2 qlen 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729641] rfcomm_recv_sabm: session ffff880110b72000 state 2 dlci 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729643] rfcomm_send_ua: ffff880110b72000 dlci 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729646] rfcomm_send_cmd: ffff880110b72000 cmd 115
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729648] rfcomm_send_frame: session ffff880110b72000 len 4
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729651] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729654] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 4
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729658] l2cap_do_send: chan ffff88010e7a9000, skb ffff8800c3959600 len 8 priority 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729663] rfcomm_process_connect: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.729667] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735796] l2cap_recv_acldata: conn ffff880081914a00 len 19 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735803] l2cap_recv_frame: len 15, cid 0x0040
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735806] l2cap_data_channel: chan ffff88010e7a9000, len 15
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735811] rfcomm_l2data_ready: ffff88010e7aec00 bytes 15
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735821] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735824] rfcomm_recv_mcc: ffff880110b72000 type 0x20 cr 2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735827] rfcomm_recv_pn: session ffff880110b72000 state 1 dlci 26
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735830] rfcomm_connect_ind: session ffff880110b72000 channel 13
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735838] rfcomm_dlc_clear_state: ffff8800c3959a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735841] rfcomm_dlc_alloc: ffff8800c3959a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735844] rfcomm_sock_alloc: sk ffff88010e7ad400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735846] rfcomm_sock_init: sk ffff88010e7ad400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735857] rfcomm_dlc_link: dlc ffff8800c3959a00 session ffff880110b72000
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735859] rfcomm_session_clear_timer: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735862] rfcomm_apply_pn: dlc ffff8800c3959a00 state 2 dlci 26 mtu 400 fc 0xf0 credits 7
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735865] rfcomm_send_pn: ffff880110b72000 cr 0 dlci 26 mtu 400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735867] rfcomm_send_frame: session ffff880110b72000 len 14
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735871] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735874] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 14
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735880] l2cap_do_send: chan ffff88010e7a9000, skb ffff8800c3959c00 len 18 priority 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.735887] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.743173] l2cap_recv_acldata: conn ffff880081914a00 len 8 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.743178] l2cap_recv_frame: len 4, cid 0x0040
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.743182] l2cap_data_channel: chan ffff88010e7a9000, len 4
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.743186] rfcomm_l2data_ready: ffff88010e7aec00 bytes 4
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.743200] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.743207] rfcomm_recv_sabm: session ffff880110b72000 state 1 dlci 26
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.743218] rfcomm_dlc_set_timer: dlc ffff8800c3959a00 state 2 timeout 6250
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.743225] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916852] l2cap_security_cfm: conn ffff880081914a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916858] l2cap_security_cfm: chan->scid 64
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916864] rfcomm_l2state_change: ffff88010e7aec00 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916872] rfcomm_security_cfm: conn ffff88000c006800 status 0x00 encrypt 0x01
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916881] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916887] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916893] rfcomm_dlc_clear_timer: dlc ffff8800c3959a00 state 2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916897] rfcomm_dlc_set_timer: dlc ffff8800c3959a00 state 2 timeout 6250
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916902] rfcomm_sk_state_change: dlc ffff8800c3959a00 state 6 err 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916914] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916920] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916945] rfcomm_sock_accept: sk ffff88010da5fc00 timeo 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916952] rfcomm_sock_accept: new socket ffff88010e7ad400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916973] rfcomm_sock_getname: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.916976] rfcomm_sock_getname: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917148] rfcomm_dlc_accept: dlc ffff8800c3959a00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917151] rfcomm_send_ua: ffff880110b72000 dlci 26
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917153] rfcomm_send_cmd: ffff880110b72000 cmd 115
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917154] rfcomm_send_frame: session ffff880110b72000 len 4
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917157] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917160] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 4
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917164] l2cap_do_send: chan ffff88010e7a9000, skb ffff8800c3959600 len 8 priority 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917169] rfcomm_dlc_clear_timer: dlc ffff8800c3959a00 state 6
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917171] rfcomm_sk_state_change: dlc ffff8800c3959a00 state 1 err 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917175] rfcomm_send_msc: ffff880110b72000 cr 1 v24 0x8c
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917177] rfcomm_send_frame: session ffff880110b72000 len 8
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917179] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917181] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 8
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.917184] l2cap_do_send: chan ffff88010e7a9000, skb ffff8800c3959200 len 12 priority 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.923967] l2cap_recv_acldata: conn ffff880081914a00 len 13 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.923973] l2cap_recv_frame: len 9, cid 0x0040
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.923977] l2cap_data_channel: chan ffff88010e7a9000, len 9
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.923982] rfcomm_l2data_ready: ffff88010e7aec00 bytes 9
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.923996] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.924003] rfcomm_recv_mcc: ffff880110b72000 type 0x38 cr 2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.924007] rfcomm_recv_msc: dlci 26 cr 2 v24 0x8d
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.924011] rfcomm_send_msc: ffff880110b72000 cr 0 v24 0x8d
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.924014] rfcomm_send_frame: session ffff880110b72000 len 8
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.924018] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.924022] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 8
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.924028] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90c800 len 12 priority 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.924040] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925194] l2cap_recv_acldata: conn ffff880081914a00 len 13 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925201] l2cap_recv_frame: len 9, cid 0x0040
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925207] l2cap_data_channel: chan ffff88010e7a9000, len 9
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925215] rfcomm_l2data_ready: ffff88010e7aec00 bytes 9
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925259] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925262] rfcomm_recv_mcc: ffff880110b72000 type 0x38 cr 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925263] rfcomm_recv_msc: dlci 26 cr 0 v24 0x8d
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925266] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925268] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 7 tx_credits 7
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925270] rfcomm_send_credits: ffff880110b72000 addr 105 credits 33
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925271] rfcomm_send_frame: session ffff880110b72000 len 5
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925273] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925275] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 5
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.925278] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90ce00 len 9 priority 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934070] l2cap_recv_acldata: conn ffff880081914a00 len 21 flags 0x2
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934077] l2cap_recv_frame: len 17, cid 0x0040
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934082] l2cap_data_channel: chan ffff88010e7a9000, len 17
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934089] rfcomm_l2data_ready: ffff88010e7aec00 bytes 17
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934108] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934116] rfcomm_recv_data: session ffff880110b72000 state 1 dlci 26 pf 16
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934132] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934139] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 39 tx_credits 15
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934198] rfcomm_sock_sendmsg: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934201] rfcomm_dlc_send: dlc ffff8800c3959a00 mtu 400 len 14
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934206] rfcomm_sock_sendmsg: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934209] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934211] rfcomm_dlc_send: dlc ffff8800c3959a00 mtu 400 len 6
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934213] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934216] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 39 tx_credits 15
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934219] rfcomm_send_frame: session ffff880110b72000 len 18
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934222] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934225] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 18
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934230] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90cd00 len 22 priority 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934235] rfcomm_send_frame: session ffff880110b72000 len 10
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934238] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934240] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 10
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934243] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90d300 len 14 priority 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934249] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934251] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:36 fdanis-linux kernel: [ 6343.934254] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 39 tx_credits 13
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319264] l2cap_recv_acldata: conn ffff880081914a00 len 20 flags 0x2
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319271] l2cap_recv_frame: len 16, cid 0x0040
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319275] l2cap_data_channel: chan ffff88010e7a9000, len 16
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319281] rfcomm_l2data_ready: ffff88010e7aec00 bytes 16
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319299] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319305] rfcomm_recv_data: session ffff880110b72000 state 1 dlci 26 pf 16
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319318] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319324] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 38 tx_credits 15
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319398] rfcomm_sock_sendmsg: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319405] rfcomm_dlc_send: dlc ffff8800c3959a00 mtu 400 len 132
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319415] rfcomm_sock_sendmsg: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319419] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319424] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319427] rfcomm_dlc_send: dlc ffff8800c3959a00 mtu 400 len 6
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319434] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 38 tx_credits 15
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319440] rfcomm_send_frame: session ffff880110b72000 len 137
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319449] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319452] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 137
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319457] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90c400 len 141 priority 0
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319463] rfcomm_send_frame: session ffff880110b72000 len 10
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319465] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319467] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 10
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319470] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90c000 len 14 priority 0
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319477] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319479] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.319482] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 38 tx_credits 13
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710808] l2cap_recv_acldata: conn ffff880081914a00 len 19 flags 0x2
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710814] l2cap_recv_frame: len 15, cid 0x0040
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710818] l2cap_data_channel: chan ffff88010e7a9000, len 15
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710824] rfcomm_l2data_ready: ffff88010e7aec00 bytes 15
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710843] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710852] rfcomm_recv_data: session ffff880110b72000 state 1 dlci 26 pf 16
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710860] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710863] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 37 tx_credits 15
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710933] rfcomm_sock_sendmsg: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710940] rfcomm_dlc_send: dlc ffff8800c3959a00 mtu 400 len 24
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710948] rfcomm_sock_sendmsg: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710952] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710959] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710961] rfcomm_dlc_send: dlc ffff8800c3959a00 mtu 400 len 6
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710964] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 37 tx_credits 15
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710967] rfcomm_send_frame: session ffff880110b72000 len 28
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710970] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710974] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 28
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710979] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90d900 len 32 priority 0
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710986] rfcomm_send_frame: session ffff880110b72000 len 10
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710988] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710990] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 10
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.710993] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90cb00 len 14 priority 0
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.711000] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.711002] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:37 fdanis-linux kernel: [ 6344.711004] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 37 tx_credits 13
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097302] l2cap_recv_acldata: conn ffff880081914a00 len 26 flags 0x2
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097309] l2cap_recv_frame: len 22, cid 0x0040
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097313] l2cap_data_channel: chan ffff88010e7a9000, len 22
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097319] rfcomm_l2data_ready: ffff88010e7aec00 bytes 22
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097337] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097345] rfcomm_recv_data: session ffff880110b72000 state 1 dlci 26 pf 16
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097353] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097355] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 36 tx_credits 15
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097422] rfcomm_sock_sendmsg: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097429] rfcomm_dlc_send: dlc ffff8800c3959a00 mtu 400 len 6
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097439] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097444] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097448] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 36 tx_credits 15
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097456] rfcomm_send_frame: session ffff880110b72000 len 10
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097459] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097462] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 10
Aug  3 11:02:37 fdanis-linux kernel: [ 6345.097466] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90dc00 len 14 priority 0
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485057] l2cap_recv_acldata: conn ffff880081914a00 len 20 flags 0x2
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485061] l2cap_recv_frame: len 16, cid 0x0040
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485063] l2cap_data_channel: chan ffff88010e7a9000, len 16
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485067] rfcomm_l2data_ready: ffff88010e7aec00 bytes 16
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485080] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485084] rfcomm_recv_data: session ffff880110b72000 state 1 dlci 26 pf 16
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485098] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485104] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 35 tx_credits 15
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485170] rfcomm_sock_sendmsg: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485177] rfcomm_dlc_send: dlc ffff8800c3959a00 mtu 400 len 6
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485191] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485193] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485196] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 35 tx_credits 15
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485199] rfcomm_send_frame: session ffff880110b72000 len 10
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485202] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485205] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 10
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.485210] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90c100 len 14 priority 0
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496249] l2cap_recv_acldata: conn ffff880081914a00 len 19 flags 0x2
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496253] l2cap_recv_frame: len 15, cid 0x0040
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496256] l2cap_data_channel: chan ffff88010e7a9000, len 15
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496260] rfcomm_l2data_ready: ffff88010e7aec00 bytes 15
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496303] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496306] rfcomm_recv_data: session ffff880110b72000 state 1 dlci 26 pf 16
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496312] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496315] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 34 tx_credits 15
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496418] rfcomm_sock_sendmsg: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496421] rfcomm_dlc_send: dlc ffff8800c3959a00 mtu 400 len 6
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496427] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496430] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496433] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 34 tx_credits 15
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496436] rfcomm_send_frame: session ffff880110b72000 len 10
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496438] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496441] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 10
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.496446] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90df00 len 14 priority 0
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531182] l2cap_recv_acldata: conn ffff880081914a00 len 20 flags 0x2
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531188] l2cap_recv_frame: len 16, cid 0x0040
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531193] l2cap_data_channel: chan ffff88010e7a9000, len 16
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531199] rfcomm_l2data_ready: ffff88010e7aec00 bytes 16
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531218] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531225] rfcomm_recv_data: session ffff880110b72000 state 1 dlci 26 pf 16
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531236] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531242] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 33 tx_credits 15
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531379] rfcomm_sock_sendmsg: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531383] rfcomm_dlc_send: dlc ffff8800c3959a00 mtu 400 len 6
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531660] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 0
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531663] rfcomm_process_dlcs: session ffff880110b72000 state 1
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531666] rfcomm_process_tx: dlc ffff8800c3959a00 state 1 cfc 40 rx_credits 33 tx_credits 15
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531669] rfcomm_send_frame: session ffff880110b72000 len 10
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531672] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531676] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 10
Aug  3 11:02:38 fdanis-linux kernel: [ 6345.531679] l2cap_do_send: chan ffff88010e7a9000, skb ffff88003f90c700 len 14 priority 0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.155133] l2cap_sock_create: sock ffff88000f207480
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.155143] l2cap_chan_create: sk ffff88010e7a9c00 chan ffff88010e7adc00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.155147] l2cap_sock_init: sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.155157] l2cap_sock_bind: sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.155165] l2cap_sock_setsockopt: sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.155180] l2cap_sock_connect: sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.155184] l2cap_chan_connect: 5C:AC:4C:FF:0B:FE -> 10:04:14:D1:96:1C psm 0x1001
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.155190] __l2cap_chan_add: conn ffff880081914a00, psm 0x19, dcid 0x0000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.155193] __l2cap_state_change: chan ffff88010e7adc00 BT_BOUND -> BT_CONNECT
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.155198] l2cap_build_cmd: conn ffff880081914a00, code 0x02, ident 0x04, len 4
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.155200] l2cap_send_cmd: code 0x02
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.184544] l2cap_recv_acldata: conn ffff880081914a00 len 16 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.184550] l2cap_recv_frame: len 12, cid 0x0001
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.184553] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.184556] l2cap_sig_channel: code 0x03 len 8 id 0x04
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.184559] l2cap_connect_rsp: dcid 0x0042 scid 0x0041 result 0x00 status 0x00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.184563] __l2cap_state_change: chan ffff88010e7adc00 BT_CONNECT -> BT_CONFIG
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.184566] l2cap_build_conf_req: chan ffff88010e7adc00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.184569] l2cap_build_cmd: conn ffff880081914a00, code 0x04, ident 0x05, len 4
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.184572] l2cap_send_cmd: code 0x04
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.185794] l2cap_recv_acldata: conn ffff880081914a00 len 16 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.185800] l2cap_recv_frame: len 12, cid 0x0001
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.185803] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.185806] l2cap_sig_channel: code 0x04 len 8 id 0x07
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.185809] l2cap_config_req: dcid 0x0041 flags 0x00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.185812] l2cap_parse_conf_req: chan ffff88010e7adc00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.185815] l2cap_get_conf_opt: type 0x01 len 2 val 0x2a0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.185818] l2cap_add_conf_opt: type 0x01 len 2 val 0x2a0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.185821] l2cap_build_cmd: conn ffff880081914a00, code 0x05, ident 0x07, len 10
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.185824] l2cap_send_cmd: code 0x05
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190748] l2cap_recv_acldata: conn ffff880081914a00 len 14 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190754] l2cap_recv_frame: len 10, cid 0x0001
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190757] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190760] l2cap_sig_channel: code 0x05 len 6 id 0x05
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190764] l2cap_config_rsp: scid 0x0041 flags 0x00 result 0x00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190768] l2cap_conf_rfc_get: chan ffff88010e7adc00, rsp ffff88000c00781a, len 0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190772] __l2cap_state_change: chan ffff88010e7adc00 BT_CONFIG -> BT_CONNECTED
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190775] l2cap_chan_ready: sk ffff88010e7a9c00, parent           (null)
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190779] __l2cap_state_change: chan ffff88010e7adc00 BT_CONNECTED -> BT_CONNECTED
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190833] l2cap_sock_getsockopt: sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190836] l2cap_sock_getsockopt_old: sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190840] l2cap_sock_getname: sock ffff88000f207480, sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190842] l2cap_sock_getname: sock ffff88000f207480, sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190867] l2cap_sock_create: sock ffff88000f204c80
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190872] l2cap_chan_create: sk ffff88010e7ac400 chan ffff88010e7a9400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190874] l2cap_sock_init: sk ffff88010e7ac400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190881] l2cap_sock_bind: sk ffff88010e7ac400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190886] l2cap_sock_setsockopt: sk ffff88010e7ac400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190895] l2cap_sock_connect: sk ffff88010e7ac400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190899] l2cap_chan_connect: 5C:AC:4C:FF:0B:FE -> 10:04:14:D1:96:1C psm 0x1003
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190904] __l2cap_chan_add: conn ffff880081914a00, psm 0x17, dcid 0x0000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190906] __l2cap_state_change: chan ffff88010e7a9400 BT_BOUND -> BT_CONNECT
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190910] l2cap_build_cmd: conn ffff880081914a00, code 0x02, ident 0x06, len 4
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190912] l2cap_send_cmd: code 0x02
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190932] l2cap_sock_sendmsg: sock ffff88000f207480, sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190935] l2cap_create_basic_pdu: chan ffff88010e7adc00 len 2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.190940] l2cap_do_send: chan ffff88010e7adc00, skb ffff8800969ff900 len 6 priority 0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.200736] l2cap_recv_acldata: conn ffff880081914a00 len 16 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.200741] l2cap_recv_frame: len 12, cid 0x0001
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.200786] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.200790] l2cap_sig_channel: code 0x03 len 8 id 0x06
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.200794] l2cap_connect_rsp: dcid 0x0043 scid 0x0042 result 0x00 status 0x00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.200799] __l2cap_state_change: chan ffff88010e7a9400 BT_CONNECT -> BT_CONFIG
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.200803] l2cap_build_conf_req: chan ffff88010e7a9400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.200807] l2cap_build_cmd: conn ffff880081914a00, code 0x04, ident 0x07, len 4
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.200811] l2cap_send_cmd: code 0x04
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.203215] l2cap_recv_acldata: conn ffff880081914a00 len 16 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.203222] l2cap_recv_frame: len 12, cid 0x0001
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.203226] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.203230] l2cap_sig_channel: code 0x04 len 8 id 0x08
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.203235] l2cap_config_req: dcid 0x0042 flags 0x00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.203239] l2cap_parse_conf_req: chan ffff88010e7a9400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.203244] l2cap_get_conf_opt: type 0x01 len 2 val 0x200
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.203248] l2cap_add_conf_opt: type 0x01 len 2 val 0x200
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.203253] l2cap_build_cmd: conn ffff880081914a00, code 0x05, ident 0x08, len 10
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.203257] l2cap_send_cmd: code 0x05
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.204426] l2cap_recv_acldata: conn ffff880081914a00 len 8 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.204451] l2cap_recv_frame: len 4, cid 0x0041
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.204458] l2cap_data_channel: chan ffff88010e7adc00, len 4
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.204519] l2cap_sock_sendmsg: sock ffff88000f207480, sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.204527] l2cap_create_basic_pdu: chan ffff88010e7adc00 len 3
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.204536] l2cap_do_send: chan ffff88010e7adc00, skb ffff8800969ffc00 len 7 priority 0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209462] l2cap_recv_acldata: conn ffff880081914a00 len 14 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209468] l2cap_recv_frame: len 10, cid 0x0001
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209473] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209477] l2cap_sig_channel: code 0x05 len 6 id 0x07
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209482] l2cap_config_rsp: scid 0x0042 flags 0x00 result 0x00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209488] l2cap_conf_rfc_get: chan ffff88010e7a9400, rsp ffff88000c00781a, len 0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209493] __l2cap_state_change: chan ffff88010e7a9400 BT_CONFIG -> BT_CONNECTED
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209498] l2cap_chan_ready: sk ffff88010e7ac400, parent           (null)
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209503] __l2cap_state_change: chan ffff88010e7a9400 BT_CONNECTED -> BT_CONNECTED
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209556] l2cap_sock_getsockopt: sk ffff88010e7ac400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209561] l2cap_sock_getsockopt_old: sk ffff88010e7ac400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209568] l2cap_sock_getname: sock ffff88000f204c80, sk ffff88010e7ac400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209572] l2cap_sock_getname: sock ffff88000f204c80, sk ffff88010e7ac400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.209685] input: 10:04:14:D1:96:1C as /devices/virtual/input/input20
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.211883] l2cap_recv_acldata: conn ffff880081914a00 len 20 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.211887] l2cap_recv_frame: len 16, cid 0x0041
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.211890] l2cap_data_channel: chan ffff88010e7adc00, len 16
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.212030] l2cap_sock_sendmsg: sock ffff88000f207480, sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.212034] l2cap_create_basic_pdu: chan ffff88010e7adc00 len 14
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.212038] l2cap_do_send: chan ffff88010e7adc00, skb ffff88003f90cd00 len 18 priority 0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.218130] l2cap_recv_acldata: conn ffff880081914a00 len 6 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.218136] l2cap_recv_frame: len 2, cid 0x0041
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.218140] l2cap_data_channel: chan ffff88010e7adc00, len 2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.218228] l2cap_sock_sendmsg: sock ffff88000f207480, sk ffff88010e7a9c00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.218232] l2cap_create_basic_pdu: chan ffff88010e7adc00 len 3
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.218236] l2cap_do_send: chan ffff88010e7adc00, skb ffff88003f90d400 len 7 priority 0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258108] l2cap_recv_acldata: conn ffff880081914a00 len 6 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258113] l2cap_recv_frame: len 2, cid 0x0041
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258116] l2cap_data_channel: chan ffff88010e7adc00, len 2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258201] l2cap_sock_create: sock ffff88000f206580
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258207] l2cap_chan_create: sk ffff88010d007000 chan ffff88010d005400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258209] l2cap_sock_init: sk ffff88010d007000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258217] l2cap_sock_bind: sk ffff88010d007000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258224] l2cap_sock_setsockopt: sk ffff88010d007000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258236] l2cap_sock_connect: sk ffff88010d007000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258241] l2cap_chan_connect: 5C:AC:4C:FF:0B:FE -> 10:04:14:D1:96:1C psm 0x1005
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258247] __l2cap_chan_add: conn ffff880081914a00, psm 0x19, dcid 0x0000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258250] __l2cap_state_change: chan ffff88010d005400 BT_BOUND -> BT_CONNECT
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258255] l2cap_build_cmd: conn ffff880081914a00, code 0x02, ident 0x08, len 4
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.258258] l2cap_send_cmd: code 0x02
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.265505] l2cap_recv_acldata: conn ffff880081914a00 len 16 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.265512] l2cap_recv_frame: len 12, cid 0x0001
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.265515] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.265519] l2cap_sig_channel: code 0x03 len 8 id 0x08
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.265523] l2cap_connect_rsp: dcid 0x0044 scid 0x0043 result 0x00 status 0x00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.265528] __l2cap_state_change: chan ffff88010d005400 BT_CONNECT -> BT_CONFIG
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.265532] l2cap_build_conf_req: chan ffff88010d005400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.265535] l2cap_build_cmd: conn ffff880081914a00, code 0x04, ident 0x09, len 4
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.265539] l2cap_send_cmd: code 0x04
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.266741] l2cap_recv_acldata: conn ffff880081914a00 len 16 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.266744] l2cap_recv_frame: len 12, cid 0x0001
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.266746] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.266748] l2cap_sig_channel: code 0x04 len 8 id 0x09
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.266751] l2cap_config_req: dcid 0x0043 flags 0x00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.266754] l2cap_parse_conf_req: chan ffff88010d005400
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.266757] l2cap_get_conf_opt: type 0x01 len 2 val 0x2a0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.266760] l2cap_add_conf_opt: type 0x01 len 2 val 0x2a0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.266763] l2cap_build_cmd: conn ffff880081914a00, code 0x05, ident 0x09, len 10
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.266766] l2cap_send_cmd: code 0x05
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270469] l2cap_recv_acldata: conn ffff880081914a00 len 14 flags 0x2
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270476] l2cap_recv_frame: len 10, cid 0x0001
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270479] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270482] l2cap_sig_channel: code 0x05 len 6 id 0x09
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270485] l2cap_config_rsp: scid 0x0043 flags 0x00 result 0x00
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270489] l2cap_conf_rfc_get: chan ffff88010d005400, rsp ffff88000c00501a, len 0
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270492] __l2cap_state_change: chan ffff88010d005400 BT_CONFIG -> BT_CONNECTED
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270496] l2cap_chan_ready: sk ffff88010d007000, parent           (null)
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270498] __l2cap_state_change: chan ffff88010d005400 BT_CONNECTED -> BT_CONNECTED
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270555] l2cap_sock_getsockopt: sk ffff88010d007000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270557] l2cap_sock_getsockopt_old: sk ffff88010d007000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270561] l2cap_sock_getname: sock ffff88000f206580, sk ffff88010d007000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270563] l2cap_sock_getname: sock ffff88000f206580, sk ffff88010d007000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270573] l2cap_sock_setsockopt: sk ffff88010d007000
Aug  3 11:02:39 fdanis-linux kernel: [ 6347.270575] l2cap_sock_setsockopt: sk ffff88010d007000


Aug  3 11:02:51 fdanis-linux kernel: [ 6358.966869] l2cap_sock_sendmsg: sock ffff88000f207480, sk ffff88010e7a9c00
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.966940] l2cap_create_basic_pdu: chan ffff88010e7adc00 len 3
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.966946] l2cap_do_send: chan ffff88010e7adc00, skb ffff8800d2acba00 len 7 priority 0
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.995894] l2cap_recv_acldata: conn ffff880081914a00 len 6 flags 0x2
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.995899] l2cap_recv_frame: len 2, cid 0x0041
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.995902] l2cap_data_channel: chan ffff88010e7adc00, len 2
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.995977] l2cap_sock_shutdown: sock ffff88000f206580, sk ffff88010d007000
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.995982] l2cap_chan_close: chan ffff88010d005400 state BT_CONNECTED sk ffff88010d007000
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.995988] l2cap_build_cmd: conn ffff880081914a00, code 0x06, ident 0x0a, len 4
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.995993] l2cap_send_cmd: code 0x06
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.995999] __l2cap_state_change: chan ffff88010d005400 BT_CONNECTED -> BT_DISCONN
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.996006] l2cap_sock_release: sock ffff88000f206580, sk ffff88010d007000
Aug  3 11:02:51 fdanis-linux kernel: [ 6358.996009] l2cap_sock_shutdown: sock ffff88000f206580, sk ffff88010d007000
Aug  3 11:02:51 fdanis-linux kernel: [ 6359.001949] l2cap_recv_acldata: conn ffff880081914a00 len 12 flags 0x2
Aug  3 11:02:51 fdanis-linux kernel: [ 6359.001956] l2cap_recv_frame: len 8, cid 0x0001
Aug  3 11:02:51 fdanis-linux kernel: [ 6359.001961] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:51 fdanis-linux kernel: [ 6359.001966] l2cap_sig_channel: code 0x07 len 4 id 0x0a
Aug  3 11:02:51 fdanis-linux kernel: [ 6359.001971] l2cap_disconnect_rsp: dcid 0x0044 scid 0x0043
Aug  3 11:02:51 fdanis-linux kernel: [ 6359.001976] l2cap_chan_del: chan ffff88010d005400, conn ffff880081914a00, err 0
Aug  3 11:02:51 fdanis-linux kernel: [ 6359.001982] __l2cap_state_change: chan ffff88010d005400 BT_DISCONN -> BT_CLOSED
Aug  3 11:02:51 fdanis-linux kernel: [ 6359.001988] l2cap_sock_kill: sk ffff88010d007000 state BT_CLOSED
Aug  3 11:02:51 fdanis-linux kernel: [ 6359.001994] l2cap_sock_destruct: sk ffff88010d007000
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121505] l2cap_sock_release: sock ffff88000f207480, sk ffff88010e7a9c00
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121512] l2cap_sock_shutdown: sock ffff88000f207480, sk ffff88010e7a9c00
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121519] l2cap_chan_close: chan ffff88010e7adc00 state BT_CONNECTED sk ffff88010e7a9c00
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121531] l2cap_build_cmd: conn ffff880081914a00, code 0x06, ident 0x0b, len 4
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121537] l2cap_send_cmd: code 0x06
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121550] __l2cap_state_change: chan ffff88010e7adc00 BT_CONNECTED -> BT_DISCONN
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121699] l2cap_sock_release: sock ffff88000f204c80, sk ffff88010e7ac400
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121702] l2cap_sock_shutdown: sock ffff88000f204c80, sk ffff88010e7ac400
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121705] l2cap_chan_close: chan ffff88010e7a9400 state BT_CONNECTED sk ffff88010e7ac400
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121710] l2cap_build_cmd: conn ffff880081914a00, code 0x06, ident 0x0c, len 4
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121712] l2cap_send_cmd: code 0x06
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.121716] __l2cap_state_change: chan ffff88010e7a9400 BT_CONNECTED -> BT_DISCONN
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.151578] l2cap_recv_acldata: conn ffff880081914a00 len 12 flags 0x2
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.151583] l2cap_recv_frame: len 8, cid 0x0001
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.151585] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.151588] l2cap_sig_channel: code 0x07 len 4 id 0x0b
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.151591] l2cap_disconnect_rsp: dcid 0x0042 scid 0x0041
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.151595] l2cap_chan_del: chan ffff88010e7adc00, conn ffff880081914a00, err 0
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.151599] __l2cap_state_change: chan ffff88010e7adc00 BT_DISCONN -> BT_CLOSED
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.151603] l2cap_sock_kill: sk ffff88010e7a9c00 state BT_CLOSED
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.151607] l2cap_sock_destruct: sk ffff88010e7a9c00
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.152730] l2cap_recv_acldata: conn ffff880081914a00 len 12 flags 0x2
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.152733] l2cap_recv_frame: len 8, cid 0x0001
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.152735] l2cap_raw_recv: conn ffff880081914a00
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.152737] l2cap_sig_channel: code 0x07 len 4 id 0x0c
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.152739] l2cap_disconnect_rsp: dcid 0x0043 scid 0x0042
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.152742] l2cap_chan_del: chan ffff88010e7a9400, conn ffff880081914a00, err 0
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.152745] __l2cap_state_change: chan ffff88010e7a9400 BT_DISCONN -> BT_CLOSED
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.152749] l2cap_sock_kill: sk ffff88010e7ac400 state BT_CLOSED
Aug  3 11:02:52 fdanis-linux kernel: [ 6360.152751] l2cap_sock_destruct: sk ffff88010e7ac400


Aug  3 11:03:12 fdanis-linux bluetoothd[1434]: Disconnected from 10:04:14:D1:96:1C, /org/bluez/1434/hci0/dev_10_04_14_D1_96_1C
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475038] rfcomm_sock_release: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475041] rfcomm_sock_shutdown: sock ffff88000f204a00, sk ffff88010e7ad400
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475044] __rfcomm_sock_close: sk ffff88010e7ad400 state 1 socket ffff88000f204a00
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475047] __rfcomm_dlc_close: dlc ffff8800c3959a00 state 1 dlci 26 err 0 session ffff880110b72000
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475050] rfcomm_send_disc: ffff880110b72000 dlci 26
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475052] rfcomm_send_cmd: ffff880110b72000 cmd 83
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475054] rfcomm_send_frame: session ffff880110b72000 len 4
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475057] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475059] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 4
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475064] l2cap_do_send: chan ffff88010e7a9000, skb ffff88000e723c00 len 8 priority 0
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475075] rfcomm_dlc_set_timer: dlc ffff8800c3959a00 state 8 timeout 5000
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475078] rfcomm_sock_kill: sk ffff88010e7ad400 state 1 refcnt 2
Aug  3 11:03:12 fdanis-linux kernel: [ 6379.475081] rfcomm_sock_destruct: sk ffff88010e7ad400 dlc ffff8800c3959a00
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574751] l2cap_recv_acldata: conn ffff880081914a00 len 8 flags 0x2
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574758] l2cap_recv_frame: len 4, cid 0x0040
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574763] l2cap_data_channel: chan ffff88010e7a9000, len 4
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574769] rfcomm_l2data_ready: ffff88010e7aec00 bytes 4
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574787] rfcomm_process_rx: session ffff880110b72000 state 1 qlen 1
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574793] rfcomm_recv_ua: session ffff880110b72000 state 1 dlci 26
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574798] __rfcomm_dlc_close: dlc ffff8800c3959a00 state 9 dlci 26 err 0 session ffff880110b72000
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574802] rfcomm_dlc_clear_timer: dlc ffff8800c3959a00 state 9
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574806] rfcomm_dlc_unlink: dlc ffff8800c3959a00 refcnt 1 session ffff880110b72000
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574810] rfcomm_dlc_free: ffff8800c3959a00
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574815] rfcomm_session_set_timer: session ffff880110b72000 state 1 timeout 500
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574819] rfcomm_send_disc: ffff880110b72000 dlci 0
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574822] rfcomm_send_cmd: ffff880110b72000 cmd 83
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574826] rfcomm_send_frame: session ffff880110b72000 len 4
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574830] l2cap_sock_sendmsg: sock ffff8800c7792800, sk ffff88010e7aec00
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574835] l2cap_create_basic_pdu: chan ffff88010e7a9000 len 4
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574841] l2cap_do_send: chan ffff88010e7a9000, skb ffff8800c3bbc900 len 8 priority 0
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574850] rfcomm_session_clear_timer: session ffff880110b72000 state 8
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.574857] rfcomm_process_dlcs: session ffff880110b72000 state 8
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.580975] l2cap_recv_acldata: conn ffff880081914a00 len 8 flags 0x2
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.580984] l2cap_recv_frame: len 4, cid 0x0040
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.580991] l2cap_data_channel: chan ffff88010e7a9000, len 4
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.580998] rfcomm_l2data_ready: ffff88010e7aec00 bytes 4
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.581014] rfcomm_process_rx: session ffff880110b72000 state 8 qlen 1
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.581022] rfcomm_recv_ua: session ffff880110b72000 state 8 dlci 0
Aug  3 11:03:13 fdanis-linux kernel: [ 6380.581030] rfcomm_process_dlcs: session ffff880110b72000 state 8




^ permalink raw reply

* [PATCH v17 15/15] audio: Add fast connectable to telephony interface
From: Frédéric Danis @ 2012-08-03 12:07 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1343995640-19784-1-git-send-email-frederic.danis@linux.intel.com>

---
 audio/telephony.c |  107 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 doc/audio-api.txt |   26 +++++++++++++
 2 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/audio/telephony.c b/audio/telephony.c
index 5626985..8efc520 100644
--- a/audio/telephony.c
+++ b/audio/telephony.c
@@ -185,8 +185,19 @@ static struct telephony_agent *find_agent(struct btd_adapter *adapter,
 
 static void free_agent(struct telephony_agent *agent)
 {
+	struct btd_adapter *adapter = agent->btd_adapter;
 	DBusMessage *msg;
 
+	/* if there is no more agent for this adapter and it has been set to
+	 * fast connectable mode, reset it to FALSE
+	 */
+	if (find_agent(adapter, NULL, NULL, NULL) == NULL &&
+			btd_adapter_get_fast_connectable(adapter)) {
+		if (btd_adapter_set_fast_connectable(adapter, FALSE))
+			error("Changing fast connectable for hci%d failed",
+				adapter_get_dev_id(adapter));
+	}
+
 	if (agent->record_id)
 		remove_record_from_server(agent->record_id);
 
@@ -1460,12 +1471,106 @@ static DBusMessage *unregister_agent(DBusConnection *conn,
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
 
+static DBusMessage *telephony_get_properties(DBusConnection *conn,
+					DBusMessage *msg, void *data)
+{
+	struct btd_adapter *adapter = data;
+	gboolean fast_connectable;
+	DBusMessage *reply;
+	DBusMessageIter iter;
+	DBusMessageIter dict;
+
+	reply = dbus_message_new_method_return(msg);
+	if (!reply)
+		return NULL;
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+	/* FastConnectable */
+	fast_connectable = btd_adapter_get_fast_connectable(adapter);
+	dict_append_entry(&dict, "FastConnectable", DBUS_TYPE_BOOLEAN,
+			  &fast_connectable);
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	return reply;
+}
+
+static DBusMessage *telephony_set_property(DBusConnection *conn,
+					DBusMessage *msg, void *data)
+{
+	struct btd_adapter *adapter = data;
+	const char *property;
+	DBusMessageIter iter;
+	DBusMessageIter sub;
+	gboolean enable;
+	DBusMessage *reply;
+
+	if (!dbus_message_iter_init(msg, &iter))
+		return btd_error_invalid_args(msg);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+		return btd_error_invalid_args(msg);
+
+	dbus_message_iter_get_basic(&iter, &property);
+	dbus_message_iter_next(&iter);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+		return btd_error_invalid_args(msg);
+	dbus_message_iter_recurse(&iter, &sub);
+
+	if (g_str_equal("FastConnectable", property)) {
+		if (dbus_message_iter_get_arg_type(&sub) !=
+				DBUS_TYPE_BOOLEAN)
+			return btd_error_invalid_args(msg);
+
+		dbus_message_iter_get_basic(&sub, &enable);
+
+		reply = dbus_message_new_method_return(msg);
+		if (!reply)
+			return NULL;
+
+		if (btd_adapter_set_fast_connectable(adapter, enable)) {
+			error("Changing fast connectable for hci%d failed",
+				adapter_get_dev_id(adapter));
+			dbus_message_unref(reply);
+			return btd_error_failed(msg,
+					"Changing to fast connectable failed");
+		}
+
+		emit_property_changed(conn, adapter_get_path(adapter),
+					AUDIO_TELEPHONY_INTERFACE,
+					"FastConnectable",
+					DBUS_TYPE_BOOLEAN, &enable);
+		return reply;
+	}
+
+	return btd_error_invalid_args(msg);
+}
+
 static const GDBusMethodTable telsrv_methods[] = {
 	{ GDBUS_METHOD("RegisterAgent",
 			GDBUS_ARGS({ "agent", "o" }, { "properties", "a{sv}" }),
 			NULL, register_agent) },
 	{ GDBUS_METHOD("UnregisterAgent",
 			GDBUS_ARGS({ "agent", "o" }), NULL, unregister_agent) },
+	{ GDBUS_METHOD("GetProperties",
+			NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
+			telephony_get_properties) },
+	{ GDBUS_METHOD("SetProperty",
+			GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
+			telephony_set_property) },
+	{ }
+};
+
+static const GDBusSignalTable telsrv_signals[] = {
+	{ GDBUS_SIGNAL("PropertyChanged",
+			GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
 	{ }
 };
 
@@ -1484,7 +1589,7 @@ int telephony_adapter_init(struct btd_adapter *adapter)
 
 	if (!g_dbus_register_interface(connection, path,
 					AUDIO_TELEPHONY_INTERFACE,
-					telsrv_methods, NULL,
+					telsrv_methods, telsrv_signals,
 					NULL, adapter, path_unregister)) {
 		error("D-Bus failed to register %s interface",
 				AUDIO_TELEPHONY_INTERFACE);
diff --git a/doc/audio-api.txt b/doc/audio-api.txt
index e8bb210..3dd497f 100644
--- a/doc/audio-api.txt
+++ b/doc/audio-api.txt
@@ -335,6 +335,32 @@ Methods		void RegisterAgent(object path, dict properties)
 
 			Unregister sender agent.
 
+		dict GetProperties()
+
+			Returns all properties for the interface. See the
+			properties section for available properties.
+
+			Possible Errors: org.bluez.Error.InvalidArguments
+
+		void SetProperty(string name, variant value)
+
+			Changes the value of the specified property. Only
+			properties that are listed as read-write are changeable.
+			On success this will emit a PropertyChanged signal.
+
+			Possible Errors: org.bluez.Error.DoesNotExist
+					 org.bluez.Error.InvalidArguments
+
+Signals		void PropertyChanged(string name, variant value)
+
+			This signal indicates a changed value of the given
+			property.
+
+Properties	boolean FastConnectable  [readwrite]
+
+			Indicates if there is adapter is in fast connectable
+			mode.
+
 TelephonyAgent hierarchy
 ========================
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v17 14/15] adapter: Add API to get fast connectable mode
From: Frédéric Danis @ 2012-08-03 12:07 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1343995640-19784-1-git-send-email-frederic.danis@linux.intel.com>

---
 src/adapter.c |   15 ++++++++++++++-
 src/adapter.h |    1 +
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/adapter.c b/src/adapter.c
index b7691d0..24fa704 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -151,6 +151,8 @@ struct btd_adapter {
 	GSList *pin_callbacks;
 
 	GSList *loaded_drivers;
+
+	gboolean fast_connectable;
 };
 
 static void dev_info_free(void *data)
@@ -3391,10 +3393,21 @@ void btd_adapter_unregister_powered_callback(struct btd_adapter *adapter,
 int btd_adapter_set_fast_connectable(struct btd_adapter *adapter,
 							gboolean enable)
 {
+	int ret;
+
 	if (!adapter->up)
 		return -EINVAL;
 
-	return mgmt_set_fast_connectable(adapter->dev_id, enable);
+	ret = mgmt_set_fast_connectable(adapter->dev_id, enable);
+	if (ret == 0)
+		adapter->fast_connectable = enable;
+
+	return ret;
+}
+
+gboolean btd_adapter_get_fast_connectable(struct btd_adapter *adapter)
+{
+	return adapter->fast_connectable;
 }
 
 int btd_adapter_read_clock(struct btd_adapter *adapter, bdaddr_t *bdaddr,
diff --git a/src/adapter.h b/src/adapter.h
index d8a1bb1..6e22dbc 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -185,6 +185,7 @@ void btd_adapter_unregister_powered_callback(struct btd_adapter *adapter,
  * type to default values. Valid for both connectable and discoverable modes. */
 int btd_adapter_set_fast_connectable(struct btd_adapter *adapter,
 							gboolean enable);
+gboolean btd_adapter_get_fast_connectable(struct btd_adapter *adapter);
 
 int btd_adapter_read_clock(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 				int which, int timeout, uint32_t *clock,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v17 13/15] audio: Add SAP GW to org.bluez.Telephony
From: Frédéric Danis @ 2012-08-03 12:07 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1343995640-19784-1-git-send-email-frederic.danis@linux.intel.com>

---
 audio/telephony.c        |   72 +++++++++++++++++++++++++++++++++++++++++++++-
 doc/assigned-numbers.txt |    1 +
 2 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/audio/telephony.c b/audio/telephony.c
index f80986b..5626985 100644
--- a/audio/telephony.c
+++ b/audio/telephony.c
@@ -62,6 +62,7 @@
 #define DEFAULT_HS_AG_CHANNEL 12
 #define DEFAULT_HF_HS_CHANNEL 7
 #define DEFAULT_HF_AG_CHANNEL 13
+#define DEFAULT_SAP_GW_CHANNEL 8
 
 struct telephony_agent;
 
@@ -79,6 +80,7 @@ struct telephony_agent;
 struct profile_config {
 	const char		*uuid;		/* agent property UUID */
 	uint8_t			channel;
+	BtIOSecLevel		sec_level;
 	const char		*r_uuid;
 	uint16_t		r_class;
 	uint16_t		r_profile;
@@ -852,6 +854,61 @@ static sdp_record_t *hfp_hs_record(struct telephony_agent *agent)
 	return record;
 }
 
+static sdp_record_t *sap_gw_record(struct telephony_agent *agent)
+{
+	sdp_list_t *apseq, *aproto, *profiles, *proto[2], *root, *svclass_id;
+	uuid_t sap_uuid, gt_uuid, root_uuid, l2cap, rfcomm;
+	sdp_profile_desc_t profile;
+	sdp_record_t *record;
+	sdp_data_t *ch;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	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(&sap_uuid, SAP_SVCLASS_ID);
+	svclass_id = sdp_list_append(NULL, &sap_uuid);
+	sdp_uuid16_create(&gt_uuid, GENERIC_TELEPHONY_SVCLASS_ID);
+	svclass_id = sdp_list_append(svclass_id, &gt_uuid);
+
+	sdp_set_service_classes(record, svclass_id);
+	sdp_list_free(svclass_id, NULL);
+
+	sdp_uuid16_create(&profile.uuid, SAP_PROFILE_ID);
+	profile.version = agent->version;
+	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);
+	apseq = sdp_list_append(NULL, proto[0]);
+
+	sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
+	proto[1] = sdp_list_append(NULL, &rfcomm);
+	ch = sdp_data_alloc(SDP_UINT8, &agent->config->channel);
+	proto[1] = sdp_list_append(proto[1], ch);
+	apseq = sdp_list_append(apseq, proto[1]);
+
+	aproto = sdp_list_append(NULL, apseq);
+	sdp_set_access_protos(record, aproto);
+
+	sdp_set_info_attr(record, "SIM Access Server", NULL, NULL);
+
+	sdp_data_free(ch);
+	sdp_list_free(proto[0], NULL);
+	sdp_list_free(proto[1], NULL);
+	sdp_list_free(apseq, NULL);
+	sdp_list_free(aproto, NULL);
+
+	return record;
+}
+
 static void gateway_auth_cb(DBusError *derr, void *user_data)
 {
 	struct audio_device *au_dev = user_data;
@@ -1209,6 +1266,7 @@ drop:
 static struct profile_config default_configs[] = {
 	{ DUN_GW_UUID,
 		DEFAULT_DUN_GW_CHANNEL,
+		BT_IO_SEC_MEDIUM,
 		NULL,
 		0,
 		0,
@@ -1217,6 +1275,7 @@ static struct profile_config default_configs[] = {
 		client_newconnection_reply },
 	{ HSP_AG_UUID,
 		DEFAULT_HS_AG_CHANNEL,
+		BT_IO_SEC_MEDIUM,
 		HSP_HS_UUID,
 		HEADSET_SVCLASS_ID,
 		HEADSET_PROFILE_ID,
@@ -1225,6 +1284,7 @@ static struct profile_config default_configs[] = {
 		hs_newconnection_reply },
 	{ HFP_HS_UUID,
 		DEFAULT_HF_HS_CHANNEL,
+		BT_IO_SEC_MEDIUM,
 		HFP_AG_UUID,
 		HANDSFREE_AGW_SVCLASS_ID,
 		HANDSFREE_PROFILE_ID,
@@ -1233,12 +1293,22 @@ static struct profile_config default_configs[] = {
 		ag_newconnection_reply },
 	{ HFP_AG_UUID,
 		DEFAULT_HF_AG_CHANNEL,
+		BT_IO_SEC_MEDIUM,
 		HFP_HS_UUID,
 		HANDSFREE_SVCLASS_ID,
 		HANDSFREE_PROFILE_ID,
 		hfp_ag_record,
 		ag_confirm,
 		hs_newconnection_reply },
+	{ SAP_UUID,
+		DEFAULT_SAP_GW_CHANNEL,
+		BT_IO_SEC_HIGH,
+		NULL,
+		0,
+		0,
+		sap_gw_record,
+		client_confirm,
+		client_newconnection_reply },
 };
 
 static void agent_disconnect_cb(DBusConnection *conn, void *user_data)
@@ -1338,7 +1408,7 @@ static DBusMessage *register_agent(DBusConnection *conn,
 				agent, NULL, &err,
 				BT_IO_OPT_SOURCE_BDADDR, &src,
 				BT_IO_OPT_CHANNEL, agent->config->channel,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+				BT_IO_OPT_SEC_LEVEL, agent->config->sec_level,
 				BT_IO_OPT_MASTER, master,
 				BT_IO_OPT_INVALID);
 	if (agent->io == NULL) {
diff --git a/doc/assigned-numbers.txt b/doc/assigned-numbers.txt
index 120d7ea..bc85cf6 100644
--- a/doc/assigned-numbers.txt
+++ b/doc/assigned-numbers.txt
@@ -10,6 +10,7 @@ Profile		Channel
 DUN		1
 HSP HS		6
 HFP HF		7
+SAP		8
 OPP		9
 FTP		10
 BIP		11
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v17 12/15] audio: Add DUN GW to org.bluez.Telephony
From: Frédéric Danis @ 2012-08-03 12:07 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1343995640-19784-1-git-send-email-frederic.danis@linux.intel.com>

---
 audio/telephony.c |  302 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 295 insertions(+), 7 deletions(-)

diff --git a/audio/telephony.c b/audio/telephony.c
index dc76d60..f80986b 100644
--- a/audio/telephony.c
+++ b/audio/telephony.c
@@ -39,6 +39,7 @@
 
 #include "btio.h"
 #include "../src/adapter.h"
+#include "../src/manager.h"
 #include "../src/device.h"
 
 #include "log.h"
@@ -56,6 +57,7 @@
 #define AUDIO_TELEPHONY_INTERFACE "org.bluez.Telephony"
 #define AUDIO_TELEPHONY_AGENT_INTERFACE "org.bluez.TelephonyAgent"
 
+#define DEFAULT_DUN_GW_CHANNEL 1
 #define DEFAULT_HS_HS_CHANNEL 6
 #define DEFAULT_HS_AG_CHANNEL 12
 #define DEFAULT_HF_HS_CHANNEL 7
@@ -123,7 +125,8 @@ struct telephony_device {
 	struct profile_config	*config;	/* default configuration */
 	char			*name;		/* agent DBus bus id */
 	char			*path;		/* agent object path */
-	struct audio_device	*au_dev;	/* Audio device for HSP/HFP */
+	struct audio_device	*au_dev;	/* Audio device for HSP/HFP
+						 * or NULL for DUN/SAP */
 	uint16_t		version;	/* remote profile version */
 	uint16_t		features;	/* remote supported features */
 	GIOChannel		*rfcomm;	/* connected RFCOMM channel */
@@ -132,6 +135,21 @@ struct telephony_device {
 	DBusPendingCall		*call;		/* D-Bus pending call */
 };
 
+/*
+ * Connecting device
+ *
+ * Used for DUN and SAP gateway profiles in place of the audio device structure
+ * to store informations during connection phase, from device connection up to
+ * authentication completion.
+ */
+struct connecting_device {
+	const char		*uuid;
+	struct btd_device	*btd_dev;
+	bdaddr_t		src, dst;
+	GIOChannel		*tmp_rfcomm;
+	guint			preauth_id;
+};
+
 static DBusConnection *connection = NULL;
 
 static GSList *agents = NULL;	/* server list */
@@ -298,6 +316,201 @@ static gboolean agent_sendfd(struct telephony_device *tel_dev, int fd,
 	return TRUE;
 }
 
+static void rfcomm_channel_close(GIOChannel *chan)
+{
+	int sock;
+
+	sock = g_io_channel_unix_get_fd(chan);
+	shutdown(sock, SHUT_RDWR);
+
+	g_io_channel_shutdown(chan, TRUE, NULL);
+	g_io_channel_unref(chan);
+}
+
+static gboolean client_dev_disconnect_cb(GIOChannel *chan, GIOCondition cond,
+						gpointer data)
+{
+	struct telephony_device *tel_dev = data;
+
+	if (cond & G_IO_NVAL)
+		return FALSE;
+
+	rfcomm_channel_close(tel_dev->rfcomm);
+	tel_dev->rfcomm = NULL;
+	telephony_device_disconnect(tel_dev);
+
+	return FALSE;
+}
+
+static void client_newconnection_reply(DBusPendingCall *call,
+					void *user_data)
+{
+	struct telephony_device *tel_dev = user_data;
+	DBusMessage *reply = dbus_pending_call_steal_reply(call);
+	DBusError derr;
+
+	dbus_error_init(&derr);
+	if (dbus_set_error_from_message(&derr, reply)) {
+		DBG("Agent reply: %s", derr.message);
+		dbus_error_free(&derr);
+		rfcomm_channel_close(tel_dev->rfcomm);
+		tel_dev->rfcomm = NULL;
+		telephony_device_disconnect(tel_dev);
+		goto done;
+	}
+
+	DBG("Agent reply: file descriptor passed successfully");
+	g_io_add_watch(tel_dev->rfcomm, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+			client_dev_disconnect_cb, tel_dev);
+
+done:
+	dbus_pending_call_unref(tel_dev->call);
+	tel_dev->call = NULL;
+	dbus_message_unref(reply);
+}
+
+static void client_connect_cb(GIOChannel *chan, GError *err,
+				gpointer user_data)
+{
+	struct connecting_device *client = user_data;
+	struct telephony_device *tel_dev;
+	char hs_address[18];
+
+	if (err) {
+		error("%s", err->message);
+		rfcomm_channel_close(client->tmp_rfcomm);
+		goto done;
+	}
+
+	ba2str(&client->dst, hs_address);
+
+	tel_dev = telephony_device_connecting(chan, client->btd_dev, NULL,
+						client->uuid);
+	if (tel_dev == NULL) {
+		rfcomm_channel_close(client->tmp_rfcomm);
+		goto done;
+	}
+
+	g_io_channel_unref(client->tmp_rfcomm);
+	client->tmp_rfcomm = NULL;
+
+	DBG("%s: Connected to %s", device_get_path(client->btd_dev),
+								hs_address);
+
+done:
+	g_free(client);
+
+	return;
+}
+
+static void client_auth_cb(DBusError *derr, void *user_data)
+{
+	struct connecting_device *client = user_data;
+	GError *err = NULL;
+
+	if (client->preauth_id) {
+		g_source_remove(client->preauth_id);
+		client->preauth_id = 0;
+	}
+
+	if (derr && dbus_error_is_set(derr)) {
+		error("Access denied: %s", derr->message);
+		goto failed;
+	}
+
+	if (!bt_io_accept(client->tmp_rfcomm, client_connect_cb, client, NULL,
+			  &err)) {
+		error("bt_io_accept: %s", err->message);
+		g_error_free(err);
+		goto failed;
+	}
+
+	return;
+
+failed:
+	rfcomm_channel_close(client->tmp_rfcomm);
+	g_free(client);
+}
+
+static gboolean client_preauth_cb(GIOChannel *chan, GIOCondition cond,
+							gpointer user_data)
+{
+	struct connecting_device *client = user_data;
+
+	DBG("Client for %s disconnected during authorization", client->uuid);
+
+	btd_cancel_authorization(&client->src, &client->dst);
+
+	rfcomm_channel_close(client->tmp_rfcomm);
+	g_free(client);
+
+	return FALSE;
+}
+
+static void client_confirm(GIOChannel *chan, gpointer data)
+{
+	struct telephony_agent *agent = data;
+	struct connecting_device *client;
+	struct btd_adapter *adapter;
+	struct btd_device *btd_dev;
+	char addr[18];
+	int perr;
+	GError *err = NULL;
+	uint8_t ch;
+
+	client = g_new0(struct connecting_device, 1);
+	client->tmp_rfcomm = g_io_channel_ref(chan);
+
+	bt_io_get(chan, BT_IO_RFCOMM, &err,
+			BT_IO_OPT_SOURCE_BDADDR, &client->src,
+			BT_IO_OPT_DEST_BDADDR, &client->dst,
+			BT_IO_OPT_CHANNEL, &ch,
+			BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", err->message);
+		g_error_free(err);
+		goto drop;
+	}
+
+	ba2str(&client->src, addr);
+
+	adapter = manager_find_adapter(&client->src);
+	if (!adapter) {
+		error("Unable to get a btd_adapter object for %s", addr);
+		goto drop;
+	}
+
+	ba2str(&client->dst, addr);
+
+	btd_dev = adapter_get_device(connection, adapter, addr);
+	if (!btd_dev) {
+		error("Unable to get btd_device object for %s", addr);
+		goto drop;
+	}
+
+	client->uuid = agent->config->uuid;
+	client->btd_dev = btd_dev;
+
+	perr = btd_request_authorization(&client->src, &client->dst,
+						agent->config->uuid,
+						client_auth_cb, client);
+	if (perr < 0) {
+		DBG("Authorization denied: %s", strerror(-perr));
+		goto drop;
+	}
+
+	client->preauth_id = g_io_add_watch(chan,
+					G_IO_NVAL | G_IO_HUP | G_IO_ERR,
+					client_preauth_cb, client);
+
+	return;
+
+drop:
+	rfcomm_channel_close(client->tmp_rfcomm);
+
+	g_free(client);
+}
+
 static gboolean hs_dev_disconnect_cb(GIOChannel *chan, GIOCondition cond,
 					gpointer data)
 {
@@ -445,7 +658,8 @@ struct telephony_device *telephony_device_connecting(GIOChannel *io,
 	struct telephony_agent *agent;
 	struct telephony_device *tel_dev;
 	uuid_t r_uuid;
-	int err;
+	int sk;
+	int err = 0;
 
 	adapter = device_get_adapter(btd_dev);
 	agent = find_agent(adapter, NULL, NULL, uuid);
@@ -461,17 +675,29 @@ struct telephony_device *telephony_device_connecting(GIOChannel *io,
 	tel_dev->rfcomm = g_io_channel_ref(io);
 	tel_dev->features = 0xFFFF;
 
-	sdp_uuid16_create(&r_uuid, tel_dev->config->r_class);
+	if (tel_dev->config->r_class == 0) {
+		sk = g_io_channel_unix_get_fd(tel_dev->rfcomm);
+
+		if (agent_sendfd(tel_dev, sk, tel_dev->config->connection_reply)
+								== FALSE) {
+			error("Failed to send RFComm socket to agent %s," \
+				" path %s", tel_dev->name, tel_dev->path);
+			err = -1;
+		}
+	} else {
+		sdp_uuid16_create(&r_uuid, tel_dev->config->r_class);
+
+		err = bt_search_service(&au_dev->src, &au_dev->dst, &r_uuid,
+						get_record_cb, tel_dev, NULL);
+		if (!err)
+			tel_dev->pending_sdp = TRUE;
+	}
 
-	err = bt_search_service(&au_dev->src, &au_dev->dst, &r_uuid,
-				get_record_cb, tel_dev, NULL);
 	if (err < 0) {
 		telephony_device_disconnect(tel_dev);
 		return NULL;
 	}
 
-	tel_dev->pending_sdp = TRUE;
-
 	return tel_dev;
 }
 
@@ -511,6 +737,60 @@ const char *telephony_get_agent_name(struct telephony_device *device)
 	return device->name;
 }
 
+static sdp_record_t *dun_gw_record(struct telephony_agent *agent)
+{
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	uuid_t root_uuid, svclass_uuid;
+	uuid_t l2cap_uuid, rfcomm_uuid;
+	sdp_profile_desc_t profile;
+	sdp_list_t *aproto, *proto[2];
+	sdp_record_t *record;
+	sdp_data_t *channel;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	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, DIALUP_NET_SVCLASS_ID);
+	svclass_id = sdp_list_append(0, &svclass_uuid);
+	sdp_set_service_classes(record, svclass_id);
+
+	sdp_uuid16_create(&profile.uuid, DIALUP_NET_PROFILE_ID);
+	profile.version = agent->version;
+	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, &agent->config->channel);
+	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);
+
+	sdp_data_free(channel);
+	sdp_list_free(proto[0], 0);
+	sdp_list_free(proto[1], 0);
+	sdp_list_free(apseq, 0);
+	sdp_list_free(pfseq, 0);
+	sdp_list_free(aproto, 0);
+	sdp_list_free(root, 0);
+	sdp_list_free(svclass_id, 0);
+
+	return record;
+}
+
 static sdp_record_t *hfp_hs_record(struct telephony_agent *agent)
 {
 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
@@ -927,6 +1207,14 @@ drop:
 }
 
 static struct profile_config default_configs[] = {
+	{ DUN_GW_UUID,
+		DEFAULT_DUN_GW_CHANNEL,
+		NULL,
+		0,
+		0,
+		dun_gw_record,
+		client_confirm,
+		client_newconnection_reply },
 	{ HSP_AG_UUID,
 		DEFAULT_HS_AG_CHANNEL,
 		HSP_HS_UUID,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v17 11/15] audio: Move HFP HF server to telephony.c
From: Frédéric Danis @ 2012-08-03 12:07 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1343995640-19784-1-git-send-email-frederic.danis@linux.intel.com>

Move HandsFree HF RFComm server from audio/manager.c to
audio/telephony.c.
Update the HandsfreeGateway API to reflect this change (remove agent
related methods).
Doing this, RFComm server related to HandsfreeGateway is only started
when an agent registers for this role of HandsFree Profile.
---
 audio/device.h    |    1 +
 audio/gateway.c   |  436 +++++++++++++++--------------------------------------
 audio/gateway.h   |    8 +
 audio/manager.c   |  210 +-------------------------
 audio/media.c     |   17 +++
 audio/telephony.c |  217 +++++++++++++++++++++++++-
 audio/transport.c |    4 +
 doc/hfp-api.txt   |   46 ------
 8 files changed, 366 insertions(+), 573 deletions(-)

diff --git a/audio/device.h b/audio/device.h
index 75f1da9..1e260e3 100644
--- a/audio/device.h
+++ b/audio/device.h
@@ -48,6 +48,7 @@ struct audio_device {
 	struct target *target;
 
 	guint hs_preauth_id;
+	guint gw_preauth_id;
 
 	struct dev_priv *priv;
 };
diff --git a/audio/gateway.c b/audio/gateway.c
index 6162948..125cb02 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -41,21 +41,20 @@
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/sdp.h>
 #include <bluetooth/sdp_lib.h>
+#include <bluetooth/uuid.h>
+
+#include "btio.h"
+#include "../src/adapter.h"
+#include "../src/device.h"
 
 #include "sdp-client.h"
 #include "device.h"
 #include "gateway.h"
+#include "telephony.h"
 #include "log.h"
 #include "error.h"
-#include "btio.h"
 #include "dbus-common.h"
 
-struct hf_agent {
-	char *name;	/* Bus id */
-	char *path;	/* D-Bus path */
-	guint watch;	/* Disconnect watch */
-};
-
 struct connect_cb {
 	unsigned int id;
 	gateway_stream_cb_t cb;
@@ -64,14 +63,14 @@ struct connect_cb {
 
 struct gateway {
 	gateway_state_t state;
-	GIOChannel *rfcomm;
+	GIOChannel *tmp_rfcomm;
 	GIOChannel *sco;
-	GIOChannel *incoming;
+	const char *connecting_uuid;
+	const char *connecting_transport_path;
 	GSList *callbacks;
-	struct hf_agent *agent;
 	DBusMessage *msg;
-	int version;
 	gateway_lock_t lock;
+	struct telephony_device *tel_dev;
 };
 
 struct gateway_state_callback {
@@ -105,16 +104,6 @@ static const char *state2str(gateway_state_t state)
 	}
 }
 
-static void agent_free(struct hf_agent *agent)
-{
-	if (!agent)
-		return;
-
-	g_free(agent->name);
-	g_free(agent->path);
-	g_free(agent);
-}
-
 static void change_state(struct audio_device *dev, gateway_state_t new_state)
 {
 	struct gateway *gw = dev->gateway;
@@ -141,8 +130,19 @@ static void change_state(struct audio_device *dev, gateway_state_t new_state)
 
 void gateway_set_state(struct audio_device *dev, gateway_state_t new_state)
 {
+	struct gateway *gw = dev->gateway;
+
 	switch (new_state) {
 	case GATEWAY_STATE_DISCONNECTED:
+		if (gw->msg) {
+			DBusMessage *reply;
+
+			reply = btd_error_failed(gw->msg, "Connect failed");
+			g_dbus_send_message(dev->conn, reply);
+			dbus_message_unref(gw->msg);
+			gw->msg = NULL;
+		}
+
 		gateway_close(dev);
 		break;
 	case GATEWAY_STATE_CONNECTING:
@@ -152,44 +152,6 @@ void gateway_set_state(struct audio_device *dev, gateway_state_t new_state)
 	}
 }
 
-static void agent_disconnect(struct audio_device *dev, struct hf_agent *agent)
-{
-	DBusMessage *msg;
-
-	msg = dbus_message_new_method_call(agent->name, agent->path,
-			"org.bluez.HandsfreeAgent", "Release");
-
-	g_dbus_send_message(dev->conn, msg);
-}
-
-static gboolean agent_sendfd(struct hf_agent *agent, int fd,
-		DBusPendingCallNotifyFunction notify, void *data)
-{
-	struct audio_device *dev = data;
-	struct gateway *gw = dev->gateway;
-	DBusMessage *msg;
-	DBusPendingCall *call;
-
-	msg = dbus_message_new_method_call(agent->name, agent->path,
-			"org.bluez.HandsfreeAgent", "NewConnection");
-
-	dbus_message_append_args(msg, DBUS_TYPE_UNIX_FD, &fd,
-					DBUS_TYPE_UINT16, &gw->version,
-					DBUS_TYPE_INVALID);
-
-	if (dbus_connection_send_with_reply(dev->conn, msg,
-							&call, -1) == FALSE) {
-		dbus_message_unref(msg);
-		return FALSE;
-	}
-
-	dbus_pending_call_set_notify(call, notify, dev, NULL);
-	dbus_pending_call_unref(call);
-	dbus_message_unref(msg);
-
-	return TRUE;
-}
-
 static unsigned int connect_cb_new(struct gateway *gw,
 					gateway_stream_cb_t func,
 					void *user_data)
@@ -264,175 +226,59 @@ static void sco_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	run_connect_cb(dev, NULL);
 }
 
-static gboolean rfcomm_disconnect_cb(GIOChannel *chan, GIOCondition cond,
-			struct audio_device *dev)
+void gateway_slc_complete(struct audio_device *dev)
 {
-	if (cond & G_IO_NVAL)
-		return FALSE;
-
-	gateway_close(dev);
-
-	return FALSE;
-}
-
-static void newconnection_reply(DBusPendingCall *call, void *data)
-{
-	struct audio_device *dev = data;
-	struct gateway *gw = dev->gateway;
-	DBusMessage *reply = dbus_pending_call_steal_reply(call);
-	DBusError derr;
-
-	if (!dev->gateway->rfcomm) {
-		DBG("RFCOMM disconnected from server before agent reply");
-		goto done;
-	}
-
-	dbus_error_init(&derr);
-	if (!dbus_set_error_from_message(&derr, reply)) {
-		DBG("Agent reply: file descriptor passed successfully");
-		g_io_add_watch(gw->rfcomm, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-					(GIOFunc) rfcomm_disconnect_cb, dev);
-		change_state(dev, GATEWAY_STATE_CONNECTED);
-		goto done;
-	}
-
-	DBG("Agent reply: %s", derr.message);
-
-	dbus_error_free(&derr);
-	gateway_close(dev);
-
-done:
-	dbus_message_unref(reply);
-}
-
-static void rfcomm_connect_cb(GIOChannel *chan, GError *err,
-				gpointer user_data)
-{
-	struct audio_device *dev = user_data;
 	struct gateway *gw = dev->gateway;
 	DBusMessage *reply;
-	int sk, ret;
 
-	if (err) {
-		error("connect(): %s", err->message);
-		goto fail;
-	}
+	DBG("Service Level Connection established");
 
-	if (!gw->agent) {
-		error("Handsfree Agent not registered");
-		goto fail;
-	}
-
-	sk = g_io_channel_unix_get_fd(chan);
-
-	if (gw->rfcomm == NULL)
-		gw->rfcomm = g_io_channel_ref(chan);
-
-	ret = agent_sendfd(gw->agent, sk, newconnection_reply, dev);
+	change_state(dev, GATEWAY_STATE_CONNECTED);
 
 	if (!gw->msg)
 		return;
 
-	if (ret)
-		reply = dbus_message_new_method_return(gw->msg);
-	else
-		reply = btd_error_failed(gw->msg, "Can't pass file descriptor");
-
+	reply = dbus_message_new_method_return(gw->msg);
 	g_dbus_send_message(dev->conn, reply);
-
-	return;
-
-fail:
-	if (gw->msg) {
-		DBusMessage *reply;
-		reply = btd_error_failed(gw->msg, "Connect failed");
-		g_dbus_send_message(dev->conn, reply);
-	}
-
-	gateway_close(dev);
-}
-
-static int get_remote_profile_version(sdp_record_t *rec)
-{
-	uuid_t uuid;
-	sdp_list_t *profiles;
-	sdp_profile_desc_t *desc;
-	int ver = 0;
-
-	sdp_uuid16_create(&uuid, HANDSFREE_PROFILE_ID);
-
-	sdp_get_profile_descs(rec, &profiles);
-	if (profiles == NULL)
-		goto done;
-
-	desc = profiles->data;
-
-	if (sdp_uuid16_cmp(&desc->uuid, &uuid) == 0)
-		ver = desc->version;
-
-	sdp_list_free(profiles, free);
-
-done:
-	return ver;
+	dbus_message_unref(gw->msg);
+	gw->msg = NULL;
 }
 
-static void get_incoming_record_cb(sdp_list_t *recs, int err,
-					gpointer user_data)
+void gateway_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	struct audio_device *dev = user_data;
 	struct gateway *gw = dev->gateway;
-	GError *gerr = NULL;
+	char hs_address[18];
 
-	if (err < 0) {
-		error("Unable to get service record: %s (%d)", strerror(-err),
-					-err);
-		goto fail;
+	if (err) {
+		error("%s", err->message);
+		goto failed;
 	}
 
-	if (!recs || !recs->data) {
-		error("No records found");
-		goto fail;
-	}
+	ba2str(&dev->dst, hs_address);
 
-	gw->version = get_remote_profile_version(recs->data);
-	if (gw->version == 0)
-		goto fail;
+	if (!telephony_is_uuid_supported(device_get_adapter(dev->btd_dev),
+							gw->connecting_uuid))
+		goto failed;
 
-	rfcomm_connect_cb(gw->incoming, gerr, dev);
-	return;
+	gw->tel_dev = telephony_device_connecting(chan, dev->btd_dev, dev,
+							gw->connecting_uuid);
+	gw->connecting_uuid = NULL;
+	telephony_set_media_transport_path(gw->tel_dev,
+						gw->connecting_transport_path);
+	gw->connecting_transport_path = NULL;
 
-fail:
-	gateway_close(dev);
-}
-
-static void unregister_incoming(gpointer user_data)
-{
-	struct audio_device *dev = user_data;
-	struct gateway *gw = dev->gateway;
-
-	if (gw->incoming) {
-		g_io_channel_unref(gw->incoming);
-		gw->incoming = NULL;
+	if (gw->tmp_rfcomm) {
+		g_io_channel_unref(gw->tmp_rfcomm);
+		gw->tmp_rfcomm = NULL;
 	}
-}
 
-static void rfcomm_incoming_cb(GIOChannel *chan, GError *err,
-				gpointer user_data)
-{
-	struct audio_device *dev = user_data;
-	struct gateway *gw = dev->gateway;
-	uuid_t uuid;
-
-	gw->incoming = g_io_channel_ref(chan);
+	DBG("%s: Connected to %s", dev->path, hs_address);
 
-	sdp_uuid16_create(&uuid, HANDSFREE_AGW_SVCLASS_ID);
-	if (bt_search_service(&dev->src, &dev->dst, &uuid,
-						get_incoming_record_cb, dev,
-						unregister_incoming) == 0)
-		return;
+	return;
 
-	unregister_incoming(dev);
-	gateway_close(dev);
+failed:
+	gateway_set_state(dev, GATEWAY_STATE_DISCONNECTED);
 }
 
 static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
@@ -469,13 +315,6 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
 		goto fail;
 	}
 
-	gw->version = get_remote_profile_version(recs->data);
-	if (gw->version == 0) {
-		error("Unable to get profile version from record");
-		err = -EINVAL;
-		goto fail;
-	}
-
 	memcpy(&uuid, classes->data, sizeof(uuid));
 	sdp_list_free(classes, free);
 
@@ -496,7 +335,7 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
 		goto fail;
 	}
 
-	io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, dev, NULL, &gerr,
+	io = bt_io_connect(BT_IO_RFCOMM, gateway_connect_cb, dev, NULL, &gerr,
 				BT_IO_OPT_SOURCE_BDADDR, &dev->src,
 				BT_IO_OPT_DEST_BDADDR, &dev->dst,
 				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
@@ -515,6 +354,8 @@ fail:
 		DBusMessage *reply = btd_error_failed(gw->msg,
 					gerr ? gerr->message : strerror(-err));
 		g_dbus_send_message(dev->conn, reply);
+		dbus_message_unref(gw->msg);
+		gw->msg = NULL;
 	}
 
 	gateway_close(dev);
@@ -540,12 +381,22 @@ static DBusMessage *ag_connect(DBusConnection *conn, DBusMessage *msg,
 	struct gateway *gw = au_dev->gateway;
 	int err;
 
-	if (!gw->agent)
+	if (gw->state == GATEWAY_STATE_CONNECTING)
+		return btd_error_in_progress(msg);
+	else if (gw->state > GATEWAY_STATE_CONNECTING)
+		return btd_error_already_connected(msg);
+
+	if (!telephony_is_uuid_supported(device_get_adapter(au_dev->btd_dev),
+								HFP_HS_UUID))
 		return btd_error_agent_not_available(msg);
 
+	gw->connecting_uuid = HFP_HS_UUID;
+
 	err = get_records(au_dev);
-	if (err < 0)
+	if (err < 0) {
+		gw->connecting_uuid = NULL;
 		return btd_error_failed(msg, strerror(-err));
+	}
 
 	gw->msg = dbus_message_ref(msg);
 
@@ -558,13 +409,13 @@ int gateway_close(struct audio_device *device)
 	struct gateway *gw = device->gateway;
 	int sock;
 
-	if (gw->rfcomm) {
-		sock = g_io_channel_unix_get_fd(gw->rfcomm);
+	if (gw->tmp_rfcomm) {
+		sock = g_io_channel_unix_get_fd(gw->tmp_rfcomm);
 		shutdown(sock, SHUT_RDWR);
 
-		g_io_channel_shutdown(gw->rfcomm, TRUE, NULL);
-		g_io_channel_unref(gw->rfcomm);
-		gw->rfcomm = NULL;
+		g_io_channel_shutdown(gw->tmp_rfcomm, TRUE, NULL);
+		g_io_channel_unref(gw->tmp_rfcomm);
+		gw->tmp_rfcomm = NULL;
 	}
 
 	if (gw->sco) {
@@ -573,6 +424,14 @@ int gateway_close(struct audio_device *device)
 		gw->sco = NULL;
 	}
 
+	if (gw->tel_dev) {
+		telephony_device_disconnect(gw->tel_dev);
+		gw->tel_dev = NULL;
+	}
+
+	gw->connecting_uuid = NULL;
+	gw->connecting_transport_path = NULL;
+
 	change_state(device, GATEWAY_STATE_DISCONNECTED);
 	g_set_error(&gerr, GATEWAY_ERROR,
 			GATEWAY_ERROR_DISCONNECTED, "Disconnected");
@@ -586,16 +445,12 @@ static DBusMessage *ag_disconnect(DBusConnection *conn, DBusMessage *msg,
 					void *data)
 {
 	struct audio_device *device = data;
-	struct gateway *gw = device->gateway;
 	DBusMessage *reply = NULL;
 	char gw_addr[18];
 
 	if (!device->conn)
 		return NULL;
 
-	if (!gw->rfcomm)
-		return btd_error_not_connected(msg);
-
 	reply = dbus_message_new_method_return(msg);
 	if (!reply)
 		return NULL;
@@ -607,17 +462,6 @@ static DBusMessage *ag_disconnect(DBusConnection *conn, DBusMessage *msg,
 	return reply;
 }
 
-static void agent_exited(DBusConnection *conn, void *data)
-{
-	struct gateway *gateway = data;
-	struct hf_agent *agent = gateway->agent;
-
-	DBG("Agent %s exited", agent->name);
-
-	agent_free(agent);
-	gateway->agent = NULL;
-}
-
 static DBusMessage *ag_get_properties(DBusConnection *conn, DBusMessage *msg,
 					void *data)
 {
@@ -649,75 +493,12 @@ static DBusMessage *ag_get_properties(DBusConnection *conn, DBusMessage *msg,
 	return reply;
 }
 
-static DBusMessage *register_agent(DBusConnection *conn,
-					DBusMessage *msg, void *data)
-{
-	struct audio_device *device = data;
-	struct gateway *gw = device->gateway;
-	struct hf_agent *agent;
-	const char *path, *name;
-
-	if (gw->agent)
-		return btd_error_already_exists(msg);
-
-	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
-						DBUS_TYPE_INVALID))
-		return btd_error_invalid_args(msg);
-
-	name = dbus_message_get_sender(msg);
-	agent = g_new0(struct hf_agent, 1);
-
-	agent->name = g_strdup(name);
-	agent->path = g_strdup(path);
-
-	agent->watch = g_dbus_add_disconnect_watch(conn, name,
-						agent_exited, gw, NULL);
-
-	gw->agent = agent;
-
-	return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *unregister_agent(DBusConnection *conn,
-				DBusMessage *msg, void *data)
-{
-	struct audio_device *device = data;
-	struct gateway *gw = device->gateway;
-	const char *path;
-
-	if (!gw->agent)
-		goto done;
-
-	if (strcmp(gw->agent->name, dbus_message_get_sender(msg)) != 0)
-		return btd_error_not_authorized(msg);
-
-	if (!dbus_message_get_args(msg, NULL,
-				DBUS_TYPE_OBJECT_PATH, &path,
-				DBUS_TYPE_INVALID))
-		return btd_error_invalid_args(msg);
-
-	if (strcmp(gw->agent->path, path) != 0)
-		return btd_error_does_not_exist(msg);
-
-	g_dbus_remove_watch(device->conn, gw->agent->watch);
-
-	agent_free(gw->agent);
-	gw->agent = NULL;
-
-done:
-	return dbus_message_new_method_return(msg);
-}
-
 static const GDBusMethodTable gateway_methods[] = {
 	{ GDBUS_ASYNC_METHOD("Connect", NULL, NULL, ag_connect) },
 	{ GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, ag_disconnect) },
 	{ GDBUS_METHOD("GetProperties",
 			NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
 			ag_get_properties) },
-	{ GDBUS_METHOD("RegisterAgent",
-			GDBUS_ARGS({ "agent", "o" }), NULL, register_agent) },
-	{ GDBUS_METHOD("UnregisterAgent",
-			GDBUS_ARGS({ "agent", "o" }), NULL, unregister_agent) },
 	{ }
 };
 
@@ -742,9 +523,6 @@ static void path_unregister(void *data)
 
 void gateway_unregister(struct audio_device *dev)
 {
-	if (dev->gateway->agent)
-		agent_disconnect(dev, dev->gateway->agent);
-
 	g_dbus_unregister_interface(dev->conn, dev->path,
 						AUDIO_GATEWAY_INTERFACE);
 }
@@ -785,13 +563,52 @@ int gateway_connect_rfcomm(struct audio_device *dev, GIOChannel *io)
 	if (!io)
 		return -EINVAL;
 
-	dev->gateway->rfcomm = g_io_channel_ref(io);
+	dev->gateway->tmp_rfcomm = g_io_channel_ref(io);
 
 	change_state(dev, GATEWAY_STATE_CONNECTING);
 
 	return 0;
 }
 
+GIOChannel *gateway_get_rfcomm(struct audio_device *dev)
+{
+	struct gateway *gw = dev->gateway;
+
+	return gw->tmp_rfcomm;
+}
+
+void gateway_set_connecting_uuid(struct audio_device *dev, const char *uuid)
+{
+	struct gateway *gw = dev->gateway;
+
+	gw->connecting_uuid = uuid;
+}
+
+void gateway_set_media_transport_path(struct audio_device *dev,
+							const char *path)
+{
+	struct gateway *gw = dev->gateway;
+
+	DBG("MediaTransport path: %s", path);
+
+	if (gw->tel_dev == NULL) {
+		gw->connecting_transport_path = path;
+		return;
+	}
+
+	telephony_set_media_transport_path(gw->tel_dev, path);
+}
+
+const char *gateway_get_telephony_agent_name(struct audio_device *dev)
+{
+	struct gateway *gw = dev->gateway;
+
+	if (gw == NULL || gw->tel_dev == NULL)
+		return NULL;
+
+	return telephony_get_agent_name(gw->tel_dev);
+}
+
 int gateway_connect_sco(struct audio_device *dev, GIOChannel *io)
 {
 	struct gateway *gw = dev->gateway;
@@ -809,21 +626,6 @@ int gateway_connect_sco(struct audio_device *dev, GIOChannel *io)
 	return 0;
 }
 
-void gateway_start_service(struct audio_device *dev)
-{
-	struct gateway *gw = dev->gateway;
-	GError *err = NULL;
-
-	if (gw->rfcomm == NULL)
-		return;
-
-	if (!bt_io_accept(gw->rfcomm, rfcomm_incoming_cb, dev, NULL, &err)) {
-		error("bt_io_accept: %s", err->message);
-		g_error_free(err);
-		gateway_close(dev);
-	}
-}
-
 static gboolean request_stream_cb(gpointer data)
 {
 	run_connect_cb(data, NULL);
@@ -839,7 +641,7 @@ unsigned int gateway_request_stream(struct audio_device *dev,
 	GError *err = NULL;
 	GIOChannel *io;
 
-	if (!gw->rfcomm)
+	if (!gw->tel_dev)
 		get_records(dev);
 	else if (!gw->sco) {
 		io = bt_io_connect(BT_IO_SCO, sco_connect_cb, dev, NULL, &err,
@@ -866,7 +668,7 @@ int gateway_config_stream(struct audio_device *dev, gateway_stream_cb_t cb,
 
 	id = connect_cb_new(gw, cb, user_data);
 
-	if (!gw->rfcomm)
+	if (!gw->tel_dev)
 		get_records(dev);
 	else if (cb)
 		g_idle_add(request_stream_cb, dev);
diff --git a/audio/gateway.h b/audio/gateway.h
index 77f5787..b42fdf1 100644
--- a/audio/gateway.h
+++ b/audio/gateway.h
@@ -74,3 +74,11 @@ gboolean gateway_remove_state_cb(unsigned int id);
 gateway_lock_t gateway_get_lock(struct audio_device *dev);
 gboolean gateway_lock(struct audio_device *dev, gateway_lock_t lock);
 gboolean gateway_unlock(struct audio_device *dev, gateway_lock_t lock);
+
+void gateway_connect_cb(GIOChannel *chan, GError *err, gpointer user_data);
+void gateway_slc_complete(struct audio_device *dev);
+void gateway_set_connecting_uuid(struct audio_device *dev, const char *uuid);
+GIOChannel *gateway_get_rfcomm(struct audio_device *dev);
+void gateway_set_media_transport_path(struct audio_device *dev,
+							const char *path);
+const char *gateway_get_telephony_agent_name(struct audio_device *dev);
diff --git a/audio/manager.c b/audio/manager.c
index 4ab0186..5dcf52d 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -89,8 +89,6 @@ typedef enum {
 struct audio_adapter {
 	struct btd_adapter *btd_adapter;
 	gboolean powered;
-	uint32_t hfp_hs_record_id;
-	GIOChannel *hfp_hs_server;
 	gint ref;
 };
 
@@ -222,196 +220,6 @@ static void handle_uuid(const char *uuidstr, struct audio_device *device)
 	}
 }
 
-static sdp_record_t *hfp_hs_record(uint8_t ch)
-{
-	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
-	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
-	uuid_t l2cap_uuid, rfcomm_uuid;
-	sdp_profile_desc_t profile;
-	sdp_record_t *record;
-	sdp_list_t *aproto, *proto[2];
-	sdp_data_t *channel;
-
-	record = sdp_record_alloc();
-	if (!record)
-		return NULL;
-
-	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 = 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, &ch);
-	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, "Hands-Free", 0, 0);
-
-	sdp_data_free(channel);
-	sdp_list_free(proto[0], 0);
-	sdp_list_free(proto[1], 0);
-	sdp_list_free(apseq, 0);
-	sdp_list_free(pfseq, 0);
-	sdp_list_free(aproto, 0);
-	sdp_list_free(root, 0);
-	sdp_list_free(svclass_id, 0);
-
-	return record;
-}
-
-static void gateway_auth_cb(DBusError *derr, void *user_data)
-{
-	struct audio_device *device = user_data;
-
-	if (derr && dbus_error_is_set(derr)) {
-		error("Access denied: %s", derr->message);
-		gateway_set_state(device, GATEWAY_STATE_DISCONNECTED);
-	} else {
-		char ag_address[18];
-
-		ba2str(&device->dst, ag_address);
-		DBG("Accepted AG connection from %s for %s",
-			ag_address, device->path);
-
-		gateway_start_service(device);
-	}
-}
-
-static void hf_io_cb(GIOChannel *chan, gpointer data)
-{
-	bdaddr_t src, dst;
-	GError *err = NULL;
-	uint8_t ch;
-	const char *server_uuid, *remote_uuid;
-	struct audio_device *device;
-	int perr;
-
-	bt_io_get(chan, BT_IO_RFCOMM, &err,
-			BT_IO_OPT_SOURCE_BDADDR, &src,
-			BT_IO_OPT_DEST_BDADDR, &dst,
-			BT_IO_OPT_CHANNEL, &ch,
-			BT_IO_OPT_INVALID);
-
-	if (err) {
-		error("%s", err->message);
-		g_error_free(err);
-		return;
-	}
-
-	server_uuid = HFP_HS_UUID;
-	remote_uuid = HFP_AG_UUID;
-
-	device = manager_get_device(&src, &dst, TRUE);
-	if (!device)
-		goto drop;
-
-	if (!device->gateway) {
-		btd_device_add_uuid(device->btd_dev, remote_uuid);
-		if (!device->gateway)
-			goto drop;
-	}
-
-	if (gateway_is_active(device)) {
-		DBG("Refusing new connection since one already exists");
-		goto drop;
-	}
-
-	if (gateway_connect_rfcomm(device, chan) < 0) {
-		error("Allocating new GIOChannel failed!");
-		goto drop;
-	}
-
-	perr = audio_device_request_authorization(device, server_uuid,
-						gateway_auth_cb, device);
-	if (perr < 0) {
-		DBG("Authorization denied: %s", strerror(-perr));
-		gateway_set_state(device, GATEWAY_STATE_DISCONNECTED);
-	}
-
-	return;
-
-drop:
-	g_io_channel_shutdown(chan, TRUE, NULL);
-}
-
-static int gateway_server_init(struct audio_adapter *adapter)
-{
-	uint8_t chan = DEFAULT_HFP_HS_CHANNEL;
-	sdp_record_t *record;
-	gboolean master = TRUE;
-	GError *err = NULL;
-	GIOChannel *io;
-	bdaddr_t src;
-
-	if (config) {
-		gboolean tmp;
-
-		tmp = g_key_file_get_boolean(config, "General", "Master",
-						&err);
-		if (err) {
-			DBG("audio.conf: %s", err->message);
-			g_clear_error(&err);
-		} else
-			master = tmp;
-	}
-
-	adapter_get_address(adapter->btd_adapter, &src);
-
-	io = bt_io_listen(BT_IO_RFCOMM, NULL, hf_io_cb, adapter, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, &src,
-				BT_IO_OPT_CHANNEL, chan,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-				BT_IO_OPT_MASTER, master,
-				BT_IO_OPT_INVALID);
-	if (!io) {
-		error("%s", err->message);
-		g_error_free(err);
-		return -1;
-	}
-
-	adapter->hfp_hs_server = io;
-	record = hfp_hs_record(chan);
-	if (!record) {
-		error("Unable to allocate new service record");
-		goto failed;
-	}
-
-	if (add_record_to_server(&src, record) < 0) {
-		error("Unable to register HFP HS service record");
-		sdp_record_free(record);
-		goto failed;
-	}
-
-	adapter->hfp_hs_record_id = record->handle;
-
-	return 0;
-
-failed:
-	g_io_channel_shutdown(adapter->hfp_hs_server, TRUE, NULL);
-	g_io_channel_unref(adapter->hfp_hs_server);
-	adapter->hfp_hs_server = NULL;
-	return -1;
-}
-
 static int audio_probe(struct btd_device *device, GSList *uuids)
 {
 	struct btd_adapter *adapter = device_get_adapter(device);
@@ -579,17 +387,12 @@ static void headset_server_remove(struct btd_adapter *adapter)
 static int gateway_server_probe(struct btd_adapter *adapter)
 {
 	struct audio_adapter *adp;
-	int err;
 
 	adp = audio_adapter_get(adapter);
 	if (!adp)
 		return -EINVAL;
 
-	err = gateway_server_init(adp);
-	if (err < 0)
-		audio_adapter_unref(adp);
-
-	return err;
+	return 0;
 }
 
 static void gateway_server_remove(struct btd_adapter *adapter)
@@ -603,17 +406,6 @@ static void gateway_server_remove(struct btd_adapter *adapter)
 	if (!adp)
 		return;
 
-	if (adp->hfp_hs_record_id) {
-		remove_record_from_server(adp->hfp_hs_record_id);
-		adp->hfp_hs_record_id = 0;
-	}
-
-	if (adp->hfp_hs_server) {
-		g_io_channel_shutdown(adp->hfp_hs_server, TRUE, NULL);
-		g_io_channel_unref(adp->hfp_hs_server);
-		adp->hfp_hs_server = NULL;
-	}
-
 	audio_adapter_unref(adp);
 }
 
diff --git a/audio/media.c b/audio/media.c
index c608c41..3e5d12d 100644
--- a/audio/media.c
+++ b/audio/media.c
@@ -647,6 +647,7 @@ static void gateway_state_changed(struct audio_device *dev,
 {
 	struct media_endpoint *endpoint = user_data;
 	struct media_transport *transport;
+	const char *path;
 
 	DBG("");
 
@@ -664,6 +665,13 @@ static void gateway_state_changed(struct audio_device *dev,
 	case GATEWAY_STATE_CONNECTING:
 		set_configuration(endpoint, dev, NULL, 0,
 					gateway_setconf_cb, dev, NULL);
+
+		transport = find_device_transport(endpoint, dev);
+		if (transport == NULL)
+			break;
+
+		path = media_transport_get_path(transport);
+		gateway_set_media_transport_path(dev, path);
 		break;
 	case GATEWAY_STATE_CONNECTED:
 		break;
@@ -743,9 +751,18 @@ static gboolean endpoint_init_hs(struct media_endpoint *endpoint, int *err)
 
 	for (l = list; l != NULL; l = l->next) {
 		struct audio_device *dev = l->data;
+		struct media_transport *transport;
+		const char *path;
 
 		set_configuration(endpoint, dev, NULL, 0,
 						gateway_setconf_cb, dev, NULL);
+
+		transport = find_device_transport(endpoint, dev);
+		if (transport == NULL)
+			break;
+
+		path = media_transport_get_path(transport);
+		gateway_set_media_transport_path(dev, path);
 	}
 
 	g_slist_free(list);
diff --git a/audio/telephony.c b/audio/telephony.c
index da1797f..dc76d60 100644
--- a/audio/telephony.c
+++ b/audio/telephony.c
@@ -48,6 +48,7 @@
 #include "glib-helper.h"
 #include "sdp-client.h"
 #include "headset.h"
+#include "gateway.h"
 #include "telephony.h"
 #include "dbus-common.h"
 #include "sdpd.h"
@@ -335,6 +336,44 @@ done:
 	dbus_message_unref(reply);
 }
 
+static gboolean ag_dev_disconnect_cb(GIOChannel *chan, GIOCondition cond,
+					gpointer data)
+{
+	struct telephony_device *tel_dev = data;
+
+	if (cond & G_IO_NVAL)
+		return FALSE;
+
+	gateway_set_state(tel_dev->au_dev, GATEWAY_STATE_DISCONNECTED);
+
+	return FALSE;
+}
+
+static void ag_newconnection_reply(DBusPendingCall *call, void *user_data)
+{
+	struct telephony_device *tel_dev = user_data;
+	DBusMessage *reply = dbus_pending_call_steal_reply(call);
+	DBusError derr;
+
+	dbus_error_init(&derr);
+	if (dbus_set_error_from_message(&derr, reply)) {
+		DBG("Agent reply: %s", derr.message);
+		dbus_error_free(&derr);
+		gateway_set_state(tel_dev->au_dev, GATEWAY_STATE_DISCONNECTED);
+		goto done;
+	}
+
+	DBG("Agent reply: file descriptor passed successfully");
+	g_io_add_watch(tel_dev->rfcomm, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+			ag_dev_disconnect_cb, tel_dev);
+	gateway_slc_complete(tel_dev->au_dev);
+
+done:
+	dbus_pending_call_unref(tel_dev->call);
+	tel_dev->call = NULL;
+	dbus_message_unref(reply);
+}
+
 static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
 {
 	struct telephony_device *tel_dev = user_data;
@@ -390,7 +429,11 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
 	return;
 
 failed:
-	headset_set_state(tel_dev->au_dev, HEADSET_STATE_DISCONNECTED);
+	if (g_strcmp0(tel_dev->config->uuid, HSP_AG_UUID) == 0 ||
+			g_strcmp0(tel_dev->config->uuid, HFP_AG_UUID) == 0)
+		headset_set_state(tel_dev->au_dev, HEADSET_STATE_DISCONNECTED);
+	else if (g_strcmp0(tel_dev->config->uuid, HFP_HS_UUID) == 0)
+		gateway_set_state(tel_dev->au_dev, GATEWAY_STATE_DISCONNECTED);
 }
 
 struct telephony_device *telephony_device_connecting(GIOChannel *io,
@@ -468,6 +511,170 @@ const char *telephony_get_agent_name(struct telephony_device *device)
 	return device->name;
 }
 
+static sdp_record_t *hfp_hs_record(struct telephony_agent *agent)
+{
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
+	uuid_t l2cap_uuid, rfcomm_uuid;
+	sdp_profile_desc_t profile;
+	sdp_list_t *aproto, *proto[2];
+	sdp_record_t *record;
+	sdp_data_t *channel, *features;
+	uint16_t sdpfeat;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	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 = agent->version;
+	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, &agent->config->channel);
+	proto[1] = sdp_list_append(proto[1], channel);
+	apseq = sdp_list_append(apseq, proto[1]);
+
+	sdpfeat = agent->features & 0x1F;
+	features = sdp_data_alloc(SDP_UINT16, &sdpfeat);
+	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, "Hands-Free", 0, 0);
+
+	sdp_data_free(channel);
+	sdp_list_free(proto[0], 0);
+	sdp_list_free(proto[1], 0);
+	sdp_list_free(apseq, 0);
+	sdp_list_free(pfseq, 0);
+	sdp_list_free(aproto, 0);
+	sdp_list_free(root, 0);
+	sdp_list_free(svclass_id, 0);
+
+	return record;
+}
+
+static void gateway_auth_cb(DBusError *derr, void *user_data)
+{
+	struct audio_device *au_dev = user_data;
+	GError *err = NULL;
+	GIOChannel *io;
+
+	if (au_dev->gw_preauth_id) {
+		g_source_remove(au_dev->gw_preauth_id);
+		au_dev->gw_preauth_id = 0;
+	}
+
+	if (derr && dbus_error_is_set(derr)) {
+		error("Access denied: %s", derr->message);
+		gateway_set_state(au_dev, GATEWAY_STATE_DISCONNECTED);
+		return;
+	}
+
+	io = gateway_get_rfcomm(au_dev);
+
+	if (!bt_io_accept(io, gateway_connect_cb, au_dev, NULL, &err)) {
+		error("bt_io_accept: %s", err->message);
+		g_error_free(err);
+		gateway_set_state(au_dev, GATEWAY_STATE_DISCONNECTED);
+		return;
+	}
+}
+
+static gboolean gateway_preauth_cb(GIOChannel *chan, GIOCondition cond,
+							gpointer user_data)
+{
+	struct audio_device *au_dev = user_data;
+
+	DBG("Gateway disconnected during authorization");
+
+	audio_device_cancel_authorization(au_dev, gateway_auth_cb, au_dev);
+
+	gateway_set_state(au_dev, GATEWAY_STATE_DISCONNECTED);
+
+	au_dev->gw_preauth_id = 0;
+
+	return FALSE;
+}
+
+static void hf_confirm(GIOChannel *chan, gpointer data)
+{
+	struct telephony_agent *agent = data;
+	struct audio_device *au_dev;
+	bdaddr_t src, dst;
+	int perr;
+	GError *err = NULL;
+	uint8_t ch;
+
+	bt_io_get(chan, BT_IO_RFCOMM, &err,
+			BT_IO_OPT_SOURCE_BDADDR, &src,
+			BT_IO_OPT_DEST_BDADDR, &dst,
+			BT_IO_OPT_CHANNEL, &ch,
+			BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", err->message);
+		g_error_free(err);
+		goto drop;
+	}
+
+	au_dev = manager_get_device(&src, &dst, TRUE);
+	if (!au_dev)
+		goto drop;
+
+	if (!au_dev->gateway) {
+		btd_device_add_uuid(au_dev->btd_dev, agent->config->r_uuid);
+		if (!au_dev->gateway)
+			goto drop;
+	}
+
+	if (gateway_is_active(au_dev)) {
+		DBG("Refusing new connection since one already exists");
+		goto drop;
+	}
+
+	gateway_set_connecting_uuid(au_dev, agent->config->uuid);
+
+	if (gateway_connect_rfcomm(au_dev, chan) < 0) {
+		error("Allocating new GIOChannel failed!");
+		goto drop;
+	}
+
+	perr = audio_device_request_authorization(au_dev, agent->config->uuid,
+						gateway_auth_cb, au_dev);
+	if (perr < 0) {
+		DBG("Authorization denied: %s", strerror(-perr));
+		gateway_set_state(au_dev, GATEWAY_STATE_DISCONNECTED);
+		return;
+	}
+
+	au_dev->gw_preauth_id = g_io_add_watch(chan,
+					G_IO_NVAL | G_IO_HUP | G_IO_ERR,
+					gateway_preauth_cb, au_dev);
+
+	return;
+
+drop:
+	g_io_channel_shutdown(chan, TRUE, NULL);
+}
+
 static sdp_record_t *hsp_ag_record(struct telephony_agent *agent)
 {
 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
@@ -728,6 +935,14 @@ static struct profile_config default_configs[] = {
 		hsp_ag_record,
 		ag_confirm,
 		hs_newconnection_reply },
+	{ HFP_HS_UUID,
+		DEFAULT_HF_HS_CHANNEL,
+		HFP_AG_UUID,
+		HANDSFREE_AGW_SVCLASS_ID,
+		HANDSFREE_PROFILE_ID,
+		hfp_hs_record,
+		hf_confirm,
+		ag_newconnection_reply },
 	{ HFP_AG_UUID,
 		DEFAULT_HF_AG_CHANNEL,
 		HFP_HS_UUID,
diff --git a/audio/transport.c b/audio/transport.c
index 7236e43..7a9b5ea 100644
--- a/audio/transport.c
+++ b/audio/transport.c
@@ -866,6 +866,10 @@ static gboolean check_telephony_agent_name(struct media_transport *transport,
 	if (tel_agent != NULL && g_strcmp0(tel_agent, sender) == 0)
 		return TRUE;
 
+	tel_agent = gateway_get_telephony_agent_name(transport->device);
+	if (tel_agent != NULL && g_strcmp0(tel_agent, sender) == 0)
+		return TRUE;
+
 	return FALSE;
 }
 
diff --git a/doc/hfp-api.txt b/doc/hfp-api.txt
index fad89ae..afc1277 100644
--- a/doc/hfp-api.txt
+++ b/doc/hfp-api.txt
@@ -22,24 +22,6 @@ Methods		void Connect()
 			Returns all properties for the interface. See the
 			properties section for available properties.
 
-		void RegisterAgent(object path)
-
-			The object path defines the path the of the agent
-			that will be called when a new Handsfree connection
-			is established.
-
-			If an application disconnects from the bus all of its
-			registered agents will be removed.
-
-		void UnregisterAgent(object path)
-
-			This unregisters the agent that has been previously
-			registered. The object path parameter must match the
-			same value that has been used on registration.
-
-			Possible Errors: org.bluez.Error.Failed
-					 org.bluez.Error.InvalidArguments
-
 
 Signals		PropertyChanged(string name, variant value)
 
@@ -54,31 +36,3 @@ Properties	string State [readonly]
 				"connecting"
 				"connected"
 				"playing"
-
-HandsfreeAgent hierarchy
-===============
-
-Service         unique name
-Interface       org.bluez.HandsfreeAgent
-Object path     freely definable
-
-Methods		void NewConnection(filedescriptor fd, uint16 version)
-
-			This method gets called whenever a new handsfree
-			connection has been established.  The objectpath
-			contains the object path of the remote device.
-
-			The agent should only return successfully once the
-			establishment of the service level connection (SLC)
-			has been completed.  In the case of Handsfree this
-			means that BRSF exchange has been performed and
-			necessary initialization has been done.
-
-			Possible Errors: org.bluez.Error.InvalidArguments
-					 org.bluez.Error.Failed
-
-		void Release()
-
-			This method gets called whenever the service daemon
-			unregisters the agent or whenever the Adapter where
-			the HandsfreeAgent registers itself is removed.
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v17 10/15] audio: Send transport path to telephony agent
From: Frédéric Danis @ 2012-08-03 12:07 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1343995640-19784-1-git-send-email-frederic.danis@linux.intel.com>

Add the ability to set MediaTransport path to the HSP/HFP agent during
the call of the NewConnection method.
Accept MediaTransport property change from telephony agent in addition
to Media Endpoint.

This allows external program, implementing telephony agent, to change
Noise Reduction/Echo Cancellation (ECNR), Inband ringtone, speaker
and microphone volume settings of the audio system (i.e. Pulse Audio)
through the MediaTransport.
---
 audio/headset.c   |   31 +++++++++++++++++++++++++++++++
 audio/headset.h   |    3 +++
 audio/media.c     |   17 +++++++++++++++++
 audio/telephony.c |   18 ++++++++++++++++++
 audio/telephony.h |    3 +++
 audio/transport.c |   23 +++++++++++++++++++++--
 6 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/audio/headset.c b/audio/headset.c
index ec4db59..fe4e62d 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -109,6 +109,7 @@ struct headset {
 
 	GIOChannel *tmp_rfcomm;
 	const char *connecting_uuid;
+	const char *connecting_transport_path;
 	GIOChannel *sco;
 	guint sco_id;
 
@@ -403,6 +404,9 @@ void headset_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		goto failed;
 
 	hs->connecting_uuid = NULL;
+	telephony_set_media_transport_path(hs->tel_dev,
+						hs->connecting_transport_path);
+	hs->connecting_transport_path = NULL;
 
 	g_io_channel_unref(hs->tmp_rfcomm);
 	hs->tmp_rfcomm = NULL;
@@ -582,6 +586,7 @@ static int get_records(struct audio_device *device, headset_stream_cb_t cb,
 						get_record_cb, device, NULL);
 	if (err < 0) {
 		hs->connecting_uuid = NULL;
+		hs->connecting_transport_path = NULL;
 		return err;
 	}
 
@@ -1137,6 +1142,31 @@ void headset_set_connecting_uuid(struct audio_device *dev, const char *uuid)
 	hs->connecting_uuid = uuid;
 }
 
+void headset_set_media_transport_path(struct audio_device *dev,
+							const char *path)
+{
+	struct headset *hs = dev->headset;
+
+	DBG("MediaTransport path: %s", path);
+
+	if (hs->tel_dev == NULL) {
+		hs->connecting_transport_path = path;
+		return;
+	}
+
+	telephony_set_media_transport_path(hs->tel_dev, path);
+}
+
+const char *headset_get_telephony_agent_name(struct audio_device *dev)
+{
+	struct headset *hs = dev->headset;
+
+	if (hs == NULL || hs->tel_dev == NULL)
+		return NULL;
+
+	return telephony_get_agent_name(hs->tel_dev);
+}
+
 int headset_connect_rfcomm(struct audio_device *dev, GIOChannel *io)
 {
 	struct headset *hs = dev->headset;
@@ -1183,6 +1213,7 @@ void headset_set_state(struct audio_device *dev, headset_state_t state)
 		}
 
 		dev->headset->connecting_uuid = NULL;
+		dev->headset->connecting_transport_path = NULL;
 
 		headset_close_rfcomm(dev);
 		emit_property_changed(dev->conn, dev->path,
diff --git a/audio/headset.h b/audio/headset.h
index 2915495..a20b587 100644
--- a/audio/headset.h
+++ b/audio/headset.h
@@ -105,3 +105,6 @@ void headset_shutdown(struct audio_device *dev);
 
 void headset_profile_connection_complete(struct audio_device *dev);
 void headset_set_connecting_uuid(struct audio_device *dev, const char *uuid);
+void headset_set_media_transport_path(struct audio_device *dev,
+							const char *path);
+const char *headset_get_telephony_agent_name(struct audio_device *dev);
diff --git a/audio/media.c b/audio/media.c
index ea6d582..c608c41 100644
--- a/audio/media.c
+++ b/audio/media.c
@@ -475,6 +475,7 @@ static void headset_state_changed(struct audio_device *dev,
 {
 	struct media_endpoint *endpoint = user_data;
 	struct media_transport *transport;
+	const char *path;
 
 	DBG("");
 
@@ -493,6 +494,13 @@ static void headset_state_changed(struct audio_device *dev,
 	case HEADSET_STATE_CONNECTING:
 		set_configuration(endpoint, dev, NULL, 0, headset_setconf_cb,
 								dev, NULL);
+
+		transport = find_device_transport(endpoint, dev);
+		if (transport == NULL)
+			break;
+
+		path = media_transport_get_path(transport);
+		headset_set_media_transport_path(dev, path);
 		break;
 	case HEADSET_STATE_CONNECTED:
 		break;
@@ -704,9 +712,18 @@ static gboolean endpoint_init_ag(struct media_endpoint *endpoint, int *err)
 
 	for (l = list; l != NULL; l = l->next) {
 		struct audio_device *dev = l->data;
+		struct media_transport *transport;
+		const char *path;
 
 		set_configuration(endpoint, dev, NULL, 0,
 						headset_setconf_cb, dev, NULL);
+
+		transport = find_device_transport(endpoint, dev);
+		if (transport == NULL)
+			break;
+
+		path = media_transport_get_path(transport);
+		headset_set_media_transport_path(dev, path);
 	}
 
 	g_slist_free(list);
diff --git a/audio/telephony.c b/audio/telephony.c
index 943c3aa..da1797f 100644
--- a/audio/telephony.c
+++ b/audio/telephony.c
@@ -111,6 +111,8 @@ struct telephony_agent {
  * It represents the connection between telephony agent (name, path and config)
  * and remote device (with its profile version and supported features if they
  * can be retrieved).
+ * If audio is used by profile, Media Transport path is stored to be sent to
+ * telephony agent during NewConnection method call.
  *
  * This is used after authentication completion and remote SDP record retrieval
  * (if supported by profile, i.e. HFP/HSP) until disconnection.
@@ -124,6 +126,7 @@ struct telephony_device {
 	uint16_t		version;	/* remote profile version */
 	uint16_t		features;	/* remote supported features */
 	GIOChannel		*rfcomm;	/* connected RFCOMM channel */
+	const char		*transport_path; /* MediaTransport path */
 	gboolean		pending_sdp;	/* SDP request is pending */
 	DBusPendingCall		*call;		/* D-Bus pending call */
 };
@@ -276,6 +279,10 @@ static gboolean agent_sendfd(struct telephony_device *tel_dev, int fd,
 		dict_append_entry(&dict, "Features", DBUS_TYPE_UINT16,
 							&tel_dev->features);
 
+	if (tel_dev->transport_path != NULL)
+		dict_append_entry(&dict, "Transport", DBUS_TYPE_OBJECT_PATH,
+						&tel_dev->transport_path);
+
 	dbus_message_iter_close_container(&iter, &dict);
 
 	if (!dbus_connection_send_with_reply(connection, msg,
@@ -450,6 +457,17 @@ void telephony_device_disconnect(struct telephony_device *device)
 	g_free(device);
 }
 
+void telephony_set_media_transport_path(struct telephony_device *device,
+						const char *path)
+{
+	device->transport_path = path;
+}
+
+const char *telephony_get_agent_name(struct telephony_device *device)
+{
+	return device->name;
+}
+
 static sdp_record_t *hsp_ag_record(struct telephony_agent *agent)
 {
 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
diff --git a/audio/telephony.h b/audio/telephony.h
index 1e20087..42ce580 100644
--- a/audio/telephony.h
+++ b/audio/telephony.h
@@ -52,6 +52,9 @@ struct telephony_device *telephony_device_connecting(GIOChannel *io,
 					struct audio_device *au_dev,
 					const char *uuid);
 void telephony_device_disconnect(struct telephony_device *device);
+void telephony_set_media_transport_path(struct telephony_device *device,
+						const char *path);
+const char *telephony_get_agent_name(struct telephony_device *device);
 
 gboolean telephony_is_uuid_supported(struct btd_adapter *adapter,
 						const char *uuid);
diff --git a/audio/transport.c b/audio/transport.c
index 6d4ad55..7236e43 100644
--- a/audio/transport.c
+++ b/audio/transport.c
@@ -857,6 +857,18 @@ static int set_property_gateway(struct media_transport *transport,
 	return -EINVAL;
 }
 
+static gboolean check_telephony_agent_name(struct media_transport *transport,
+							const char *sender)
+{
+	const char *tel_agent;
+
+	tel_agent = headset_get_telephony_agent_name(transport->device);
+	if (tel_agent != NULL && g_strcmp0(tel_agent, sender) == 0)
+		return TRUE;
+
+	return FALSE;
+}
+
 static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
@@ -865,6 +877,7 @@ static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
 	DBusMessageIter value;
 	const char *property, *sender;
 	GSList *l;
+	gboolean sender_ok = FALSE;
 	int err;
 
 	if (!dbus_message_iter_init(msg, &iter))
@@ -888,12 +901,18 @@ static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
 		struct media_owner *owner = l->data;
 
 		if (g_strcmp0(owner->name, sender) == 0) {
-			err = transport->set_property(transport, property,
-								&value);
+			sender_ok = TRUE;
 			break;
 		}
 	}
 
+	/* Check if Telephony agent does this request */
+	if (!sender_ok)
+		sender_ok = check_telephony_agent_name(transport, sender);
+
+	if (sender_ok)
+		err = transport->set_property(transport, property, &value);
+
 	if (err < 0) {
 		if (err == -EINVAL)
 			return btd_error_invalid_args(msg);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v17 09/15] audio: Move HFP/HSP AG servers to telephony.c
From: Frédéric Danis @ 2012-08-03 12:07 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1343995640-19784-1-git-send-email-frederic.danis@linux.intel.com>

Move HeadSet/HandsFree AudioGateway RFComm servers from audio/manager.c
to audio/telephony.c.
Doing this, each RfComm server is started (and the related SDP record
advertised) only when an agent registers for its specific profile.
---
 audio/headset.c   |   48 +++----
 audio/headset.h   |    5 +-
 audio/manager.c   |  386 +----------------------------------------------------
 audio/telephony.c |  315 ++++++++++++++++++++++++++++++++++++++++++-
 audio/telephony.h |    2 -
 5 files changed, 332 insertions(+), 424 deletions(-)

diff --git a/audio/headset.c b/audio/headset.c
index 0070953..ec4db59 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -389,7 +389,6 @@ void headset_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	struct audio_device *dev = user_data;
 	struct headset *hs = dev->headset;
 	struct btd_device *btd_dev = dev->btd_dev;
-	struct btd_adapter *adapter;
 	struct pending_connect *p = hs->pending;
 	char hs_address[18];
 
@@ -398,15 +397,6 @@ void headset_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		goto failed;
 	}
 
-	adapter = device_get_adapter(btd_dev);
-
-	/* For HFP telephony isn't ready just disconnect */
-	if (hs->hfp_active && !telephony_is_ready(adapter)) {
-		error("Unable to accept HFP connection since the telephony "
-				"subsystem isn't initialized");
-		goto failed;
-	}
-
 	hs->tel_dev = telephony_device_connecting(chan, btd_dev, dev,
 							hs->connecting_uuid);
 	if (hs->tel_dev == NULL)
@@ -561,20 +551,30 @@ static int get_records(struct audio_device *device, headset_stream_cb_t cb,
 			void *user_data, unsigned int *cb_id)
 {
 	struct headset *hs = device->headset;
-	uint16_t svclass;
+	struct btd_adapter *adapter;
+	gboolean hsp_ag_supported, hfp_ag_supported;
+	uint16_t svclass = 0;
 	uuid_t uuid;
 	int err;
 
-	if (hs->pending && hs->pending->svclass == HANDSFREE_SVCLASS_ID)
-		svclass = HEADSET_SVCLASS_ID;
-	else
-		svclass = hs->search_hfp ? HANDSFREE_SVCLASS_ID :
-							HEADSET_SVCLASS_ID;
+	adapter = device_get_adapter(device->btd_dev);
+
+	hsp_ag_supported = telephony_is_uuid_supported(adapter, HSP_AG_UUID);
+	hfp_ag_supported = telephony_is_uuid_supported(adapter, HFP_AG_UUID);
 
-	if (svclass == HANDSFREE_SVCLASS_ID)
+	if (hfp_ag_supported && hs->search_hfp && hs->pending == NULL) {
+		svclass = HANDSFREE_SVCLASS_ID;
 		hs->connecting_uuid = HFP_AG_UUID;
-	else
+	} else if (hsp_ag_supported) {
+		svclass = HEADSET_SVCLASS_ID;
 		hs->connecting_uuid = HSP_AG_UUID;
+	} else {
+		if (hs->pending) {
+			pending_connect_finalize(device);
+			headset_set_state(device, HEADSET_STATE_DISCONNECTED);
+		}
+		return -1;
+	}
 
 	sdp_uuid16_create(&uuid, svclass);
 
@@ -700,7 +700,6 @@ static DBusMessage *hs_connect(DBusConnection *conn, DBusMessage *msg,
 {
 	struct audio_device *device = data;
 	struct headset *hs = device->headset;
-	struct btd_adapter *adapter;
 	int err;
 
 	if (hs->state == HEADSET_STATE_CONNECTING)
@@ -708,11 +707,6 @@ static DBusMessage *hs_connect(DBusConnection *conn, DBusMessage *msg,
 	else if (hs->state > HEADSET_STATE_CONNECTING)
 		return btd_error_already_connected(msg);
 
-	adapter = device_get_adapter(device->btd_dev);
-
-	if (hs->hfp_handle && !telephony_is_ready(adapter))
-		return btd_error_not_ready(msg);
-
 	device->auto_connect = FALSE;
 
 	err = rfcomm_connect(device, NULL, NULL, NULL);
@@ -922,14 +916,14 @@ register_iface:
 	return hs;
 }
 
-uint32_t headset_config_init(GKeyFile *config)
+void headset_config_init(GKeyFile *config)
 {
 	GError *err = NULL;
 	char *str;
 
 	/* Use the default values if there is no config file */
 	if (config == NULL)
-		return telephony_get_ag_features();
+		return;
 
 	str = g_key_file_get_string(config, "General", "SCORouting",
 					&err);
@@ -945,8 +939,6 @@ uint32_t headset_config_init(GKeyFile *config)
 			error("Invalid Headset Routing value: %s", str);
 		g_free(str);
 	}
-
-	return telephony_get_ag_features();
 }
 
 static gboolean hs_dc_timeout(struct audio_device *dev)
diff --git a/audio/headset.h b/audio/headset.h
index 61e63c8..2915495 100644
--- a/audio/headset.h
+++ b/audio/headset.h
@@ -24,9 +24,6 @@
 
 #define AUDIO_HEADSET_INTERFACE "org.bluez.Headset"
 
-#define DEFAULT_HS_AG_CHANNEL 12
-#define DEFAULT_HF_AG_CHANNEL 13
-
 typedef enum {
 	HEADSET_STATE_DISCONNECTED,
 	HEADSET_STATE_CONNECTING,
@@ -62,7 +59,7 @@ struct headset *headset_init(struct audio_device *dev, uint16_t svc,
 
 void headset_unregister(struct audio_device *dev);
 
-uint32_t headset_config_init(GKeyFile *config);
+void headset_config_init(GKeyFile *config);
 
 void headset_update(struct audio_device *dev, uint16_t svc,
 			const char *uuidstr);
diff --git a/audio/manager.c b/audio/manager.c
index 2b125a0..4ab0186 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -89,11 +89,7 @@ typedef enum {
 struct audio_adapter {
 	struct btd_adapter *btd_adapter;
 	gboolean powered;
-	uint32_t hsp_ag_record_id;
-	uint32_t hfp_ag_record_id;
 	uint32_t hfp_hs_record_id;
-	GIOChannel *hsp_ag_server;
-	GIOChannel *hfp_ag_server;
 	GIOChannel *hfp_hs_server;
 	gint ref;
 };
@@ -226,62 +222,6 @@ static void handle_uuid(const char *uuidstr, struct audio_device *device)
 	}
 }
 
-static sdp_record_t *hsp_ag_record(uint8_t ch)
-{
-	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
-	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
-	uuid_t l2cap_uuid, rfcomm_uuid;
-	sdp_profile_desc_t profile;
-	sdp_record_t *record;
-	sdp_list_t *aproto, *proto[2];
-	sdp_data_t *channel;
-
-	record = sdp_record_alloc();
-	if (!record)
-		return NULL;
-
-	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 = 0x0102;
-	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, &ch);
-	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 Audio Gateway", 0, 0);
-
-	sdp_data_free(channel);
-	sdp_list_free(proto[0], 0);
-	sdp_list_free(proto[1], 0);
-	sdp_list_free(apseq, 0);
-	sdp_list_free(pfseq, 0);
-	sdp_list_free(aproto, 0);
-	sdp_list_free(root, 0);
-	sdp_list_free(svclass_id, 0);
-
-	return record;
-}
-
 static sdp_record_t *hfp_hs_record(uint8_t ch)
 {
 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
@@ -338,201 +278,6 @@ static sdp_record_t *hfp_hs_record(uint8_t ch)
 	return record;
 }
 
-static sdp_record_t *hfp_ag_record(uint8_t ch, uint32_t feat)
-{
-	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
-	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
-	uuid_t l2cap_uuid, rfcomm_uuid;
-	sdp_profile_desc_t profile;
-	sdp_list_t *aproto, *proto[2];
-	sdp_record_t *record;
-	sdp_data_t *channel, *features;
-	uint8_t netid = 0x01;
-	uint16_t sdpfeat;
-	sdp_data_t *network;
-
-	record = sdp_record_alloc();
-	if (!record)
-		return NULL;
-
-	network = sdp_data_alloc(SDP_UINT8, &netid);
-	if (!network) {
-		sdp_record_free(record);
-		return NULL;
-	}
-
-	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, &ch);
-	proto[1] = sdp_list_append(proto[1], channel);
-	apseq = sdp_list_append(apseq, proto[1]);
-
-	sdpfeat = (uint16_t) feat & 0xF;
-	features = sdp_data_alloc(SDP_UINT16, &sdpfeat);
-	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, "Hands-Free Audio Gateway", 0, 0);
-
-	sdp_attr_add(record, SDP_ATTR_EXTERNAL_NETWORK, network);
-
-	sdp_data_free(channel);
-	sdp_list_free(proto[0], 0);
-	sdp_list_free(proto[1], 0);
-	sdp_list_free(apseq, 0);
-	sdp_list_free(pfseq, 0);
-	sdp_list_free(aproto, 0);
-	sdp_list_free(root, 0);
-	sdp_list_free(svclass_id, 0);
-
-	return record;
-}
-
-static void headset_auth_cb(DBusError *derr, void *user_data)
-{
-	struct audio_device *device = user_data;
-	GError *err = NULL;
-	GIOChannel *io;
-
-	if (device->hs_preauth_id) {
-		g_source_remove(device->hs_preauth_id);
-		device->hs_preauth_id = 0;
-	}
-
-	if (derr && dbus_error_is_set(derr)) {
-		error("Access denied: %s", derr->message);
-		headset_set_state(device, HEADSET_STATE_DISCONNECTED);
-		return;
-	}
-
-	io = headset_get_rfcomm(device);
-
-	if (!bt_io_accept(io, headset_connect_cb, device, NULL, &err)) {
-		error("bt_io_accept: %s", err->message);
-		g_error_free(err);
-		headset_set_state(device, HEADSET_STATE_DISCONNECTED);
-		return;
-	}
-}
-
-static gboolean hs_preauth_cb(GIOChannel *chan, GIOCondition cond,
-							gpointer user_data)
-{
-	struct audio_device *device = user_data;
-
-	DBG("Headset disconnected during authorization");
-
-	audio_device_cancel_authorization(device, headset_auth_cb, device);
-
-	headset_set_state(device, HEADSET_STATE_DISCONNECTED);
-
-	device->hs_preauth_id = 0;
-
-	return FALSE;
-}
-
-static void ag_confirm(GIOChannel *chan, gpointer data)
-{
-	const char *server_uuid, *remote_uuid;
-	struct audio_device *device;
-	gboolean hfp_active;
-	bdaddr_t src, dst;
-	int perr;
-	GError *err = NULL;
-	uint8_t ch;
-
-	bt_io_get(chan, BT_IO_RFCOMM, &err,
-			BT_IO_OPT_SOURCE_BDADDR, &src,
-			BT_IO_OPT_DEST_BDADDR, &dst,
-			BT_IO_OPT_CHANNEL, &ch,
-			BT_IO_OPT_INVALID);
-	if (err) {
-		error("%s", err->message);
-		g_error_free(err);
-		goto drop;
-	}
-
-	if (ch == DEFAULT_HS_AG_CHANNEL) {
-		hfp_active = FALSE;
-		server_uuid = HSP_AG_UUID;
-		remote_uuid = HSP_HS_UUID;
-	} else {
-		hfp_active = TRUE;
-		server_uuid = HFP_AG_UUID;
-		remote_uuid = HFP_HS_UUID;
-	}
-
-	device = manager_get_device(&src, &dst, TRUE);
-	if (!device)
-		goto drop;
-
-	if (!manager_allow_headset_connection(device)) {
-		DBG("Refusing headset: too many existing connections");
-		goto drop;
-	}
-
-	if (!device->headset) {
-		btd_device_add_uuid(device->btd_dev, remote_uuid);
-		if (!device->headset)
-			goto drop;
-	}
-
-	if (headset_get_state(device) > HEADSET_STATE_DISCONNECTED) {
-		DBG("Refusing new connection since one already exists");
-		goto drop;
-	}
-
-	headset_set_hfp_active(device, hfp_active);
-	headset_set_rfcomm_initiator(device, TRUE);
-
-	if (headset_connect_rfcomm(device, chan) < 0) {
-		error("headset_connect_rfcomm failed");
-		goto drop;
-	}
-
-	headset_set_state(device, HEADSET_STATE_CONNECTING);
-
-	perr = audio_device_request_authorization(device, server_uuid,
-						headset_auth_cb, device);
-	if (perr < 0) {
-		DBG("Authorization denied: %s", strerror(-perr));
-		headset_set_state(device, HEADSET_STATE_DISCONNECTED);
-		return;
-	}
-
-	device->hs_preauth_id = g_io_add_watch(chan,
-					G_IO_NVAL | G_IO_HUP | G_IO_ERR,
-					hs_preauth_cb, device);
-
-	device->auto_connect = auto_connect;
-
-	return;
-
-drop:
-	g_io_channel_shutdown(chan, TRUE, NULL);
-}
-
 static void gateway_auth_cb(DBusError *derr, void *user_data)
 {
 	struct audio_device *device = user_data;
@@ -608,108 +353,6 @@ drop:
 	g_io_channel_shutdown(chan, TRUE, NULL);
 }
 
-static int headset_server_init(struct audio_adapter *adapter)
-{
-	uint8_t chan = DEFAULT_HS_AG_CHANNEL;
-	sdp_record_t *record;
-	gboolean master = TRUE;
-	GError *err = NULL;
-	uint32_t features;
-	GIOChannel *io;
-	bdaddr_t src;
-
-	if (config) {
-		gboolean tmp;
-
-		tmp = g_key_file_get_boolean(config, "General", "Master",
-						&err);
-		if (err) {
-			DBG("audio.conf: %s", err->message);
-			g_clear_error(&err);
-		} else
-			master = tmp;
-	}
-
-	adapter_get_address(adapter->btd_adapter, &src);
-
-	io =  bt_io_listen(BT_IO_RFCOMM, NULL, ag_confirm, adapter, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, &src,
-				BT_IO_OPT_CHANNEL, chan,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-				BT_IO_OPT_MASTER, master,
-				BT_IO_OPT_INVALID);
-	if (!io)
-		goto failed;
-
-	adapter->hsp_ag_server = io;
-
-	record = hsp_ag_record(chan);
-	if (!record) {
-		error("Unable to allocate new service record");
-		goto failed;
-	}
-
-	if (add_record_to_server(&src, record) < 0) {
-		error("Unable to register HS AG service record");
-		sdp_record_free(record);
-		goto failed;
-	}
-	adapter->hsp_ag_record_id = record->handle;
-
-	features = headset_config_init(config);
-
-	if (!enabled.hfp)
-		return 0;
-
-	chan = DEFAULT_HF_AG_CHANNEL;
-
-	io = bt_io_listen(BT_IO_RFCOMM, NULL, ag_confirm, adapter, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, &src,
-				BT_IO_OPT_CHANNEL, chan,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-				BT_IO_OPT_MASTER, master,
-				BT_IO_OPT_INVALID);
-	if (!io)
-		goto failed;
-
-	adapter->hfp_ag_server = io;
-
-	record = hfp_ag_record(chan, features);
-	if (!record) {
-		error("Unable to allocate new service record");
-		goto failed;
-	}
-
-	if (add_record_to_server(&src, record) < 0) {
-		error("Unable to register HF AG service record");
-		sdp_record_free(record);
-		goto failed;
-	}
-	adapter->hfp_ag_record_id = record->handle;
-
-	return 0;
-
-failed:
-	if (err) {
-		error("%s", err->message);
-		g_error_free(err);
-	}
-
-	if (adapter->hsp_ag_server) {
-		g_io_channel_shutdown(adapter->hsp_ag_server, TRUE, NULL);
-		g_io_channel_unref(adapter->hsp_ag_server);
-		adapter->hsp_ag_server = NULL;
-	}
-
-	if (adapter->hfp_ag_server) {
-		g_io_channel_shutdown(adapter->hfp_ag_server, TRUE, NULL);
-		g_io_channel_unref(adapter->hfp_ag_server);
-		adapter->hfp_ag_server = NULL;
-	}
-
-	return -1;
-}
-
 static int gateway_server_init(struct audio_adapter *adapter)
 {
 	uint8_t chan = DEFAULT_HFP_HS_CHANNEL;
@@ -903,7 +546,6 @@ static int headset_server_probe(struct btd_adapter *adapter)
 {
 	struct audio_adapter *adp;
 	const gchar *path = adapter_get_path(adapter);
-	int err;
 
 	DBG("path %s", path);
 
@@ -911,11 +553,7 @@ static int headset_server_probe(struct btd_adapter *adapter)
 	if (!adp)
 		return -EINVAL;
 
-	err = headset_server_init(adp);
-	if (err < 0) {
-		audio_adapter_unref(adp);
-		return err;
-	}
+	headset_config_init(config);
 
 	btd_adapter_register_powered_callback(adapter, state_changed);
 
@@ -935,28 +573,6 @@ static void headset_server_remove(struct btd_adapter *adapter)
 	if (!adp)
 		return;
 
-	if (adp->hsp_ag_record_id) {
-		remove_record_from_server(adp->hsp_ag_record_id);
-		adp->hsp_ag_record_id = 0;
-	}
-
-	if (adp->hsp_ag_server) {
-		g_io_channel_shutdown(adp->hsp_ag_server, TRUE, NULL);
-		g_io_channel_unref(adp->hsp_ag_server);
-		adp->hsp_ag_server = NULL;
-	}
-
-	if (adp->hfp_ag_record_id) {
-		remove_record_from_server(adp->hfp_ag_record_id);
-		adp->hfp_ag_record_id = 0;
-	}
-
-	if (adp->hfp_ag_server) {
-		g_io_channel_shutdown(adp->hfp_ag_server, TRUE, NULL);
-		g_io_channel_unref(adp->hfp_ag_server);
-		adp->hfp_ag_server = NULL;
-	}
-
 	audio_adapter_unref(adp);
 }
 
diff --git a/audio/telephony.c b/audio/telephony.c
index 49ccafd..943c3aa 100644
--- a/audio/telephony.c
+++ b/audio/telephony.c
@@ -43,18 +43,24 @@
 
 #include "log.h"
 #include "device.h"
+#include "manager.h"
 #include "error.h"
 #include "glib-helper.h"
 #include "sdp-client.h"
 #include "headset.h"
 #include "telephony.h"
 #include "dbus-common.h"
+#include "sdpd.h"
 
 #define AUDIO_TELEPHONY_INTERFACE "org.bluez.Telephony"
 #define AUDIO_TELEPHONY_AGENT_INTERFACE "org.bluez.TelephonyAgent"
 
 #define DEFAULT_HS_HS_CHANNEL 6
+#define DEFAULT_HS_AG_CHANNEL 12
 #define DEFAULT_HF_HS_CHANNEL 7
+#define DEFAULT_HF_AG_CHANNEL 13
+
+struct telephony_agent;
 
 /*
  * Profile configuration
@@ -62,6 +68,8 @@
  * It describes for each supported profile:
  *  - UUID, RFCOMM channel and security level
  *  - remote UUID, service class and profile descriptor if they exist
+ *  - SDP record create function
+ *  - RFCOMM connection approval callback
  *  - profile connection complete callback called when agent replied to
  *    NewConnection method call
  */
@@ -71,13 +79,17 @@ struct profile_config {
 	const char		*r_uuid;
 	uint16_t		r_class;
 	uint16_t		r_profile;
+	sdp_record_t		*(*record_init)(struct telephony_agent *agent);
+	BtIOConfirm		confirm;
 	DBusPendingCallNotifyFunction connection_reply;
 };
 
 /*
  * Telephony agent
  *
- * It represents the telephony agent with provided version and features.
+ * It represents the telephony agent for which BlueZ will publish an
+ * SDP record (record_id) with provided version and features.
+ * BlueZ will also listen for incoming connection on io.
  *
  * This is done by adapter.
  */
@@ -89,6 +101,8 @@ struct telephony_agent {
 	uint16_t		version;	/* agent profile version */
 	uint16_t		features;	/* agent supported features */
 	guint			watch;		/* agent disconnect watcher */
+	GIOChannel		*io;		/* listener channel */
+	uint32_t		record_id;	/* SDP record id */
 };
 
 /*
@@ -149,6 +163,14 @@ static void free_agent(struct telephony_agent *agent)
 {
 	DBusMessage *msg;
 
+	if (agent->record_id)
+		remove_record_from_server(agent->record_id);
+
+	if (agent->io) {
+		g_io_channel_shutdown(agent->io, TRUE, NULL);
+		g_io_channel_unref(agent->io);
+	}
+
 	if (agent->watch) {
 		msg = dbus_message_new_method_call(agent->name, agent->path,
 				AUDIO_TELEPHONY_AGENT_INTERFACE, "Release");
@@ -428,14 +450,255 @@ void telephony_device_disconnect(struct telephony_device *device)
 	g_free(device);
 }
 
-gboolean telephony_is_ready(struct btd_adapter *adapter)
+static sdp_record_t *hsp_ag_record(struct telephony_agent *agent)
 {
-	return find_agent(adapter, NULL, NULL, HFP_AG_UUID) ? TRUE : FALSE;
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
+	uuid_t l2cap_uuid, rfcomm_uuid;
+	sdp_profile_desc_t profile;
+	sdp_record_t *record;
+	sdp_list_t *aproto, *proto[2];
+	sdp_data_t *channel;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	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 = agent->version;
+	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, &agent->config->channel);
+	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 Audio Gateway", 0, 0);
+
+	sdp_data_free(channel);
+	sdp_list_free(proto[0], 0);
+	sdp_list_free(proto[1], 0);
+	sdp_list_free(apseq, 0);
+	sdp_list_free(pfseq, 0);
+	sdp_list_free(aproto, 0);
+	sdp_list_free(root, 0);
+	sdp_list_free(svclass_id, 0);
+
+	return record;
 }
 
-uint32_t telephony_get_ag_features(void)
+static sdp_record_t *hfp_ag_record(struct telephony_agent *agent)
 {
-	return 0;
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
+	uuid_t l2cap_uuid, rfcomm_uuid;
+	sdp_profile_desc_t profile;
+	sdp_list_t *aproto, *proto[2];
+	sdp_record_t *record;
+	sdp_data_t *channel, *features;
+	uint8_t netid;
+	uint16_t sdpfeat;
+	sdp_data_t *network;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	netid = agent->features & AG_FEATURE_REJECT_A_CALL ? 1 : 0;
+	network = sdp_data_alloc(SDP_UINT8, &netid);
+	if (!network) {
+		sdp_record_free(record);
+		return NULL;
+	}
+
+	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 = agent->version;
+	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, &agent->config->channel);
+	proto[1] = sdp_list_append(proto[1], channel);
+	apseq = sdp_list_append(apseq, proto[1]);
+
+	sdpfeat = agent->features & 0x1F;
+	features = sdp_data_alloc(SDP_UINT16, &sdpfeat);
+	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, "Hands-Free Audio Gateway", 0, 0);
+
+	sdp_attr_add(record, SDP_ATTR_EXTERNAL_NETWORK, network);
+
+	sdp_data_free(channel);
+	sdp_list_free(proto[0], 0);
+	sdp_list_free(proto[1], 0);
+	sdp_list_free(apseq, 0);
+	sdp_list_free(pfseq, 0);
+	sdp_list_free(aproto, 0);
+	sdp_list_free(root, 0);
+	sdp_list_free(svclass_id, 0);
+
+	return record;
+}
+
+static void headset_auth_cb(DBusError *derr, void *user_data)
+{
+	struct audio_device *au_dev = user_data;
+	GError *err = NULL;
+	GIOChannel *io;
+
+	if (au_dev->hs_preauth_id) {
+		g_source_remove(au_dev->hs_preauth_id);
+		au_dev->hs_preauth_id = 0;
+	}
+
+	if (derr && dbus_error_is_set(derr)) {
+		error("Access denied: %s", derr->message);
+		headset_set_state(au_dev, HEADSET_STATE_DISCONNECTED);
+		return;
+	}
+
+	io = headset_get_rfcomm(au_dev);
+
+	if (!bt_io_accept(io, headset_connect_cb, au_dev, NULL, &err)) {
+		error("bt_io_accept: %s", err->message);
+		g_error_free(err);
+		headset_set_state(au_dev, HEADSET_STATE_DISCONNECTED);
+		return;
+	}
+}
+
+static gboolean hs_preauth_cb(GIOChannel *chan, GIOCondition cond,
+							gpointer user_data)
+{
+	struct audio_device *au_dev = user_data;
+
+	DBG("Headset disconnected during authorization");
+
+	audio_device_cancel_authorization(au_dev, headset_auth_cb, au_dev);
+
+	headset_set_state(au_dev, HEADSET_STATE_DISCONNECTED);
+
+	au_dev->hs_preauth_id = 0;
+
+	return FALSE;
+}
+
+static void ag_confirm(GIOChannel *chan, gpointer data)
+{
+	struct telephony_agent *agent = data;
+	struct audio_device *au_dev;
+	gboolean hfp_active;
+	bdaddr_t src, dst;
+	int perr;
+	GError *err = NULL;
+	uint8_t ch;
+
+	bt_io_get(chan, BT_IO_RFCOMM, &err,
+			BT_IO_OPT_SOURCE_BDADDR, &src,
+			BT_IO_OPT_DEST_BDADDR, &dst,
+			BT_IO_OPT_CHANNEL, &ch,
+			BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", err->message);
+		g_error_free(err);
+		goto drop;
+	}
+
+	/* TODO: to remove ? */
+	if (ch == DEFAULT_HS_AG_CHANNEL)
+		hfp_active = FALSE;
+	else
+		hfp_active = TRUE;
+
+	au_dev = manager_get_device(&src, &dst, TRUE);
+	if (!au_dev)
+		goto drop;
+
+	if (!manager_allow_headset_connection(au_dev)) {
+		DBG("Refusing headset: too many existing connections");
+		goto drop;
+	}
+
+	if (!au_dev->headset) {
+		btd_device_add_uuid(au_dev->btd_dev, agent->config->r_uuid);
+		if (!au_dev->headset)
+			goto drop;
+	}
+
+	if (headset_get_state(au_dev) > HEADSET_STATE_DISCONNECTED) {
+		DBG("Refusing new connection since one already exists");
+		goto drop;
+	}
+
+	headset_set_hfp_active(au_dev, hfp_active);
+	headset_set_rfcomm_initiator(au_dev, TRUE);
+	headset_set_connecting_uuid(au_dev, agent->config->uuid);
+
+	if (headset_connect_rfcomm(au_dev, chan) < 0) {
+		error("headset_connect_rfcomm failed");
+		goto drop;
+	}
+
+	headset_set_state(au_dev, HEADSET_STATE_CONNECTING);
+
+	perr = audio_device_request_authorization(au_dev, agent->config->uuid,
+						headset_auth_cb, au_dev);
+	if (perr < 0) {
+		DBG("Authorization denied: %s", strerror(-perr));
+		headset_set_state(au_dev, HEADSET_STATE_DISCONNECTED);
+		return;
+	}
+
+	au_dev->hs_preauth_id = g_io_add_watch(chan,
+					G_IO_NVAL | G_IO_HUP | G_IO_ERR,
+					hs_preauth_cb, au_dev);
+
+#if 0
+	device->auto_connect = auto_connect;
+#endif
+
+	return;
+
+drop:
+	g_io_channel_shutdown(chan, TRUE, NULL);
 }
 
 static struct profile_config default_configs[] = {
@@ -444,12 +707,16 @@ static struct profile_config default_configs[] = {
 		HSP_HS_UUID,
 		HEADSET_SVCLASS_ID,
 		HEADSET_PROFILE_ID,
+		hsp_ag_record,
+		ag_confirm,
 		hs_newconnection_reply },
 	{ HFP_AG_UUID,
 		DEFAULT_HF_AG_CHANNEL,
 		HFP_HS_UUID,
 		HANDSFREE_SVCLASS_ID,
 		HANDSFREE_PROFILE_ID,
+		hfp_ag_record,
+		ag_confirm,
 		hs_newconnection_reply },
 };
 
@@ -499,6 +766,10 @@ static DBusMessage *register_agent(DBusConnection *conn,
 	uint16_t version = 0;
 	uint16_t features = 0xFFFF;
 	struct telephony_agent *agent;
+	sdp_record_t *record;
+	bdaddr_t src;
+	gboolean master = TRUE;
+	GError *err = NULL;
 
 	sender = dbus_message_get_sender(msg);
 
@@ -529,9 +800,43 @@ static DBusMessage *register_agent(DBusConnection *conn,
 							agent_disconnect_cb,
 							agent, NULL);
 
+	record = agent->config->record_init(agent);
+	if (!record) {
+		error("Unable to allocate new service record");
+		return btd_error_failed(msg, "Unable to allocate new service " \
+						"record");
+	}
+
 	DBG("Register agent : %s%s for %s version 0x%04X with features 0x%02X",
 					sender, path, uuid, version, features);
 
+	/* start RFComm agent server */
+	adapter_get_address(adapter, &src);
+
+	agent->io = bt_io_listen(BT_IO_RFCOMM, NULL, agent->config->confirm,
+				agent, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, &src,
+				BT_IO_OPT_CHANNEL, agent->config->channel,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+				BT_IO_OPT_MASTER, master,
+				BT_IO_OPT_INVALID);
+	if (agent->io == NULL) {
+		error("Unable to register server");
+		sdp_record_free(record);
+		free_agent(agent);
+		return btd_error_failed(msg, "Failed to register server");
+	}
+
+	/* advertise agent sdp record */
+	if (add_record_to_server(&src, record) < 0) {
+		error("Unable to register service record");
+		sdp_record_free(record);
+		free_agent(agent);
+		return btd_error_failed(msg, "Failed to register sdp record");
+	}
+
+	agent->record_id = record->handle;
+
 	agents = g_slist_append(agents, agent);
 
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
diff --git a/audio/telephony.h b/audio/telephony.h
index 1a4ab06..1e20087 100644
--- a/audio/telephony.h
+++ b/audio/telephony.h
@@ -53,8 +53,6 @@ struct telephony_device *telephony_device_connecting(GIOChannel *io,
 					const char *uuid);
 void telephony_device_disconnect(struct telephony_device *device);
 
-gboolean telephony_is_ready(struct btd_adapter *adapter);
-uint32_t telephony_get_ag_features(void);
 gboolean telephony_is_uuid_supported(struct btd_adapter *adapter,
 						const char *uuid);
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v17 08/15] audio: Remove oFono telephony driver
From: Frédéric Danis @ 2012-08-03 12:07 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1343995640-19784-1-git-send-email-frederic.danis@linux.intel.com>

Remove oFono telephony driver which has been deprecated by
org.bluez.Telephony interface.
---
 audio/telephony-ofono.c | 1637 -----------------------------------------------
 1 file changed, 1637 deletions(-)
 delete mode 100644 audio/telephony-ofono.c

diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
deleted file mode 100644
index 961fedd..0000000
--- a/audio/telephony-ofono.c
+++ /dev/null
@@ -1,1637 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2009-2010  Intel Corporation
- *  Copyright (C) 2006-2009  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *
- *
- *  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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <glib.h>
-#include <dbus/dbus.h>
-#include <gdbus.h>
-
-#include <bluetooth/sdp.h>
-
-#include "log.h"
-#include "telephony.h"
-
-enum net_registration_status {
-	NETWORK_REG_STATUS_HOME = 0x00,
-	NETWORK_REG_STATUS_ROAM,
-	NETWORK_REG_STATUS_NOSERV
-};
-
-struct voice_call {
-	char *obj_path;
-	int status;
-	gboolean originating;
-	gboolean conference;
-	char *number;
-	guint watch;
-};
-
-static DBusConnection *connection = NULL;
-static char *modem_obj_path = NULL;
-static char *last_dialed_number = NULL;
-static GSList *calls = NULL;
-static GSList *watches = NULL;
-static GSList *pending = NULL;
-
-#define OFONO_BUS_NAME "org.ofono"
-#define OFONO_PATH "/"
-#define OFONO_MODEM_INTERFACE "org.ofono.Modem"
-#define OFONO_MANAGER_INTERFACE "org.ofono.Manager"
-#define OFONO_NETWORKREG_INTERFACE "org.ofono.NetworkRegistration"
-#define OFONO_VCMANAGER_INTERFACE "org.ofono.VoiceCallManager"
-#define OFONO_VC_INTERFACE "org.ofono.VoiceCall"
-
-/* HAL battery namespace key values */
-static int battchg_cur = -1;    /* "battery.charge_level.current" */
-static int battchg_last = -1;   /* "battery.charge_level.last_full" */
-static int battchg_design = -1; /* "battery.charge_level.design" */
-
-static struct {
-	uint8_t status;
-	uint32_t signals_bar;
-	char *operator_name;
-} net = {
-	.status = NETWORK_REG_STATUS_NOSERV,
-	.signals_bar = 0,
-	.operator_name = NULL,
-};
-
-static const char *chld_str = "0,1,1x,2,2x,3,4";
-static char *subscriber_number = NULL;
-
-static gboolean events_enabled = FALSE;
-
-static struct indicator ofono_indicators[] =
-{
-	{ "battchg",	"0-5",	5,	TRUE },
-	{ "signal",	"0-5",	5,	TRUE },
-	{ "service",	"0,1",	1,	TRUE },
-	{ "call",	"0,1",	0,	TRUE },
-	{ "callsetup",	"0-3",	0,	TRUE },
-	{ "callheld",	"0-2",	0,	FALSE },
-	{ "roam",	"0,1",	0,	TRUE },
-	{ NULL }
-};
-
-static struct voice_call *find_vc(const char *path)
-{
-	GSList *l;
-
-	for (l = calls; l != NULL; l = l->next) {
-		struct voice_call *vc = l->data;
-
-		if (g_str_equal(vc->obj_path, path))
-			return vc;
-	}
-
-	return NULL;
-}
-
-static struct voice_call *find_vc_with_status(int status)
-{
-	GSList *l;
-
-	for (l = calls; l != NULL; l = l->next) {
-		struct voice_call *vc = l->data;
-
-		if (vc->status == status)
-			return vc;
-	}
-
-	return NULL;
-}
-
-static struct voice_call *find_vc_without_status(int status)
-{
-	GSList *l;
-
-	for (l = calls; l != NULL; l = l->next) {
-		struct voice_call *call = l->data;
-
-		if (call->status != status)
-			return call;
-	}
-
-	return NULL;
-}
-
-static int number_type(const char *number)
-{
-	if (number == NULL)
-		return NUMBER_TYPE_TELEPHONY;
-
-	if (number[0] == '+' || strncmp(number, "00", 2) == 0)
-		return NUMBER_TYPE_INTERNATIONAL;
-
-	return NUMBER_TYPE_TELEPHONY;
-}
-
-void telephony_device_connected(void *telephony_device)
-{
-	struct voice_call *coming;
-
-	DBG("telephony-ofono: device %p connected", telephony_device);
-
-	coming = find_vc_with_status(CALL_STATUS_ALERTING);
-	if (coming) {
-		if (find_vc_with_status(CALL_STATUS_ACTIVE))
-			telephony_call_waiting_ind(coming->number,
-						number_type(coming->number));
-		else
-			telephony_incoming_call_ind(coming->number,
-						number_type(coming->number));
-	}
-}
-
-void telephony_device_disconnected(void *telephony_device)
-{
-	DBG("telephony-ofono: device %p disconnected", telephony_device);
-	events_enabled = FALSE;
-}
-
-void telephony_event_reporting_req(void *telephony_device, int ind)
-{
-	events_enabled = ind == 1 ? TRUE : FALSE;
-
-	telephony_event_reporting_rsp(telephony_device, CME_ERROR_NONE);
-}
-
-void telephony_response_and_hold_req(void *telephony_device, int rh)
-{
-	telephony_response_and_hold_rsp(telephony_device,
-						CME_ERROR_NOT_SUPPORTED);
-}
-
-void telephony_last_dialed_number_req(void *telephony_device)
-{
-	DBG("telephony-ofono: last dialed number request");
-
-	if (last_dialed_number)
-		telephony_dial_number_req(telephony_device, last_dialed_number);
-	else
-		telephony_last_dialed_number_rsp(telephony_device,
-				CME_ERROR_NOT_ALLOWED);
-}
-
-static int send_method_call(const char *dest, const char *path,
-                                const char *interface, const char *method,
-                                DBusPendingCallNotifyFunction cb,
-                                void *user_data, int type, ...)
-{
-	DBusMessage *msg;
-	DBusPendingCall *call;
-	va_list args;
-
-	msg = dbus_message_new_method_call(dest, path, interface, method);
-	if (!msg) {
-		error("Unable to allocate new D-Bus %s message", method);
-		return -ENOMEM;
-	}
-
-	va_start(args, type);
-
-	if (!dbus_message_append_args_valist(msg, type, args)) {
-		dbus_message_unref(msg);
-		va_end(args);
-		return -EIO;
-	}
-
-	va_end(args);
-
-	if (!cb) {
-		g_dbus_send_message(connection, msg);
-		return 0;
-	}
-
-	if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
-		error("Sending %s failed", method);
-		dbus_message_unref(msg);
-		return -EIO;
-	}
-
-	dbus_pending_call_set_notify(call, cb, user_data, NULL);
-	pending = g_slist_prepend(pending, call);
-	dbus_message_unref(msg);
-
-	return 0;
-}
-
-static int answer_call(struct voice_call *vc)
-{
-	DBG("%s", vc->number);
-	return send_method_call(OFONO_BUS_NAME, vc->obj_path,
-						OFONO_VC_INTERFACE, "Answer",
-						NULL, NULL, DBUS_TYPE_INVALID);
-}
-
-static int release_call(struct voice_call *vc)
-{
-	DBG("%s", vc->number);
-	return send_method_call(OFONO_BUS_NAME, vc->obj_path,
-						OFONO_VC_INTERFACE, "Hangup",
-						NULL, NULL, DBUS_TYPE_INVALID);
-}
-
-static int release_answer_calls(void)
-{
-	DBG("");
-	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
-						OFONO_VCMANAGER_INTERFACE,
-						"ReleaseAndAnswer",
-						NULL, NULL, DBUS_TYPE_INVALID);
-}
-
-static int split_call(struct voice_call *call)
-{
-	DBG("%s", call->number);
-	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
-						OFONO_VCMANAGER_INTERFACE,
-						"PrivateChat",
-						NULL, NULL,
-						DBUS_TYPE_OBJECT_PATH,
-						call->obj_path,
-						DBUS_TYPE_INVALID);
-	return -1;
-}
-
-static int swap_calls(void)
-{
-	DBG("");
-	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
-						OFONO_VCMANAGER_INTERFACE,
-						"SwapCalls",
-						NULL, NULL, DBUS_TYPE_INVALID);
-}
-
-static int create_conference(void)
-{
-	DBG("");
-	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
-						OFONO_VCMANAGER_INTERFACE,
-						"CreateMultiparty",
-						NULL, NULL, DBUS_TYPE_INVALID);
-}
-
-static int release_conference(void)
-{
-	DBG("");
-	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
-						OFONO_VCMANAGER_INTERFACE,
-						"HangupMultiparty",
-						NULL, NULL, DBUS_TYPE_INVALID);
-}
-
-static int call_transfer(void)
-{
-	DBG("");
-	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
-						OFONO_VCMANAGER_INTERFACE,
-						"Transfer",
-						NULL, NULL, DBUS_TYPE_INVALID);
-}
-
-void telephony_terminate_call_req(void *telephony_device)
-{
-	struct voice_call *call;
-	struct voice_call *alerting;
-	int err;
-
-	call = find_vc_with_status(CALL_STATUS_ACTIVE);
-	if (!call)
-		call = calls->data;
-
-	if (!call) {
-		error("No active call");
-		telephony_terminate_call_rsp(telephony_device,
-						CME_ERROR_NOT_ALLOWED);
-		return;
-	}
-
-	alerting = find_vc_with_status(CALL_STATUS_ALERTING);
-	if (call->status == CALL_STATUS_HELD && alerting)
-		err = release_call(alerting);
-	else if (call->conference)
-		err = release_conference();
-	else
-		err = release_call(call);
-
-	if (err < 0)
-		telephony_terminate_call_rsp(telephony_device,
-						CME_ERROR_AG_FAILURE);
-	else
-		telephony_terminate_call_rsp(telephony_device, CME_ERROR_NONE);
-}
-
-void telephony_answer_call_req(void *telephony_device)
-{
-	struct voice_call *vc;
-	int ret;
-
-	vc = find_vc_with_status(CALL_STATUS_INCOMING);
-	if (!vc)
-		vc = find_vc_with_status(CALL_STATUS_ALERTING);
-
-	if (!vc)
-		vc = find_vc_with_status(CALL_STATUS_WAITING);
-
-	if (!vc) {
-		telephony_answer_call_rsp(telephony_device,
-					CME_ERROR_NOT_ALLOWED);
-		return;
-	}
-
-	ret = answer_call(vc);
-	if (ret < 0) {
-		telephony_answer_call_rsp(telephony_device,
-					CME_ERROR_AG_FAILURE);
-		return;
-	}
-
-	telephony_answer_call_rsp(telephony_device, CME_ERROR_NONE);
-}
-
-void telephony_dial_number_req(void *telephony_device, const char *number)
-{
-	const char *clir;
-	int ret;
-
-	DBG("telephony-ofono: dial request to %s", number);
-
-	if (!modem_obj_path) {
-		telephony_dial_number_rsp(telephony_device,
-					CME_ERROR_AG_FAILURE);
-		return;
-	}
-
-	if (!strncmp(number, "*31#", 4)) {
-		number += 4;
-		clir = "enabled";
-	} else if (!strncmp(number, "#31#", 4)) {
-		number += 4;
-		clir =  "disabled";
-	} else
-		clir = "default";
-
-	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
-			OFONO_VCMANAGER_INTERFACE,
-                        "Dial", NULL, NULL,
-			DBUS_TYPE_STRING, &number,
-			DBUS_TYPE_STRING, &clir,
-			DBUS_TYPE_INVALID);
-
-	if (ret < 0)
-		telephony_dial_number_rsp(telephony_device,
-			CME_ERROR_AG_FAILURE);
-	else
-		telephony_dial_number_rsp(telephony_device, CME_ERROR_NONE);
-}
-
-void telephony_transmit_dtmf_req(void *telephony_device, char tone)
-{
-	char *tone_string;
-	int ret;
-
-	DBG("telephony-ofono: transmit dtmf: %c", tone);
-
-	if (!modem_obj_path) {
-		telephony_transmit_dtmf_rsp(telephony_device,
-					CME_ERROR_AG_FAILURE);
-		return;
-	}
-
-	tone_string = g_strdup_printf("%c", tone);
-	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
-			OFONO_VCMANAGER_INTERFACE,
-			"SendTones", NULL, NULL,
-			DBUS_TYPE_STRING, &tone_string,
-			DBUS_TYPE_INVALID);
-	g_free(tone_string);
-
-	if (ret < 0)
-		telephony_transmit_dtmf_rsp(telephony_device,
-			CME_ERROR_AG_FAILURE);
-	else
-		telephony_transmit_dtmf_rsp(telephony_device, CME_ERROR_NONE);
-}
-
-void telephony_subscriber_number_req(void *telephony_device)
-{
-	DBG("telephony-ofono: subscriber number request");
-
-	if (subscriber_number)
-		telephony_subscriber_number_ind(subscriber_number,
-						NUMBER_TYPE_TELEPHONY,
-						SUBSCRIBER_SERVICE_VOICE);
-	telephony_subscriber_number_rsp(telephony_device, CME_ERROR_NONE);
-}
-
-void telephony_list_current_calls_req(void *telephony_device)
-{
-	GSList *l;
-	int i;
-
-	DBG("telephony-ofono: list current calls request");
-
-	for (l = calls, i = 1; l != NULL; l = l->next, i++) {
-		struct voice_call *vc = l->data;
-		int direction, multiparty;
-
-		direction = vc->originating ?
-				CALL_DIR_OUTGOING : CALL_DIR_INCOMING;
-
-		multiparty = vc->conference ?
-				CALL_MULTIPARTY_YES : CALL_MULTIPARTY_NO;
-
-		DBG("call %s direction %d multiparty %d", vc->number,
-							direction, multiparty);
-
-		telephony_list_current_call_ind(i, direction, vc->status,
-					CALL_MODE_VOICE, multiparty,
-					vc->number, number_type(vc->number));
-	}
-
-	telephony_list_current_calls_rsp(telephony_device, CME_ERROR_NONE);
-}
-
-void telephony_operator_selection_req(void *telephony_device)
-{
-	DBG("telephony-ofono: operator selection request");
-
-	telephony_operator_selection_ind(OPERATOR_MODE_AUTO,
-				net.operator_name ? net.operator_name : "");
-	telephony_operator_selection_rsp(telephony_device, CME_ERROR_NONE);
-}
-
-static void foreach_vc_with_status(int status,
-					int (*func)(struct voice_call *vc))
-{
-	GSList *l;
-
-	for (l = calls; l != NULL; l = l->next) {
-		struct voice_call *call = l->data;
-
-		if (call->status == status)
-			func(call);
-	}
-}
-
-void telephony_call_hold_req(void *telephony_device, const char *cmd)
-{
-	const char *idx;
-	struct voice_call *call;
-	int err = 0;
-
-	DBG("telephony-ofono: got call hold request %s", cmd);
-
-	if (strlen(cmd) > 1)
-		idx = &cmd[1];
-	else
-		idx = NULL;
-
-	if (idx)
-		call = g_slist_nth_data(calls, strtol(idx, NULL, 0) - 1);
-	else
-		call = NULL;
-
-	switch (cmd[0]) {
-	case '0':
-		if (find_vc_with_status(CALL_STATUS_WAITING))
-			foreach_vc_with_status(CALL_STATUS_WAITING,
-								release_call);
-		else
-			foreach_vc_with_status(CALL_STATUS_HELD, release_call);
-		break;
-	case '1':
-		if (idx) {
-			if (call)
-				err = release_call(call);
-			break;
-		}
-		err = release_answer_calls();
-		break;
-	case '2':
-		if (idx) {
-			if (call)
-				err = split_call(call);
-		} else {
-			call = find_vc_with_status(CALL_STATUS_WAITING);
-
-			if (call)
-				err = answer_call(call);
-			else
-				err = swap_calls();
-		}
-		break;
-	case '3':
-		if (find_vc_with_status(CALL_STATUS_HELD) ||
-				find_vc_with_status(CALL_STATUS_WAITING))
-			err = create_conference();
-		break;
-	case '4':
-		err = call_transfer();
-		break;
-	default:
-		DBG("Unknown call hold request");
-		break;
-	}
-
-	if (err)
-		telephony_call_hold_rsp(telephony_device,
-					CME_ERROR_AG_FAILURE);
-	else
-		telephony_call_hold_rsp(telephony_device, CME_ERROR_NONE);
-}
-
-void telephony_nr_and_ec_req(void *telephony_device, gboolean enable)
-{
-	DBG("telephony-ofono: got %s NR and EC request",
-			enable ? "enable" : "disable");
-
-	telephony_nr_and_ec_rsp(telephony_device, CME_ERROR_NONE);
-}
-
-void telephony_key_press_req(void *telephony_device, const char *keys)
-{
-	struct voice_call *active, *incoming;
-	int err;
-
-	DBG("telephony-ofono: got key press request for %s", keys);
-
-	incoming = find_vc_with_status(CALL_STATUS_INCOMING);
-
-	active = find_vc_with_status(CALL_STATUS_ACTIVE);
-
-	if (incoming)
-		err = answer_call(incoming);
-	else if (active)
-		err = release_call(active);
-	else
-		err = 0;
-
-	if (err < 0)
-		telephony_key_press_rsp(telephony_device,
-							CME_ERROR_AG_FAILURE);
-	else
-		telephony_key_press_rsp(telephony_device, CME_ERROR_NONE);
-}
-
-void telephony_voice_dial_req(void *telephony_device, gboolean enable)
-{
-	DBG("telephony-ofono: got %s voice dial request",
-			enable ? "enable" : "disable");
-
-	telephony_voice_dial_rsp(telephony_device, CME_ERROR_NOT_SUPPORTED);
-}
-
-static gboolean iter_get_basic_args(DBusMessageIter *iter,
-					int first_arg_type, ...)
-{
-	int type;
-	va_list ap;
-
-	va_start(ap, first_arg_type);
-
-	for (type = first_arg_type; type != DBUS_TYPE_INVALID;
-		type = va_arg(ap, int)) {
-		void *value = va_arg(ap, void *);
-		int real_type = dbus_message_iter_get_arg_type(iter);
-
-		if (real_type != type) {
-			error("iter_get_basic_args: expected %c but got %c",
-				(char) type, (char) real_type);
-			break;
-		}
-
-		dbus_message_iter_get_basic(iter, value);
-		dbus_message_iter_next(iter);
-	}
-
-	va_end(ap);
-
-	return type == DBUS_TYPE_INVALID ? TRUE : FALSE;
-}
-
-static void call_free(void *data)
-{
-	struct voice_call *vc = data;
-
-	DBG("%s", vc->obj_path);
-
-	if (vc->status == CALL_STATUS_ACTIVE)
-		telephony_update_indicator(ofono_indicators, "call",
-							EV_CALL_INACTIVE);
-	else
-		telephony_update_indicator(ofono_indicators, "callsetup",
-							EV_CALLSETUP_INACTIVE);
-
-	if (vc->status == CALL_STATUS_INCOMING)
-		telephony_calling_stopped_ind();
-
-	g_dbus_remove_watch(connection, vc->watch);
-	g_free(vc->obj_path);
-	g_free(vc->number);
-	g_free(vc);
-}
-
-static gboolean handle_vc_property_changed(DBusConnection *conn,
-					DBusMessage *msg, void *data)
-{
-	struct voice_call *vc = data;
-	const char *obj_path = dbus_message_get_path(msg);
-	DBusMessageIter iter, sub;
-	const char *property, *state;
-
-	DBG("path %s", obj_path);
-
-	dbus_message_iter_init(msg, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
-		error("Unexpected signature in vc PropertyChanged signal");
-		return TRUE;
-	}
-
-	dbus_message_iter_get_basic(&iter, &property);
-	DBG("property %s", property);
-
-	dbus_message_iter_next(&iter);
-	dbus_message_iter_recurse(&iter, &sub);
-	if (g_str_equal(property, "State")) {
-		dbus_message_iter_get_basic(&sub, &state);
-		DBG("State %s", state);
-		if (g_str_equal(state, "disconnected")) {
-			calls = g_slist_remove(calls, vc);
-			call_free(vc);
-		} else if (g_str_equal(state, "active")) {
-			telephony_update_indicator(ofono_indicators,
-							"call", EV_CALL_ACTIVE);
-			telephony_update_indicator(ofono_indicators,
-							"callsetup",
-							EV_CALLSETUP_INACTIVE);
-			if (vc->status == CALL_STATUS_INCOMING)
-				telephony_calling_stopped_ind();
-			vc->status = CALL_STATUS_ACTIVE;
-		} else if (g_str_equal(state, "alerting")) {
-			telephony_update_indicator(ofono_indicators,
-					"callsetup", EV_CALLSETUP_ALERTING);
-			vc->status = CALL_STATUS_ALERTING;
-			vc->originating = TRUE;
-		} else if (g_str_equal(state, "incoming")) {
-			/* state change from waiting to incoming */
-			telephony_update_indicator(ofono_indicators,
-					"callsetup", EV_CALLSETUP_INCOMING);
-			telephony_incoming_call_ind(vc->number,
-						NUMBER_TYPE_TELEPHONY);
-			vc->status = CALL_STATUS_INCOMING;
-			vc->originating = FALSE;
-		} else if (g_str_equal(state, "held")) {
-			vc->status = CALL_STATUS_HELD;
-			if (find_vc_without_status(CALL_STATUS_HELD))
-				telephony_update_indicator(ofono_indicators,
-							"callheld",
-							EV_CALLHELD_MULTIPLE);
-			else
-				telephony_update_indicator(ofono_indicators,
-							"callheld",
-							EV_CALLHELD_ON_HOLD);
-		}
-	} else if (g_str_equal(property, "Multiparty")) {
-		dbus_bool_t multiparty;
-
-		dbus_message_iter_get_basic(&sub, &multiparty);
-		DBG("Multiparty %s", multiparty ? "True" : "False");
-		vc->conference = multiparty;
-	}
-
-	return TRUE;
-}
-
-static struct voice_call *call_new(const char *path, DBusMessageIter *properties)
-{
-	struct voice_call *vc;
-
-	DBG("%s", path);
-
-	vc = g_new0(struct voice_call, 1);
-	vc->obj_path = g_strdup(path);
-	vc->watch = g_dbus_add_signal_watch(connection, NULL, path,
-					OFONO_VC_INTERFACE, "PropertyChanged",
-					handle_vc_property_changed, vc, NULL);
-
-	while (dbus_message_iter_get_arg_type(properties)
-						== DBUS_TYPE_DICT_ENTRY) {
-		DBusMessageIter entry, value;
-		const char *property, *cli, *state;
-		dbus_bool_t multiparty;
-
-		dbus_message_iter_recurse(properties, &entry);
-		dbus_message_iter_get_basic(&entry, &property);
-
-		dbus_message_iter_next(&entry);
-		dbus_message_iter_recurse(&entry, &value);
-
-		if (g_str_equal(property, "LineIdentification")) {
-			dbus_message_iter_get_basic(&value, &cli);
-			DBG("cli %s", cli);
-			vc->number = g_strdup(cli);
-		} else if (g_str_equal(property, "State")) {
-			dbus_message_iter_get_basic(&value, &state);
-			DBG("state %s", state);
-			if (g_str_equal(state, "incoming"))
-				vc->status = CALL_STATUS_INCOMING;
-			else if (g_str_equal(state, "dialing"))
-				vc->status = CALL_STATUS_DIALING;
-			else if (g_str_equal(state, "alerting"))
-				vc->status = CALL_STATUS_ALERTING;
-			else if (g_str_equal(state, "waiting"))
-				vc->status = CALL_STATUS_WAITING;
-			else if (g_str_equal(state, "held"))
-				vc->status = CALL_STATUS_HELD;
-		} else if (g_str_equal(property, "Multiparty")) {
-			dbus_message_iter_get_basic(&value, &multiparty);
-			DBG("Multipary %s", multiparty ? "True" : "False");
-			vc->conference = multiparty;
-		}
-
-		dbus_message_iter_next(properties);
-	}
-
-	switch (vc->status) {
-	case CALL_STATUS_INCOMING:
-		DBG("CALL_STATUS_INCOMING");
-		vc->originating = FALSE;
-		telephony_update_indicator(ofono_indicators, "callsetup",
-					EV_CALLSETUP_INCOMING);
-		telephony_incoming_call_ind(vc->number, NUMBER_TYPE_TELEPHONY);
-		break;
-	case CALL_STATUS_DIALING:
-		DBG("CALL_STATUS_DIALING");
-		vc->originating = TRUE;
-		g_free(last_dialed_number);
-		last_dialed_number = g_strdup(vc->number);
-		telephony_update_indicator(ofono_indicators, "callsetup",
-					EV_CALLSETUP_OUTGOING);
-		break;
-	case CALL_STATUS_ALERTING:
-		DBG("CALL_STATUS_ALERTING");
-		vc->originating = TRUE;
-		g_free(last_dialed_number);
-		last_dialed_number = g_strdup(vc->number);
-		telephony_update_indicator(ofono_indicators, "callsetup",
-					EV_CALLSETUP_ALERTING);
-		break;
-	case CALL_STATUS_WAITING:
-		DBG("CALL_STATUS_WAITING");
-		vc->originating = FALSE;
-		telephony_update_indicator(ofono_indicators, "callsetup",
-					EV_CALLSETUP_INCOMING);
-		telephony_call_waiting_ind(vc->number, NUMBER_TYPE_TELEPHONY);
-		break;
-	}
-
-	return vc;
-}
-
-static void remove_pending(DBusPendingCall *call)
-{
-	pending = g_slist_remove(pending, call);
-	dbus_pending_call_unref(call);
-}
-
-static void call_added(const char *path, DBusMessageIter *properties)
-{
-	struct voice_call *vc;
-
-	DBG("%s", path);
-
-	vc = find_vc(path);
-	if (vc)
-		return;
-
-	vc = call_new(path, properties);
-	calls = g_slist_prepend(calls, vc);
-}
-
-static void get_calls_reply(DBusPendingCall *call, void *user_data)
-{
-	DBusError err;
-	DBusMessage *reply;
-	DBusMessageIter iter, entry;
-
-	DBG("");
-	reply = dbus_pending_call_steal_reply(call);
-
-	dbus_error_init(&err);
-	if (dbus_set_error_from_message(&err, reply)) {
-		error("ofono replied with an error: %s, %s",
-				err.name, err.message);
-		dbus_error_free(&err);
-		goto done;
-	}
-
-	dbus_message_iter_init(reply, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
-		error("Unexpected signature");
-		goto done;
-	}
-
-	dbus_message_iter_recurse(&iter, &entry);
-
-	while (dbus_message_iter_get_arg_type(&entry)
-						== DBUS_TYPE_STRUCT) {
-		const char *path;
-		DBusMessageIter value, properties;
-
-		dbus_message_iter_recurse(&entry, &value);
-		dbus_message_iter_get_basic(&value, &path);
-
-		dbus_message_iter_next(&value);
-		dbus_message_iter_recurse(&value, &properties);
-
-		call_added(path, &properties);
-
-		dbus_message_iter_next(&entry);
-	}
-
-done:
-	dbus_message_unref(reply);
-	remove_pending(call);
-}
-
-static void handle_network_property(const char *property, DBusMessageIter *variant)
-{
-	const char *status, *operator;
-	unsigned int signals_bar;
-
-	if (g_str_equal(property, "Status")) {
-		dbus_message_iter_get_basic(variant, &status);
-		DBG("Status is %s", status);
-		if (g_str_equal(status, "registered")) {
-			net.status = NETWORK_REG_STATUS_HOME;
-			telephony_update_indicator(ofono_indicators,
-						"roam", EV_ROAM_INACTIVE);
-			telephony_update_indicator(ofono_indicators,
-						"service", EV_SERVICE_PRESENT);
-		} else if (g_str_equal(status, "roaming")) {
-			net.status = NETWORK_REG_STATUS_ROAM;
-			telephony_update_indicator(ofono_indicators,
-						"roam", EV_ROAM_ACTIVE);
-			telephony_update_indicator(ofono_indicators,
-						"service", EV_SERVICE_PRESENT);
-		} else {
-			net.status = NETWORK_REG_STATUS_NOSERV;
-			telephony_update_indicator(ofono_indicators,
-						"roam", EV_ROAM_INACTIVE);
-			telephony_update_indicator(ofono_indicators,
-						"service", EV_SERVICE_NONE);
-		}
-	} else if (g_str_equal(property, "Name")) {
-		dbus_message_iter_get_basic(variant, &operator);
-		DBG("Operator is %s", operator);
-		g_free(net.operator_name);
-		net.operator_name = g_strdup(operator);
-	} else if (g_str_equal(property, "SignalStrength")) {
-		dbus_message_iter_get_basic(variant, &signals_bar);
-		DBG("SignalStrength is %d", signals_bar);
-		net.signals_bar = signals_bar;
-		telephony_update_indicator(ofono_indicators, "signal",
-						(signals_bar + 20) / 21);
-	}
-}
-
-static int parse_network_properties(DBusMessageIter *properties)
-{
-	int i;
-
-	/* Reset indicators */
-	for (i = 0; ofono_indicators[i].desc != NULL; i++) {
-		if (g_str_equal(ofono_indicators[i].desc, "battchg"))
-			ofono_indicators[i].val = 5;
-		else
-			ofono_indicators[i].val = 0;
-	}
-
-	while (dbus_message_iter_get_arg_type(properties)
-						== DBUS_TYPE_DICT_ENTRY) {
-		const char *key;
-		DBusMessageIter value, entry;
-
-		dbus_message_iter_recurse(properties, &entry);
-		dbus_message_iter_get_basic(&entry, &key);
-
-		dbus_message_iter_next(&entry);
-		dbus_message_iter_recurse(&entry, &value);
-
-		handle_network_property(key, &value);
-
-		dbus_message_iter_next(properties);
-	}
-
-	return 0;
-}
-
-static void get_properties_reply(DBusPendingCall *call, void *user_data)
-{
-	DBusError err;
-	DBusMessage *reply;
-	DBusMessageIter iter, properties;
-	int ret = 0;
-
-	DBG("");
-	reply = dbus_pending_call_steal_reply(call);
-
-	dbus_error_init(&err);
-	if (dbus_set_error_from_message(&err, reply)) {
-		error("ofono replied with an error: %s, %s",
-				err.name, err.message);
-		dbus_error_free(&err);
-		goto done;
-	}
-
-	dbus_message_iter_init(reply, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
-		error("Unexpected signature");
-		goto done;
-	}
-
-	dbus_message_iter_recurse(&iter, &properties);
-
-	ret = parse_network_properties(&properties);
-	if (ret < 0) {
-		error("Unable to parse %s.GetProperty reply",
-						OFONO_NETWORKREG_INTERFACE);
-		goto done;
-	}
-
-	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
-				OFONO_VCMANAGER_INTERFACE, "GetCalls",
-				get_calls_reply, NULL, DBUS_TYPE_INVALID);
-	if (ret < 0)
-		error("Unable to send %s.GetCalls",
-						OFONO_VCMANAGER_INTERFACE);
-
-done:
-	dbus_message_unref(reply);
-	remove_pending(call);
-}
-
-static void network_found(const char *path)
-{
-	int ret;
-
-	DBG("%s", path);
-
-	modem_obj_path = g_strdup(path);
-
-	ret = send_method_call(OFONO_BUS_NAME, path,
-				OFONO_NETWORKREG_INTERFACE, "GetProperties",
-				get_properties_reply, NULL, DBUS_TYPE_INVALID);
-	if (ret < 0)
-		error("Unable to send %s.GetProperties",
-						OFONO_NETWORKREG_INTERFACE);
-}
-
-static void modem_removed(const char *path)
-{
-	if (g_strcmp0(modem_obj_path, path) != 0)
-		return;
-
-	DBG("%s", path);
-
-	g_slist_free_full(calls, call_free);
-	calls = NULL;
-
-	g_free(net.operator_name);
-	net.operator_name = NULL;
-	net.status = NETWORK_REG_STATUS_NOSERV;
-	net.signals_bar = 0;
-
-	g_free(modem_obj_path);
-	modem_obj_path = NULL;
-}
-
-static void parse_modem_interfaces(const char *path, DBusMessageIter *ifaces)
-{
-	DBG("%s", path);
-
-	while (dbus_message_iter_get_arg_type(ifaces) == DBUS_TYPE_STRING) {
-		const char *iface;
-
-		dbus_message_iter_get_basic(ifaces, &iface);
-
-		if (g_str_equal(iface, OFONO_NETWORKREG_INTERFACE)) {
-			network_found(path);
-			return;
-		}
-
-		dbus_message_iter_next(ifaces);
-	}
-
-	modem_removed(path);
-}
-
-static void modem_added(const char *path, DBusMessageIter *properties)
-{
-	if (modem_obj_path != NULL) {
-		DBG("Ignoring, modem already exist");
-		return;
-	}
-
-	DBG("%s", path);
-
-	while (dbus_message_iter_get_arg_type(properties)
-						== DBUS_TYPE_DICT_ENTRY) {
-		const char *key;
-		DBusMessageIter interfaces, value, entry;
-
-		dbus_message_iter_recurse(properties, &entry);
-		dbus_message_iter_get_basic(&entry, &key);
-
-		dbus_message_iter_next(&entry);
-		dbus_message_iter_recurse(&entry, &value);
-
-		if (strcasecmp(key, "Interfaces") != 0)
-			goto next;
-
-		if (dbus_message_iter_get_arg_type(&value)
-							!= DBUS_TYPE_ARRAY) {
-			error("Invalid Signature");
-			return;
-		}
-
-		dbus_message_iter_recurse(&value, &interfaces);
-
-		parse_modem_interfaces(path, &interfaces);
-
-		if (modem_obj_path != NULL)
-			return;
-
-	next:
-		dbus_message_iter_next(properties);
-	}
-}
-
-static void get_modems_reply(DBusPendingCall *call, void *user_data)
-{
-	DBusError err;
-	DBusMessage *reply;
-	DBusMessageIter iter, entry;
-
-	DBG("");
-	reply = dbus_pending_call_steal_reply(call);
-
-	dbus_error_init(&err);
-	if (dbus_set_error_from_message(&err, reply)) {
-		error("ofono replied with an error: %s, %s",
-				err.name, err.message);
-		dbus_error_free(&err);
-		goto done;
-	}
-
-	/* Skip modem selection if a modem already exist */
-	if (modem_obj_path != NULL)
-		goto done;
-
-	dbus_message_iter_init(reply, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
-		error("Unexpected signature");
-		goto done;
-	}
-
-	dbus_message_iter_recurse(&iter, &entry);
-
-	while (dbus_message_iter_get_arg_type(&entry)
-						== DBUS_TYPE_STRUCT) {
-		const char *path;
-		DBusMessageIter item, properties;
-
-		dbus_message_iter_recurse(&entry, &item);
-		dbus_message_iter_get_basic(&item, &path);
-
-		dbus_message_iter_next(&item);
-		dbus_message_iter_recurse(&item, &properties);
-
-		modem_added(path, &properties);
-		if (modem_obj_path != NULL)
-			break;
-
-		dbus_message_iter_next(&entry);
-	}
-
-done:
-	dbus_message_unref(reply);
-	remove_pending(call);
-}
-
-static gboolean handle_network_property_changed(DBusConnection *conn,
-						DBusMessage *msg, void *data)
-{
-	DBusMessageIter iter, variant;
-	const char *property;
-
-	dbus_message_iter_init(msg, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
-		error("Unexpected signature in networkregistration"
-					" PropertyChanged signal");
-		return TRUE;
-	}
-	dbus_message_iter_get_basic(&iter, &property);
-	DBG("in handle_registration_property_changed(),"
-					" the property is %s", property);
-
-	dbus_message_iter_next(&iter);
-	dbus_message_iter_recurse(&iter, &variant);
-
-	handle_network_property(property, &variant);
-
-	return TRUE;
-}
-
-static void handle_modem_property(const char *path, const char *property,
-						DBusMessageIter *variant)
-{
-	DBG("%s", property);
-
-	if (g_str_equal(property, "Interfaces")) {
-		DBusMessageIter interfaces;
-
-		if (dbus_message_iter_get_arg_type(variant)
-							!= DBUS_TYPE_ARRAY) {
-			error("Invalid signature");
-			return;
-		}
-
-		dbus_message_iter_recurse(variant, &interfaces);
-		parse_modem_interfaces(path, &interfaces);
-	}
-}
-
-static gboolean handle_modem_property_changed(DBusConnection *conn,
-						DBusMessage *msg, void *data)
-{
-	DBusMessageIter iter, variant;
-	const char *property, *path;
-
-	path = dbus_message_get_path(msg);
-
-	/* Ignore if modem already exist and paths doesn't match */
-	if (modem_obj_path != NULL &&
-				g_str_equal(path, modem_obj_path) == FALSE)
-		return TRUE;
-
-	dbus_message_iter_init(msg, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
-		error("Unexpected signature in %s.%s PropertyChanged signal",
-					dbus_message_get_interface(msg),
-					dbus_message_get_member(msg));
-		return TRUE;
-	}
-
-	dbus_message_iter_get_basic(&iter, &property);
-
-	dbus_message_iter_next(&iter);
-	dbus_message_iter_recurse(&iter, &variant);
-
-	handle_modem_property(path, property, &variant);
-
-	return TRUE;
-}
-
-static gboolean handle_vcmanager_call_added(DBusConnection *conn,
-						DBusMessage *msg, void *data)
-{
-	DBusMessageIter iter, properties;
-	const char *path = dbus_message_get_path(msg);
-
-	/* Ignore call if modem path doesn't math */
-	if (g_strcmp0(modem_obj_path, path) != 0)
-		return TRUE;
-
-	dbus_message_iter_init(msg, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter)
-						!= DBUS_TYPE_OBJECT_PATH) {
-		error("Unexpected signature in %s.%s signal",
-					dbus_message_get_interface(msg),
-					dbus_message_get_member(msg));
-		return TRUE;
-	}
-
-	dbus_message_iter_get_basic(&iter, &path);
-	dbus_message_iter_next(&iter);
-	dbus_message_iter_recurse(&iter, &properties);
-
-	call_added(path, &properties);
-
-	return TRUE;
-}
-
-static void call_removed(const char *path)
-{
-	struct voice_call *vc;
-
-	DBG("%s", path);
-
-	vc = find_vc(path);
-	if (vc == NULL)
-		return;
-
-	calls = g_slist_remove(calls, vc);
-	call_free(vc);
-}
-
-static gboolean handle_vcmanager_call_removed(DBusConnection *conn,
-						DBusMessage *msg, void *data)
-{
-	const char *path = dbus_message_get_path(msg);
-
-	/* Ignore call if modem path doesn't math */
-	if (g_strcmp0(modem_obj_path, path) != 0)
-		return TRUE;
-
-	if (!dbus_message_get_args(msg, NULL,
-				DBUS_TYPE_OBJECT_PATH, &path,
-				DBUS_TYPE_INVALID)) {
-		error("Unexpected signature in %s.%s signal",
-					dbus_message_get_interface(msg),
-					dbus_message_get_member(msg));
-		return TRUE;
-	}
-
-	call_removed(path);
-
-	return TRUE;
-}
-
-static gboolean handle_manager_modem_added(DBusConnection *conn,
-						DBusMessage *msg, void *data)
-{
-	DBusMessageIter iter, properties;
-	const char *path;
-
-	if (modem_obj_path != NULL)
-		return TRUE;
-
-	dbus_message_iter_init(msg, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter)
-						!= DBUS_TYPE_OBJECT_PATH) {
-		error("Unexpected signature in %s.%s signal",
-					dbus_message_get_interface(msg),
-					dbus_message_get_member(msg));
-		return TRUE;
-	}
-
-	dbus_message_iter_get_basic(&iter, &path);
-	dbus_message_iter_next(&iter);
-	dbus_message_iter_recurse(&iter, &properties);
-
-	modem_added(path, &properties);
-
-	return TRUE;
-}
-
-static gboolean handle_manager_modem_removed(DBusConnection *conn,
-						DBusMessage *msg, void *data)
-{
-	const char *path;
-
-	if (!dbus_message_get_args(msg, NULL,
-				DBUS_TYPE_OBJECT_PATH, &path,
-				DBUS_TYPE_INVALID)) {
-		error("Unexpected signature in %s.%s signal",
-					dbus_message_get_interface(msg),
-					dbus_message_get_member(msg));
-		return TRUE;
-	}
-
-	modem_removed(path);
-
-	return TRUE;
-}
-
-static void hal_battery_level_reply(DBusPendingCall *call, void *user_data)
-{
-	DBusMessage *reply;
-	DBusError err;
-	dbus_int32_t level;
-	int *value = user_data;
-
-	reply = dbus_pending_call_steal_reply(call);
-
-	dbus_error_init(&err);
-	if (dbus_set_error_from_message(&err, reply)) {
-		error("hald replied with an error: %s, %s",
-				err.name, err.message);
-		dbus_error_free(&err);
-		goto done;
-	}
-
-	dbus_error_init(&err);
-	if (dbus_message_get_args(reply, &err,
-				DBUS_TYPE_INT32, &level,
-				DBUS_TYPE_INVALID) == FALSE) {
-		error("Unable to parse GetPropertyInteger reply: %s, %s",
-							err.name, err.message);
-		dbus_error_free(&err);
-		goto done;
-	}
-
-	*value = (int) level;
-
-	if (value == &battchg_last)
-		DBG("telephony-ofono: battery.charge_level.last_full"
-					" is %d", *value);
-	else if (value == &battchg_design)
-		DBG("telephony-ofono: battery.charge_level.design"
-					" is %d", *value);
-	else
-		DBG("telephony-ofono: battery.charge_level.current"
-					" is %d", *value);
-
-	if ((battchg_design > 0 || battchg_last > 0) && battchg_cur >= 0) {
-		int new, max;
-
-		if (battchg_last > 0)
-			max = battchg_last;
-		else
-			max = battchg_design;
-
-		new = battchg_cur * 5 / max;
-
-		telephony_update_indicator(ofono_indicators, "battchg", new);
-	}
-done:
-	dbus_message_unref(reply);
-	remove_pending(call);
-}
-
-static void hal_get_integer(const char *path, const char *key, void *user_data)
-{
-	send_method_call("org.freedesktop.Hal", path,
-			"org.freedesktop.Hal.Device",
-			"GetPropertyInteger",
-			hal_battery_level_reply, user_data,
-			DBUS_TYPE_STRING, &key,
-			DBUS_TYPE_INVALID);
-}
-
-static gboolean handle_hal_property_modified(DBusConnection *conn,
-						DBusMessage *msg, void *data)
-{
-	const char *path;
-	DBusMessageIter iter, array;
-	dbus_int32_t num_changes;
-
-	path = dbus_message_get_path(msg);
-
-	dbus_message_iter_init(msg, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
-		error("Unexpected signature in hal PropertyModified signal");
-		return TRUE;
-	}
-
-	dbus_message_iter_get_basic(&iter, &num_changes);
-	dbus_message_iter_next(&iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
-		error("Unexpected signature in hal PropertyModified signal");
-		return TRUE;
-	}
-
-	dbus_message_iter_recurse(&iter, &array);
-
-	while (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
-		DBusMessageIter prop;
-		const char *name;
-		dbus_bool_t added, removed;
-
-		dbus_message_iter_recurse(&array, &prop);
-
-		if (!iter_get_basic_args(&prop,
-					DBUS_TYPE_STRING, &name,
-					DBUS_TYPE_BOOLEAN, &added,
-					DBUS_TYPE_BOOLEAN, &removed,
-					DBUS_TYPE_INVALID)) {
-			error("Invalid hal PropertyModified parameters");
-			break;
-		}
-
-		if (g_str_equal(name, "battery.charge_level.last_full"))
-			hal_get_integer(path, name, &battchg_last);
-		else if (g_str_equal(name, "battery.charge_level.current"))
-			hal_get_integer(path, name, &battchg_cur);
-		else if (g_str_equal(name, "battery.charge_level.design"))
-			hal_get_integer(path, name, &battchg_design);
-
-		dbus_message_iter_next(&array);
-	}
-
-	return TRUE;
-}
-
-static void add_watch(const char *sender, const char *path,
-				const char *interface, const char *member,
-				GDBusSignalFunction function)
-{
-	guint watch;
-
-	watch = g_dbus_add_signal_watch(connection, sender, path, interface,
-					member, function, NULL, NULL);
-
-	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
-}
-
-static void hal_find_device_reply(DBusPendingCall *call, void *user_data)
-{
-	DBusMessage *reply;
-	DBusError err;
-	DBusMessageIter iter, sub;
-	int type;
-	const char *path;
-
-	DBG("begin of hal_find_device_reply()");
-	reply = dbus_pending_call_steal_reply(call);
-
-	dbus_error_init(&err);
-
-	if (dbus_set_error_from_message(&err, reply)) {
-		error("hald replied with an error: %s, %s",
-				err.name, err.message);
-		dbus_error_free(&err);
-		goto done;
-	}
-
-	dbus_message_iter_init(reply, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
-		error("Unexpected signature in hal_find_device_reply()");
-		goto done;
-	}
-
-	dbus_message_iter_recurse(&iter, &sub);
-
-	type = dbus_message_iter_get_arg_type(&sub);
-
-	if (type != DBUS_TYPE_OBJECT_PATH && type != DBUS_TYPE_STRING) {
-		error("No hal device with battery capability found");
-		goto done;
-	}
-
-	dbus_message_iter_get_basic(&sub, &path);
-
-	DBG("telephony-ofono: found battery device at %s", path);
-
-	add_watch(NULL, path, "org.freedesktop.Hal.Device",
-			"PropertyModified", handle_hal_property_modified);
-
-	hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
-	hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
-	hal_get_integer(path, "battery.charge_level.design", &battchg_design);
-done:
-	dbus_message_unref(reply);
-	remove_pending(call);
-}
-
-static void handle_service_connect(DBusConnection *conn, void *user_data)
-{
-	DBG("telephony-ofono: %s found", OFONO_BUS_NAME);
-
-	send_method_call(OFONO_BUS_NAME, OFONO_PATH,
-				OFONO_MANAGER_INTERFACE, "GetModems",
-				get_modems_reply, NULL, DBUS_TYPE_INVALID);
-}
-
-static void handle_service_disconnect(DBusConnection *conn, void *user_data)
-{
-	DBG("telephony-ofono: %s exitted", OFONO_BUS_NAME);
-
-	if (modem_obj_path)
-		modem_removed(modem_obj_path);
-}
-
-int telephony_init(void)
-{
-	uint32_t features = AG_FEATURE_EC_ANDOR_NR |
-				AG_FEATURE_INBAND_RINGTONE |
-				AG_FEATURE_REJECT_A_CALL |
-				AG_FEATURE_ENHANCED_CALL_STATUS |
-				AG_FEATURE_ENHANCED_CALL_CONTROL |
-				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES |
-				AG_FEATURE_THREE_WAY_CALLING;
-	const char *battery_cap = "battery";
-	int ret;
-	guint watch;
-
-	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
-
-	add_watch(OFONO_BUS_NAME, NULL, OFONO_MODEM_INTERFACE,
-			"PropertyChanged", handle_modem_property_changed);
-	add_watch(OFONO_BUS_NAME, NULL, OFONO_NETWORKREG_INTERFACE,
-			"PropertyChanged", handle_network_property_changed);
-	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
-			"ModemAdded", handle_manager_modem_added);
-	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
-			"ModemRemoved", handle_manager_modem_removed);
-	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
-			"CallAdded", handle_vcmanager_call_added);
-	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
-			"CallRemoved", handle_vcmanager_call_removed);
-
-	watch = g_dbus_add_service_watch(connection, OFONO_BUS_NAME,
-						handle_service_connect,
-						handle_service_disconnect,
-						NULL, NULL);
-	if (watch == 0)
-		return -ENOMEM;
-
-	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
-
-	ret = send_method_call("org.freedesktop.Hal",
-				"/org/freedesktop/Hal/Manager",
-				"org.freedesktop.Hal.Manager",
-				"FindDeviceByCapability",
-				hal_find_device_reply, NULL,
-				DBUS_TYPE_STRING, &battery_cap,
-				DBUS_TYPE_INVALID);
-	if (ret < 0)
-		return ret;
-
-	DBG("telephony_init() successfully");
-
-	telephony_ready_ind(features, ofono_indicators, BTRH_NOT_SUPPORTED,
-								chld_str);
-
-	return ret;
-}
-
-static void remove_watch(gpointer data)
-{
-	g_dbus_remove_watch(connection, GPOINTER_TO_UINT(data));
-}
-
-static void pending_free(void *data)
-{
-	DBusPendingCall *call = data;
-
-	if (!dbus_pending_call_get_completed(call))
-		dbus_pending_call_cancel(call);
-
-	dbus_pending_call_unref(call);
-}
-
-void telephony_exit(void)
-{
-	DBG("");
-
-	g_free(last_dialed_number);
-	last_dialed_number = NULL;
-
-	if (modem_obj_path)
-		modem_removed(modem_obj_path);
-
-	g_slist_free_full(watches, remove_watch);
-	watches = NULL;
-
-	g_slist_free_full(pending, pending_free);
-	pending = NULL;
-
-	dbus_connection_unref(connection);
-	connection = NULL;
-
-	telephony_deinit();
-}
-- 
1.7.9.5


^ permalink raw reply related


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