Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: Log all parameters in cmd_status for easier debugging
From: Szymon Janc @ 2011-02-28 13:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 net/bluetooth/mgmt.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 34f58f4..e6efaae 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -49,7 +49,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
 	struct mgmt_hdr *hdr;
 	struct mgmt_ev_cmd_status *ev;
 
-	BT_DBG("sock %p", sk);
+	BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status);
 
 	skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
 	if (!skb)
-- 
1.7.0.4
on behalf of ST-Ericsson

^ permalink raw reply related

* [PATCH] Bluetooth: Fix possible NULL pointer dereference in cmd_complete
From: Szymon Janc @ 2011-02-28 13:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc

It is now possible to create command complete event without specific
reply data by passing NULL as reply with len 0. Check pointer before
calling memcpy to avoid undefined behaviour.
---
 net/bluetooth/mgmt.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 46c3edc..34f58f4 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -92,7 +92,9 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp,
 
 	ev = (void *) skb_put(skb, sizeof(*ev) + rp_len);
 	put_unaligned_le16(cmd, &ev->opcode);
-	memcpy(ev->data, rp, rp_len);
+
+	if (rp)
+		memcpy(ev->data, rp, rp_len);
 
 	if (sock_queue_rcv_skb(sk, skb) < 0)
 		kfree_skb(skb);
-- 
1.7.0.4
on behalf of ST-Ericsson

^ permalink raw reply related

* Re: [pulseaudio-discuss] Problems trying to connecf HFP device
From: Daniel Wagner @ 2011-02-28 12:33 UTC (permalink / raw)
  To: Franz Glauber; +Cc: linux-bluetooth
In-Reply-To: <AANLkTi=mgDqXjSBNahtXEWbJ+Cj6K3pbfmAT=TJUjPoo@mail.gmail.com>

Hi Franz,

On Mon, Feb 28, 2011 at 08:05:25AM -0300, Franz Glauber wrote:
> I got a dump with hcitool, the last line was after the delay. I got
> latest 4.89 bluez and kernel 2.6.36-r5. Any ideas?

What is your exact problem? Just the other day, I got HFP (audio
gateway) working on my computer. The main problem was that I had to
tell PulseAudio to loopback the audio stream to the audio
card. Otherwise, PulseAudio would suspend the BT audio streams which
resulted in a SCO disconnect.

HTH,
daniel

^ permalink raw reply

* [PATCH] Adjust prefix of contact id for pulling single vCard
From: Rafal Michalski @ 2011-02-28 12:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Rafal Michalski

Pulling single vCard is related to recognizing it by prefix of contact id.
Previously it was "contact: " and has been changed to "urn:uuid:".
This patch fixes it and allows to pull valid single vCard.
---
 plugins/phonebook-tracker.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 9963aab..b204493 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -73,7 +73,7 @@
 #define COL_SENT 20
 #define COL_ANSWERED 21
 #define CONTACTS_ID_COL 22
-#define CONTACT_ID_PREFIX "contact:"
+#define CONTACT_ID_PREFIX "urn:uuid:"
 
 #define FAX_NUM_TYPE "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#FaxNumber"
 #define MOBILE_NUM_TYPE "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#CellPhoneNumber"
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 2/2] Fix response on adapter RequestSession method
From: Dmitriy Paliy @ 2011-02-28 11:34 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz; +Cc: Dmitriy Paliy
In-Reply-To: <1298892865-14930-1-git-send-email-dmitriy.paliy@nokia.com>

Fixes response on adapter RequestSession method to be sent after mode is
changed. More specifically change of power off mode to power on is in
question.

Currenty, response is sent when mode change is confirmed by agent, not by
response from controller. Such may lead to failed CreateDevice method if
it is called quickly enough after RequestSession when controller is
powered off.
---
 src/adapter.c |   45 ++++++++++++++++++++++++++++++++++++---------
 1 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 49a23ec..5cdb371 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -510,11 +510,19 @@ done:
 
 	DBG("%s", modestr);
 
-	if (msg != NULL)
-		/* Wait for mode change to reply */
-		adapter->pending_mode = create_session(adapter, connection,
-							msg, new_mode, NULL);
-	else
+	if (msg != NULL) {
+		const char *sender = dbus_message_get_sender(msg);
+		struct session_req *req;
+
+		req = find_session(adapter->mode_sessions, sender);
+		if (req) {
+			adapter->pending_mode = req;
+			session_ref(req);
+		} else
+			/* Wait for mode change to reply */
+			adapter->pending_mode = create_session(adapter,
+					connection, msg, new_mode, NULL);
+	} else
 		/* Nothing to reply just write the new mode */
 		adapter->mode = new_mode;
 
@@ -795,17 +803,31 @@ static void confirm_mode_cb(struct agent *agent, DBusError *derr, void *data)
 		return;
 	}
 
-	err = set_mode(req->adapter, req->mode, NULL);
-	if (err < 0)
+	err = set_mode(req->adapter, req->mode, req->msg);
+	if (err < 0) {
 		reply = btd_error_failed(req->msg, strerror(-err));
-	else
+		goto proceed;
+	}
+
+	if (!req->adapter->pending_mode) {
 		reply = dbus_message_new_method_return(req->msg);
+		goto proceed;
+	}
+
+	goto done;
 
+proceed:
+	/*
+	 * Send reply immidiately only if there was an error changing
+	 * mode, or change is not needed. Otherwise, reply is sent in
+	 * set_mode_complete.
+	 */
 	g_dbus_send_message(req->conn, reply);
 
 	dbus_message_unref(req->msg);
 	req->msg = NULL;
 
+done:
 	if (!find_session(req->adapter->mode_sessions, req->owner))
 		session_unref(req);
 }
@@ -2485,7 +2507,12 @@ static void set_mode_complete(struct btd_adapter *adapter)
 			if (strcmp(dbus_message_get_member(msg),
 						"SetProperty") == 0)
 				adapter->global_mode = adapter->mode;
-			reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+			if (strcmp(dbus_message_get_member(msg),
+						"RequestSession") == 0)
+				reply = dbus_message_new_method_return(msg);
+			else
+				reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 		}
 
 		g_dbus_send_message(connection, reply);
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/2] Move find_session in adapter.c
From: Dmitriy Paliy @ 2011-02-28 11:34 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz; +Cc: Dmitriy Paliy
In-Reply-To: <1298892865-14930-1-git-send-email-dmitriy.paliy@nokia.com>

find_session is moved to be before set_mode, to avoid declaration
of prototype. It is used in the subsequent patch.
---
 src/adapter.c |   28 ++++++++++++++--------------
 1 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 2e11832..49a23ec 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -452,6 +452,20 @@ static int adapter_set_mode(struct btd_adapter *adapter, uint8_t mode)
 	return 0;
 }
 
+static struct session_req *find_session(GSList *list, const char *sender)
+{
+	GSList *l;
+
+	for (l = list; l; l = l->next) {
+		struct session_req *req = l->data;
+
+		if (g_str_equal(req->owner, sender))
+			return req;
+	}
+
+	return NULL;
+}
+
 static int set_mode(struct btd_adapter *adapter, uint8_t new_mode,
 			DBusMessage *msg)
 {
@@ -620,20 +634,6 @@ static void adapter_set_pairable_timeout(struct btd_adapter *adapter,
 						adapter);
 }
 
-static struct session_req *find_session(GSList *list, const char *sender)
-{
-	GSList *l;
-
-	for (l = list; l; l = l->next) {
-		struct session_req *req = l->data;
-
-		if (g_str_equal(req->owner, sender))
-			return req;
-	}
-
-	return NULL;
-}
-
 static uint8_t get_needed_mode(struct btd_adapter *adapter, uint8_t mode)
 {
 	GSList *l;
-- 
1.7.1


^ permalink raw reply related

* [PATCH 0/2 v2] Fix response on adapter RequestSession method
From: Dmitriy Paliy @ 2011-02-28 11:34 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz

Hi,

These patches are resent due to wrong enumeration in previous submission.

BR,
Dmitriy


^ permalink raw reply

* [PATCH 2/2] Fix response on adapter RequestSession method
From: Dmitriy Paliy @ 2011-02-28 11:28 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz; +Cc: Dmitriy Paliy
In-Reply-To: <1298892529-14648-1-git-send-email-dmitriy.paliy@nokia.com>

Fixes response on adapter RequestSession method to be sent after mode is
changed. More specifically change of power off mode to power on is in
question.

Currenty, response is sent when mode change is confirmed by agent, not by
response from controller. Such may lead to failed CreateDevice method if
it is called quickly enough after RequestSession when controller is
powered off.
---
 src/adapter.c |   45 ++++++++++++++++++++++++++++++++++++---------
 1 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 49a23ec..5cdb371 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -510,11 +510,19 @@ done:
 
 	DBG("%s", modestr);
 
-	if (msg != NULL)
-		/* Wait for mode change to reply */
-		adapter->pending_mode = create_session(adapter, connection,
-							msg, new_mode, NULL);
-	else
+	if (msg != NULL) {
+		const char *sender = dbus_message_get_sender(msg);
+		struct session_req *req;
+
+		req = find_session(adapter->mode_sessions, sender);
+		if (req) {
+			adapter->pending_mode = req;
+			session_ref(req);
+		} else
+			/* Wait for mode change to reply */
+			adapter->pending_mode = create_session(adapter,
+					connection, msg, new_mode, NULL);
+	} else
 		/* Nothing to reply just write the new mode */
 		adapter->mode = new_mode;
 
@@ -795,17 +803,31 @@ static void confirm_mode_cb(struct agent *agent, DBusError *derr, void *data)
 		return;
 	}
 
-	err = set_mode(req->adapter, req->mode, NULL);
-	if (err < 0)
+	err = set_mode(req->adapter, req->mode, req->msg);
+	if (err < 0) {
 		reply = btd_error_failed(req->msg, strerror(-err));
-	else
+		goto proceed;
+	}
+
+	if (!req->adapter->pending_mode) {
 		reply = dbus_message_new_method_return(req->msg);
+		goto proceed;
+	}
+
+	goto done;
 
+proceed:
+	/*
+	 * Send reply immidiately only if there was an error changing
+	 * mode, or change is not needed. Otherwise, reply is sent in
+	 * set_mode_complete.
+	 */
 	g_dbus_send_message(req->conn, reply);
 
 	dbus_message_unref(req->msg);
 	req->msg = NULL;
 
+done:
 	if (!find_session(req->adapter->mode_sessions, req->owner))
 		session_unref(req);
 }
@@ -2485,7 +2507,12 @@ static void set_mode_complete(struct btd_adapter *adapter)
 			if (strcmp(dbus_message_get_member(msg),
 						"SetProperty") == 0)
 				adapter->global_mode = adapter->mode;
-			reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+			if (strcmp(dbus_message_get_member(msg),
+						"RequestSession") == 0)
+				reply = dbus_message_new_method_return(msg);
+			else
+				reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 		}
 
 		g_dbus_send_message(connection, reply);
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/22] Move find_session in adapter.c
From: Dmitriy Paliy @ 2011-02-28 11:28 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz; +Cc: Dmitriy Paliy

find_session is moved to be before set_mode, to avoid declaration
of prototype. It is used in the subsequent patch.
---
 src/adapter.c |   28 ++++++++++++++--------------
 1 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 2e11832..49a23ec 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -452,6 +452,20 @@ static int adapter_set_mode(struct btd_adapter *adapter, uint8_t mode)
 	return 0;
 }
 
+static struct session_req *find_session(GSList *list, const char *sender)
+{
+	GSList *l;
+
+	for (l = list; l; l = l->next) {
+		struct session_req *req = l->data;
+
+		if (g_str_equal(req->owner, sender))
+			return req;
+	}
+
+	return NULL;
+}
+
 static int set_mode(struct btd_adapter *adapter, uint8_t new_mode,
 			DBusMessage *msg)
 {
@@ -620,20 +634,6 @@ static void adapter_set_pairable_timeout(struct btd_adapter *adapter,
 						adapter);
 }
 
-static struct session_req *find_session(GSList *list, const char *sender)
-{
-	GSList *l;
-
-	for (l = list; l; l = l->next) {
-		struct session_req *req = l->data;
-
-		if (g_str_equal(req->owner, sender))
-			return req;
-	}
-
-	return NULL;
-}
-
 static uint8_t get_needed_mode(struct btd_adapter *adapter, uint8_t mode)
 {
 	GSList *l;
-- 
1.7.1


^ permalink raw reply related

* [pulseaudio-discuss] Problems trying to connecf HFP device
From: Franz Glauber @ 2011-02-28 11:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <AANLkTinMEH4utheRXZPjh0v-+ms8zPvEXDurvxwQBO6S@mail.gmail.com>

I got a dump with hcitool, the last line was after the delay. I got
latest 4.89 bluez and kernel 2.6.36-r5. Any ideas?

< HCI Command: Create Connection (0x01|0x0005) plen 13
> HCI Event: Command Status (0x0f) plen 4
> HCI Event: Link Key Request (0x17) plen 6
< HCI Command: Link Key Request Reply (0x01|0x000b) plen 22
> HCI Event: Command Complete (0x0e) plen 10
> HCI Event: Connect Complete (0x03) plen 11
< HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2
> HCI Event: Connection Packet Type Changed (0x1d) plen 5
> HCI Event: Command Status (0x0f) plen 4
> HCI Event: Read Remote Supported Features (0x0b) plen 11
< ACL data: handle 1 flags 0x02 dlen 10
    L2CAP(s): Info req: type 2
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 12
    L2CAP(s): Info rsp: type 2 result 1
      Not supported
< ACL data: handle 1 flags 0x02 dlen 12
    L2CAP(s): Connect req: psm 1 scid 0x0040
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 0 status 0
      Connection successful
< ACL data: handle 1 flags 0x02 dlen 12
    L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 0
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 14
    L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 0
      Success
> ACL data: handle 1 flags 0x02 dlen 16
    L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 4
      MTU 64
< ACL data: handle 1 flags 0x02 dlen 18
    L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 4
      MTU 64
> HCI Event: Number of Completed Packets (0x13) plen 5
< ACL data: handle 1 flags 0x02 dlen 24
    L2CAP(d): cid 0x0040 len 20 [psm 1]
        SDP SSA Req: tid 0x0 len 0xf
          pat uuid-16 0x111e (Handsfree)
          max 65535
          aid(s) 0x0000 - 0xffff
          cont 00
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 17
> ACL data: handle 1 flags 0x01 dlen 17
> ACL data: handle 1 flags 0x01 dlen 17
> ACL data: handle 1 flags 0x01 dlen 17
> ACL data: handle 1 flags 0x01 dlen 17
> ACL data: handle 1 flags 0x01 dlen 17
> ACL data: handle 1 flags 0x01 dlen 17
> ACL data: handle 1 flags 0x01 dlen 4
    L2CAP(d): cid 0x0040 len 119 [psm 1]
        SDP SSA Rsp: tid 0x0 len 0x72
          count 111
          record #0
              aid 0x0000 (SrvRecHndl)
                 uint 0x10000
              aid 0x0001 (SrvClassIDList)
                 < uuid-16 0x111e (Handsfree) uuid-16 0x1203 (Audio) >
              aid 0x0004 (ProtocolDescList)
                 < < uuid-16 0x0100 (L2CAP) > <
                 uuid-16 0x0003 (RFCOMM) uint 0x1 > >
              aid 0x0005 (BrwGrpList)
                 < uuid-16 0x1002 (PubBrwsGrp) >
              aid 0x0009 (BTProfileDescList)
                 < < uuid-16 0x111e (Handsfree) uint 0x105 > >
              aid 0x0100 (SrvName)
                 str "Hands-Free"
              aid 0x0102 (ProviderName)
                 str "TERAX COMMUNICATION INC."
              aid 0x0311 (SuppFeatures)
                 uint 0x18
          cont 00
< ACL data: handle 1 flags 0x02 dlen 12
    L2CAP(s): Connect req: psm 3 scid 0x0041
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0041 scid 0x0041 result 0 status 0
      Connection successful
< ACL data: handle 1 flags 0x02 dlen 16
    L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 4
      MTU 1013
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 14
    L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 0
      Success
> ACL data: handle 1 flags 0x02 dlen 16
    L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 4
      MTU 261
< ACL data: handle 1 flags 0x02 dlen 18
    L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 4
      MTU 261
< ACL data: handle 1 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): SABM: cr 1 dlci 0 pf 1 ilen 0 fcs 0x1c
> HCI Event: Number of Completed Packets (0x13) plen 5
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): UA: cr 1 dlci 0 pf 1 ilen 0 fcs 0xd7
< HCI Command: Authentication Requested (0x01|0x0011) plen 2
> HCI Event: Command Status (0x0f) plen 4
> HCI Event: Auth Complete (0x06) plen 3
< HCI Command: Set Connection Encryption (0x01|0x0013) plen 3
> HCI Event: Command Status (0x0f) plen 4
> HCI Event: Encrypt Change (0x08) plen 4
< ACL data: handle 1 flags 0x02 dlen 18
    L2CAP(d): cid 0x0041 len 14 [psm 3]
      RFCOMM(s): PN CMD: cr 1 dlci 0 pf 0 ilen 10 fcs 0x70 mcc_len 8
      dlci 2 frame_type 0 credit_flow 15 pri 7 ack_timer 0
      frame_size 256 max_retrans 0 credits 7
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 17
> ACL data: handle 1 flags 0x01 dlen 1
    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 2 frame_type 0 credit_flow 14 pri 7 ack_timer 0
      frame_size 256 max_retrans 0 credits 2
< ACL data: handle 1 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): SABM: cr 1 dlci 2 pf 1 ilen 0 fcs 0x59
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): UA: cr 1 dlci 2 pf 1 ilen 0 fcs 0x92
< ACL data: handle 1 flags 0x02 dlen 12
    L2CAP(d): cid 0x0041 len 8 [psm 3]
      RFCOMM(s): MSC CMD: cr 1 dlci 0 pf 0 ilen 4 fcs 0x70 mcc_len 2
      dlci 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 b1 1 b2 0 b3 0 len 0
> ACL data: handle 1 flags 0x02 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 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 b1 1 b2 0 b3 0 len 0
< ACL data: handle 1 flags 0x02 dlen 12
    L2CAP(d): cid 0x0041 len 8 [psm 3]
      RFCOMM(s): MSC RSP: cr 1 dlci 0 pf 0 ilen 4 fcs 0x70 mcc_len 2
      dlci 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 b1 1 b2 0 b3 0 len 0
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 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 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 b1 1 b2 0 b3 0 len 0
< ACL data: handle 1 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 1 ilen 0 fcs 0x86 credits 33
> HCI Event: Number of Completed Packets (0x13) plen 5
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 17
> ACL data: handle 1 flags 0x01 dlen 2
    L2CAP(d): cid 0x0041 len 15 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 0 ilen 11 fcs 0x40
< ACL data: handle 1 flags 0x02 dlen 22
    L2CAP(d): cid 0x0041 len 18 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 0 ilen 14 fcs 0x9a
< ACL data: handle 1 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 0 ilen 6 fcs 0x9a
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 0 fcs 0x5c credits 1
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 0 fcs 0x5c credits 1
> ACL data: handle 1 flags 0x02 dlen 17
> ACL data: handle 1 flags 0x01 dlen 1
    L2CAP(d): cid 0x0041 len 14 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 0 ilen 10 fcs 0x40
< ACL data: handle 1 flags 0x02 dlen 141
    L2CAP(d): cid 0x0041 len 137 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 0 ilen 132 fcs 0x9a
< ACL data: handle 1 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 0 ilen 6 fcs 0x9a
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 0 fcs 0x5c credits 1
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 0 fcs 0x5c credits 1
> ACL data: handle 1 flags 0x02 dlen 17
    L2CAP(d): cid 0x0041 len 13 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 0 ilen 9 fcs 0x40
< ACL data: handle 1 flags 0x02 dlen 32
    L2CAP(d): cid 0x0041 len 28 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 0 ilen 24 fcs 0x9a
< ACL data: handle 1 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 0 ilen 6 fcs 0x9a
> HCI Event: Number of Completed Packets (0x13) plen 5
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 0 fcs 0x5c credits 1
> ACL data: handle 1 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 0 fcs 0x5c credits 1
> ACL data: handle 1 flags 0x02 dlen 17
> ACL data: handle 1 flags 0x01 dlen 7
    L2CAP(d): cid 0x0041 len 20 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 0 ilen 16 fcs 0x40
< ACL data: handle 1 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 0 ilen 6 fcs 0x9a
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 0 fcs 0x5c credits 1
> ACL data: handle 1 flags 0x02 dlen 17
> ACL data: handle 1 flags 0x01 dlen 1
    L2CAP(d): cid 0x0041 len 14 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 0 ilen 10 fcs 0x40
< ACL data: handle 1 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 0 ilen 6 fcs 0x9a
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 0 fcs 0x5c credits 1
< HCI Command: Add SCO Connection (0x01|0x0007) plen 4
< ACL data: handle 1 flags 0x02 dlen 12
    L2CAP(s): Disconn req: dcid 0x0040 scid 0x0040
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 1 flags 0x02 dlen 12
    L2CAP(s): Disconn rsp: dcid 0x0040 scid 0x0040

> HCI Event: Mode Change (0x14) plen 6

--
Franz

http://ciudaddelpico.com




--
Franz

http://ciudaddelpico.com

^ permalink raw reply

* Re: [PATCH] work around for l2cap NULL dereference in l2cap_conn_start
From: David Fries @ 2011-02-28  5:03 UTC (permalink / raw)
  To: Liang Bao, Andrei Warkentin, linux-bluetooth, linux-kernel,
	Feng Tang
In-Reply-To: <20110227191545.GB2166@joana>

On Sun, Feb 27, 2011 at 04:15:45PM -0300, Gustavo F. Padovan wrote:
> I pushed the following patch to bluetooth-2.6 tree. It should fix the problem
> by avoiding connections to be accepted before a L2CAP info response comes:

Is
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git
the bluetooth-2.6 tree you mentioned?  I don't see your patch there.
As a side note, the inline patch in your e-mail has the tabs replaced by
spaces, once I changed them, it applied cleanly.

I first reverted to the base N900 kernel-power-2.6.28 46 (none of my
changes or debugging), it crashed as expected.  I then applied your
patch 743400e0, and it still crashed.  I added back the
l2cap_conn_start parent check and some debugging in af_bluetooth.c
dmesg debug output and patches follow.

I haven't at all looked into the bluetooth protocol, but what connect
sequence difference does it make if I power on the bluetooth headset
and press play on the headset before it automatically pairs with the
N900, vs power on bluetooth headset, wait for it to pair then press
play?  I ask this partly because I'm curiouse, but mostly how I
trigger the bug.  This is with pulse audio running, but no
applications playing audio or responding to a play event from the
headset.

[  443.424560] bt_accept_dequeue, parent cd54ba00 newsock c81f0180, defer_setup && BT_CONNECT2
[  443.427368] avoided crash in l2cap_conn_start sk c6d3f600 result 1 status 2
[  443.518463] bt_accept_dequeue, parent cdee9c00 newsock c81f0000, BT_CONNECTED
[  443.729736] bt_accept_dequeue, parent cd54be00 newsock c81f0000, BT_CONNECTED
[  443.813537] bt_accept_dequeue, parent cd54b600 newsock c81f0180, defer_setup && BT_CONNECT2

>From 5bc80fafac43b6698e271f1246cb24e596bf2ef1 Mon Sep 17 00:00:00 2001
From: David Fries <david@fries.net>
Date: Sun, 6 Feb 2011 14:34:49 -0600
Subject: [PATCH 1/2] work around for l2cap NULL dereference in l2cap_conn_start print sk

---
 net/bluetooth/l2cap.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index fda7741..ff05f51 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -400,7 +400,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
 					struct sock *parent = bt_sk(sk)->parent;
 					rsp.result = cpu_to_le16(L2CAP_CR_PEND);
 					rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
-					parent->sk_data_ready(parent, 0);
+					if(!parent) {
+						printk(KERN_DEBUG "avoided "
+							"crash in %s sk %p "
+							"result %d status %d\n",
+							__func__, sk,
+							rsp.result, rsp.status);
+					} else {
+						parent->sk_data_ready(parent,
+							0);
+					}
 
 				} else {
 					sk->sk_state = BT_CONFIG;
-- 
1.7.2.3


>From 42b9a6ef68a1cd0ef025b826afcfb0ef23342fe5 Mon Sep 17 00:00:00 2001
From: David Fries <david@fries.net>
Date: Sun, 27 Feb 2011 21:50:14 -0600
Subject: [PATCH 2/2] af_bluetooth.c debug

---
 net/bluetooth/af_bluetooth.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 8e910f1..57cd360 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -211,6 +211,18 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
 			continue;
 		}
 
+		if (bt_sk(parent)->defer_setup && sk->sk_state == BT_CONNECT2)
+			printk("%s, parent %p newsock %p, "
+				"defer_setup && BT_CONNECT2\n", __func__,
+				parent, newsock);
+		if (sk->sk_state == BT_CONNECTED)
+			printk("%s, parent %p newsock %p, "
+				"BT_CONNECTED\n", __func__,
+				parent, newsock);
+		if (!newsock)
+			printk("%s, parent %p newsock %p, "
+				"!newsock\n", __func__,
+				parent, newsock);
 		if ((bt_sk(parent)->defer_setup && sk->sk_state == BT_CONNECT2)
 				|| sk->sk_state == BT_CONNECTED || !newsock) {
 			bt_accept_unlink(sk);
-- 
1.7.2.3

 
> commit 743400e01a33779f93b79c84a1b0d1a2d27338c8
> Author: Gustavo F. Padovan <padovan@profusion.mobi>
> Date:   Sun Feb 27 16:05:07 2011 -0300
> 
>     Bluetooth: Don't accept l2cap connection before info_rsp
>     
>     When using defer_setup accepting a connection before receive the L2CAP
>     Info Response for the connection lead us to a crash in l2cap_conn_start(.
>     
>     Reported-by: David Fries <david@fries.net>
>     Reported-by: Liang Bao <tim.bao@gmail.com>
>     Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
> 
> diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
> index c4cf3f5..a8ca42b 100644
> --- a/net/bluetooth/af_bluetooth.c
> +++ b/net/bluetooth/af_bluetooth.c
> @@ -211,8 +211,8 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
>                         continue;
>                 }
>  
> -               if (sk->sk_state == BT_CONNECTED || !newsock ||
> -                                               bt_sk(parent)->defer_setup) {
> +               if ((bt_sk(parent)->defer_setup && sk->sk_state == BT_CONNECT2)
> +                               || sk->sk_state == BT_CONNECTED || !newsock) {
>                         bt_accept_unlink(sk);
>                         if (newsock)
>                                 sock_graft(sk, newsock);
> 
> 
> -- 
> Gustavo F. Padovan
> http://profusion.mobi
> --
> 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

-- 
David Fries <david@fries.net>
http://fries.net/~david/ (PGP encryption key available)

^ permalink raw reply related

* [PATCH v1] Fix HCI LE advertising report dump
From: Andre Dieb Martins @ 2011-02-28  3:58 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Dieb Martins

LE advertising report event has only one data block for each report. Thus, we
can't reuse ext_inquiry_response_dump(), which loops over successive data blocks
until reaches a zero-length one.

This commit introduces ext_inquiry_data_dump(), which dumps a frame containing
data formatted according to [Vol 3] Part C, Section 8. This function is reused
by ext_inquiry_response_dump().

Also adds RSSI parsing to each advertising report.
---
 parser/hci.c |  146 +++++++++++++++++++++++++++++++++------------------------
 1 files changed, 84 insertions(+), 62 deletions(-)

diff --git a/parser/hci.c b/parser/hci.c
index 183fa66..e4a3633 100644
--- a/parser/hci.c
+++ b/parser/hci.c
@@ -757,67 +757,83 @@ static char *filterpolicy2str(uint8_t policy)
 	}
 }
 
-static inline void ext_inquiry_response_dump(int level, struct frame *frm)
+static inline void ext_inquiry_data_dump(int level, struct frame *frm,
+						uint8_t *data)
 {
-	void *ptr = frm->ptr;
-	uint32_t len = frm->len;
-	uint8_t type, length;
+	uint8_t len = data[0];
+	uint8_t type;
 	char *str;
 	int i;
 
-	length = get_u8(frm);
+	if (len == 0)
+		return;
 
-	while (length > 0) {
-		type = get_u8(frm);
-		length--;
+	type = data[1];
+	data += 2;
+	len -= 1;
 
-		switch (type) {
-		case 0x01:
-			p_indent(level, frm);
-			printf("Flags:");
-			for (i = 0; i < length; i++)
-				printf(" 0x%2.2x", *((uint8_t *) (frm->ptr + i)));
-			printf("\n");
-			break;
+	switch (type) {
+	case 0x01:
+		p_indent(level, frm);
+		printf("Flags:");
+		for (i = 0; i < len; i++)
+			printf(" 0x%2.2x", data[i]);
+		printf("\n");
+		break;
 
-		case 0x02:
-		case 0x03:
-			p_indent(level, frm);
-			printf("%s service classes:",
-					type == 0x02 ? "Shortened" : "Complete");
-			for (i = 0; i < length / 2; i++) {
-				uint16_t val = btohs(bt_get_unaligned((uint16_t *) (frm->ptr + (i * 2))));
-				printf(" 0x%4.4x", val);
-			}
-			printf("\n");
-			break;
+	case 0x02:
+	case 0x03:
+		p_indent(level, frm);
+		printf("%s service classes:",
+				type == 0x02 ? "Shortened" : "Complete");
 
-		case 0x08:
-		case 0x09:
-			str = malloc(length + 1);
-			if (str) {
-				snprintf(str, length + 1, "%s", (char *) frm->ptr);
-				for (i = 0; i < length; i++)
-					if (!isprint(str[i]))
-						str[i] = '.';
-				p_indent(level, frm);
-				printf("%s local name: \'%s\'\n",
-					type == 0x08 ? "Shortened" : "Complete", str);
-				free(str);
-			}
-			break;
+		for (i = 0; i < len / 2; i++) {
+			uint16_t val;
 
-		case 0x0a:
-			p_indent(level, frm);
-			printf("TX power level: %d\n", *((uint8_t *) frm->ptr));
-			break;
+			val = btohs(bt_get_unaligned(((uint16_t *) (data + i * 2))));
+			printf(" 0x%4.4x", val);
+		}
+		printf("\n");
+		break;
 
-		default:
+	case 0x08:
+	case 0x09:
+		str = malloc(len + 1);
+		if (str) {
+			snprintf(str, len + 1, "%s", (char *) data);
+			for (i = 0; i < len; i++)
+				if (!isprint(str[i]))
+					str[i] = '.';
 			p_indent(level, frm);
-			printf("Unknown type 0x%02x with %d bytes data\n",
-								type, length);
-			break;
+			printf("%s local name: \'%s\'\n",
+				type == 0x08 ? "Shortened" : "Complete", str);
+			free(str);
 		}
+		break;
+
+	case 0x0a:
+		p_indent(level, frm);
+		printf("TX power level: %d\n", *((uint8_t *) data));
+		break;
+
+	default:
+		p_indent(level, frm);
+		printf("Unknown type 0x%02x with %d bytes data\n",
+							type, len);
+		break;
+	}
+}
+
+static inline void ext_inquiry_response_dump(int level, struct frame *frm)
+{
+	void *ptr = frm->ptr;
+	uint32_t len = frm->len;
+	uint8_t length;
+
+	length = get_u8(frm);
+
+	while (length > 0) {
+		ext_inquiry_data_dump(level, frm, frm->ptr);
 
 		frm->ptr += length;
 		frm->len -= length;
@@ -825,8 +841,10 @@ static inline void ext_inquiry_response_dump(int level, struct frame *frm)
 		length = get_u8(frm);
 	}
 
-	frm->ptr = ptr + (EXTENDED_INQUIRY_INFO_SIZE - INQUIRY_INFO_WITH_RSSI_SIZE);
-	frm->len = len + (EXTENDED_INQUIRY_INFO_SIZE - INQUIRY_INFO_WITH_RSSI_SIZE);
+	frm->ptr = ptr +
+		(EXTENDED_INQUIRY_INFO_SIZE - INQUIRY_INFO_WITH_RSSI_SIZE);
+	frm->len = len +
+		(EXTENDED_INQUIRY_INFO_SIZE - INQUIRY_INFO_WITH_RSSI_SIZE);
 }
 
 static inline void bdaddr_command_dump(int level, struct frame *frm)
@@ -3504,14 +3522,12 @@ static inline void evt_le_conn_complete_dump(int level, struct frame *frm)
 
 static inline void evt_le_advertising_report_dump(int level, struct frame *frm)
 {
-	uint8_t num = get_u8(frm);
-	char addr[18];
-	int i;
+	uint8_t num_reports = get_u8(frm);
+	const uint8_t RSSI_SIZE = 1;
 
-	for (i = 0; i < num; i++) {
+	while (num_reports--) {
+		char addr[18];
 		le_advertising_info *info = frm->ptr;
-		void *ptr = frm->ptr;
-		uint32_t len = frm->len;
 
 		p_ba2str(&info->bdaddr, addr);
 
@@ -3522,13 +3538,19 @@ static inline void evt_le_advertising_report_dump(int level, struct frame *frm)
 		printf("bdaddr %s (%s)\n", addr,
 					bdaddrtype2str(info->bdaddr_type));
 
-		frm->ptr += LE_ADVERTISING_INFO_SIZE;
-		frm->len -= LE_ADVERTISING_INFO_SIZE;
+		if (info->length > 0) {
+			ext_inquiry_data_dump(level, frm,
+					((uint8_t *) &info->length) + 1);
+		}
 
-		ext_inquiry_response_dump(level, frm);
+		frm->ptr += LE_ADVERTISING_INFO_SIZE + info->length;
+		frm->len -= LE_ADVERTISING_INFO_SIZE + info->length;
+
+		p_indent(level, frm);
+		printf("RSSI: %d\n", ((int8_t *) frm->ptr)[frm->len - 1]);
 
-		frm->ptr = ptr + 1;
-		frm->len = len - 1;
+		frm->ptr += RSSI_SIZE;
+		frm->len -= RSSI_SIZE;
 	}
 }
 
-- 
1.7.1


^ permalink raw reply related

* Re: [bluetooth-next 04/15] Bluetooth: Add support for using the crypto subsystem
From: Vinicius Gomes @ 2011-02-28  0:49 UTC (permalink / raw)
  To: Vinicius Costa Gomes, linux-bluetooth, Anderson Briglia
  Cc: Gustavo F. Padovan
In-Reply-To: <20110227202041.GG2166@joana>

Hi Gustavo,

On Sun, Feb 27, 2011 at 5:20 PM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> Hi Vinicius,
>
> * Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2011-02-21 14:23:51 -0300]:
>
>> This will allow using the crypto subsystem for encrypting data. As SMP
>> (Security Manager Protocol) is implemented almost entirely on the host
>> side and the crypto module already implements the needed methods
>> (AES-128), it makes sense to use it.
>>
>> This patch also adds a new Kconfig option to toggle the SMP support.
>>
>> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
>> Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
>> ---
>>  include/net/bluetooth/hci_core.h |    2 ++
>>  net/bluetooth/Kconfig            |    6 ++++++
>>  net/bluetooth/hci_core.c         |   22 ++++++++++++++++++++++
>>  net/bluetooth/smp.c              |   17 +++++++++++++++--
>>  4 files changed, 45 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
>> index d5d8454..e8dbde8 100644
>> --- a/include/net/bluetooth/hci_core.h
>> +++ b/include/net/bluetooth/hci_core.h
>> @@ -161,6 +161,8 @@ struct hci_dev {
>>
>>       __u16                   init_last_cmd;
>>
>> +     struct crypto_blkcipher *tfm;
>> +
>>       struct inquiry_cache    inq_cache;
>>       struct hci_conn_hash    conn_hash;
>>       struct list_head        blacklist;
>> diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
>> index c6f9c2f..e9f40af 100644
>> --- a/net/bluetooth/Kconfig
>> +++ b/net/bluetooth/Kconfig
>> @@ -22,6 +22,7 @@ menuconfig BT
>>            BNEP Module (Bluetooth Network Encapsulation Protocol)
>>            CMTP Module (CAPI Message Transport Protocol)
>>            HIDP Module (Human Interface Device Protocol)
>> +          SMP Module (Security Manager Protocol)
>>
>>         Say Y here to compile Bluetooth support into the kernel or say M to
>>         compile it as module (bluetooth).
>> @@ -35,11 +36,16 @@ config BT_L2CAP
>>       bool "L2CAP protocol support"
>>       depends on BT
>>       select CRC16
>> +     select CRYPTO_BLKCIPHER
>> +     select CRYPTO_AES
>>       help
>>         L2CAP (Logical Link Control and Adaptation Protocol) provides
>>         connection oriented and connection-less data transport.  L2CAP
>>         support is required for most Bluetooth applications.
>>
>> +       Also included is support for SMP (Security Manager Protocol) which
>> +       is the security layer on top of LE (Low Energy) links.
>> +
>>  config BT_SCO
>>       bool "SCO links support"
>>       depends on BT
>> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
>> index b372fb8..ff67843 100644
>> --- a/net/bluetooth/hci_core.c
>> +++ b/net/bluetooth/hci_core.c
>> @@ -42,6 +42,7 @@
>>  #include <linux/notifier.h>
>>  #include <linux/rfkill.h>
>>  #include <linux/timer.h>
>> +#include <linux/crypto.h>
>>  #include <net/sock.h>
>>
>>  #include <asm/system.h>
>> @@ -60,6 +61,8 @@ static void hci_notify(struct hci_dev *hdev, int event);
>>
>>  static DEFINE_RWLOCK(hci_task_lock);
>>
>> +static int enable_smp;
>> +
>>  /* HCI device list */
>>  LIST_HEAD(hci_dev_list);
>>  DEFINE_RWLOCK(hci_dev_list_lock);
>> @@ -1077,6 +1080,14 @@ static void hci_cmd_timer(unsigned long arg)
>>       tasklet_schedule(&hdev->cmd_task);
>>  }
>>
>> +static struct crypto_blkcipher *alloc_cypher(void)
>> +{
>> +     if (enable_smp)
>> +             return crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
>> +
>> +     return ERR_PTR(-ENOTSUPP);
>> +}
>> +
>>  /* Register HCI device */
>>  int hci_register_dev(struct hci_dev *hdev)
>>  {
>> @@ -1155,6 +1166,11 @@ int hci_register_dev(struct hci_dev *hdev)
>>       if (!hdev->workqueue)
>>               goto nomem;
>>
>> +     hdev->tfm = alloc_cypher();
>> +     if (IS_ERR(hdev->tfm))
>> +             BT_INFO("Failed to load transform for ecb(aes): %ld",
>> +                                                     PTR_ERR(hdev->tfm));
>> +
>>       hci_register_sysfs(hdev);
>>
>>       hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
>> @@ -1203,6 +1219,9 @@ int hci_unregister_dev(struct hci_dev *hdev)
>>                                       !test_bit(HCI_SETUP, &hdev->flags))
>>               mgmt_index_removed(hdev->id);
>>
>> +     if (!IS_ERR(hdev->tfm))
>> +             crypto_free_blkcipher(hdev->tfm);
>> +
>>       hci_notify(hdev, HCI_DEV_UNREG);
>>
>>       if (hdev->rfkill) {
>> @@ -2037,3 +2056,6 @@ static void hci_cmd_task(unsigned long arg)
>>               }
>>       }
>>  }
>> +
>> +module_param(enable_smp, bool, 0644);
>> +MODULE_PARM_DESC(enable_smp, "Enable SMP support (LE only)");
>
> This all should be obviously inside smp.c

I have a couple of points against it:

1. it's only used for one purpose, it says whether to try or not to
allocate the block cypher, which is done during the adapter
registration;

2. If the current way is ok, it would mean that I would need to export
another method from smp.c, that was something that I tried to
minimize;

3. and my weakest argument, seems that there are other similar uses,
for example enable_mgmt.

But if you think the code will be clearer moving that to smp.c, will
be glad to change.

>
> Regards,
>
> --
> Gustavo F. Padovan
> http://profusion.mobi
>


Cheers,
-- 
Vinicius

^ permalink raw reply

* Re: [bluetooth-next 04/15] Bluetooth: Add support for using the crypto subsystem
From: Gustavo F. Padovan @ 2011-02-27 20:20 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth, Anderson Briglia
In-Reply-To: <02fa778ab4292dffba1330e829b0d4029517a21e.1298307667.git.vinicius.gomes@openbossa.org>

Hi Vinicius,

* Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2011-02-21 14:23:51 -0300]:

> This will allow using the crypto subsystem for encrypting data. As SMP
> (Security Manager Protocol) is implemented almost entirely on the host
> side and the crypto module already implements the needed methods
> (AES-128), it makes sense to use it.
> 
> This patch also adds a new Kconfig option to toggle the SMP support.
> 
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
> ---
>  include/net/bluetooth/hci_core.h |    2 ++
>  net/bluetooth/Kconfig            |    6 ++++++
>  net/bluetooth/hci_core.c         |   22 ++++++++++++++++++++++
>  net/bluetooth/smp.c              |   17 +++++++++++++++--
>  4 files changed, 45 insertions(+), 2 deletions(-)
> 
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index d5d8454..e8dbde8 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -161,6 +161,8 @@ struct hci_dev {
>  
>  	__u16			init_last_cmd;
>  
> +	struct crypto_blkcipher	*tfm;
> +
>  	struct inquiry_cache	inq_cache;
>  	struct hci_conn_hash	conn_hash;
>  	struct list_head	blacklist;
> diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
> index c6f9c2f..e9f40af 100644
> --- a/net/bluetooth/Kconfig
> +++ b/net/bluetooth/Kconfig
> @@ -22,6 +22,7 @@ menuconfig BT
>  	     BNEP Module (Bluetooth Network Encapsulation Protocol)
>  	     CMTP Module (CAPI Message Transport Protocol)
>  	     HIDP Module (Human Interface Device Protocol)
> +	     SMP Module (Security Manager Protocol)
>  
>  	  Say Y here to compile Bluetooth support into the kernel or say M to
>  	  compile it as module (bluetooth).
> @@ -35,11 +36,16 @@ config BT_L2CAP
>  	bool "L2CAP protocol support"
>  	depends on BT
>  	select CRC16
> +	select CRYPTO_BLKCIPHER
> +	select CRYPTO_AES
>  	help
>  	  L2CAP (Logical Link Control and Adaptation Protocol) provides
>  	  connection oriented and connection-less data transport.  L2CAP
>  	  support is required for most Bluetooth applications.
>  
> +	  Also included is support for SMP (Security Manager Protocol) which
> +	  is the security layer on top of LE (Low Energy) links.
> +
>  config BT_SCO
>  	bool "SCO links support"
>  	depends on BT
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index b372fb8..ff67843 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -42,6 +42,7 @@
>  #include <linux/notifier.h>
>  #include <linux/rfkill.h>
>  #include <linux/timer.h>
> +#include <linux/crypto.h>
>  #include <net/sock.h>
>  
>  #include <asm/system.h>
> @@ -60,6 +61,8 @@ static void hci_notify(struct hci_dev *hdev, int event);
>  
>  static DEFINE_RWLOCK(hci_task_lock);
>  
> +static int enable_smp;
> +
>  /* HCI device list */
>  LIST_HEAD(hci_dev_list);
>  DEFINE_RWLOCK(hci_dev_list_lock);
> @@ -1077,6 +1080,14 @@ static void hci_cmd_timer(unsigned long arg)
>  	tasklet_schedule(&hdev->cmd_task);
>  }
>  
> +static struct crypto_blkcipher *alloc_cypher(void)
> +{
> +	if (enable_smp)
> +		return crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
> +
> +	return ERR_PTR(-ENOTSUPP);
> +}
> +
>  /* Register HCI device */
>  int hci_register_dev(struct hci_dev *hdev)
>  {
> @@ -1155,6 +1166,11 @@ int hci_register_dev(struct hci_dev *hdev)
>  	if (!hdev->workqueue)
>  		goto nomem;
>  
> +	hdev->tfm = alloc_cypher();
> +	if (IS_ERR(hdev->tfm))
> +		BT_INFO("Failed to load transform for ecb(aes): %ld",
> +							PTR_ERR(hdev->tfm));
> +
>  	hci_register_sysfs(hdev);
>  
>  	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
> @@ -1203,6 +1219,9 @@ int hci_unregister_dev(struct hci_dev *hdev)
>  					!test_bit(HCI_SETUP, &hdev->flags))
>  		mgmt_index_removed(hdev->id);
>  
> +	if (!IS_ERR(hdev->tfm))
> +		crypto_free_blkcipher(hdev->tfm);
> +
>  	hci_notify(hdev, HCI_DEV_UNREG);
>  
>  	if (hdev->rfkill) {
> @@ -2037,3 +2056,6 @@ static void hci_cmd_task(unsigned long arg)
>  		}
>  	}
>  }
> +
> +module_param(enable_smp, bool, 0644);
> +MODULE_PARM_DESC(enable_smp, "Enable SMP support (LE only)");

This all should be obviously inside smp.c

Regards,

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH] Bluetooth: l2cap: fix a NULL pointer oops in l2cap_conn_start
From: Gustavo F. Padovan @ 2011-02-27 20:13 UTC (permalink / raw)
  To: Feng Tang; +Cc: marcel, linux-bluetooth
In-Reply-To: <1298361804-11733-1-git-send-email-feng.tang@intel.com>

Hi Feng,

* Feng Tang <feng.tang@intel.com> [2011-02-22 16:03:24 +0800]:

> When I try to setup a PAND connection between the sever and client,
> the server side always get a NULL pointer oops in l2cap_conn_start()
> right after the client run "pand -r PANU -c sever_addr". Don't have
> the boot log as it's an immediate hang.
> 
> Simply adding this "if (parent)" check will fix it, don't know whether
> it fix the real problem. Anyway, send it as a hint.

I pushed a proper fix for this issues, see the bluetooth-2.6 tree.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH v2] Bluetooth: Use ERR_PTR as return error from hci_connect
From: Gustavo F. Padovan @ 2011-02-27 20:12 UTC (permalink / raw)
  To: anderson.briglia; +Cc: linux-bluetooth, Ville Tervo
In-Reply-To: <4d640a47.a21fec0a.065e.466f@mx.google.com>

Hi Briglia,

* anderson.briglia@openbossa.org <anderson.briglia@openbossa.org> [2011-02-22 16:10:53 -0300]:

> From: Ville Tervo <ville.tervo@nokia.com>
> 
> Use ERR_PTR mechanism to return error from hci_connect.
> 
> Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
> Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
> ---
>  net/bluetooth/hci_conn.c   |    4 ++--
>  net/bluetooth/l2cap_core.c |   10 ++++------
>  net/bluetooth/mgmt.c       |    4 ++--
>  net/bluetooth/sco.c        |    6 +++---
>  4 files changed, 11 insertions(+), 13 deletions(-)

Patch is applied now, but I had to fix it, your error handling was still
wrong. Here are the changes I did to your patch:

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 0bbb6c6..c9f9cec 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -841,7 +841,7 @@ int l2cap_do_connect(struct sock *sk)
        struct hci_conn *hcon;
        struct hci_dev *hdev;
        __u8 auth_type;
-       int err = 0;
+       int err;
 
        BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
                                                        l2cap_pi(sk)->psm);
@@ -869,6 +869,7 @@ int l2cap_do_connect(struct sock *sk)
        conn = l2cap_conn_add(hcon, 0);
        if (!conn) {
                hci_conn_put(hcon);
+               err = -ENOMEM;
                goto done;
        }
 
@@ -890,6 +891,8 @@ int l2cap_do_connect(struct sock *sk)
                        l2cap_do_start(sk);
        }
 
+       err = 0;
+
 done:
        hci_dev_unlock_bh(hdev);
        hci_dev_put(hdev);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 26f2f04..42fdffd 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -204,6 +204,7 @@ static int sco_connect(struct sock *sk)
        conn = sco_conn_add(hcon, 0);
        if (!conn) {
                hci_conn_put(hcon);
+               err = -ENOMEM;
                goto done;
        }
 
-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply related

* Re: [PATCH v3 3/3] Bluetooth: Validate data size before accessing mgmt commands
From: Gustavo F. Padovan @ 2011-02-27 19:58 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung
In-Reply-To: <1298657149-3091-3-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

* Szymon Janc <szymon.janc@tieto.com> [2011-02-25 19:05:49 +0100]:

> Crafted (too small) data buffer could result in reading data outside of buffer.
> Validate buffer size and return EINVAL if size is wrong.
> 
> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
>  net/bluetooth/mgmt.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 52 insertions(+), 0 deletions(-)

All 3 patches are applied now, thanks.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* RFCOMM not starting automatically
From: W.P. @ 2011-02-27 19:35 UTC (permalink / raw)
  To: linux-bluetooth

Hi,
my problem is: RFCOMM not starting automatically after upgrade to BlueZ
4.86.
If I issue manually rfcomm bind all /dev/rfcomm* is there.

As I can see there is no invocation of bluetooth in rc*.d S* scripts
only udev script.

System Fedora 8 (kernel, initscripts, glibc from 10).

What am I missing?
(of course I can add Sxxbluetooth containing rfcomm bind all to my
scripts but it looks "quick and dirty").

W.P.

^ permalink raw reply

* Re: [PATCH] Bluetooth: Fix BT_L2CAP and BT_SCO in Kconfig
From: Gustavo F. Padovan @ 2011-02-27 19:19 UTC (permalink / raw)
  To: Vitaly Wool; +Cc: davem, linville, linux-bluetooth, netdev
In-Reply-To: <AANLkTimuyx4ixPq5BexRHozebVpjry2k-2xskqVf79g1@mail.gmail.com>

Hi Vitaly,

* Vitaly Wool <vitalywool@gmail.com> [2011-02-26 18:52:44 +0100]:

> Hi Gustavo,
> 
> On Sat, Feb 26, 2011 at 2:41 AM, Gustavo F. Padovan
> <padovan@profusion.mobi> wrote:
> > If we want something "bool" built-in in something "tristate" it can't
> > "depend on" the tristate config option.
> >
> > Report by DaveM:
> >
> >   I give it 'y' just to make it happen, for both, and afterways no
> >   matter how many times I rerun "make oldconfig" I keep seeing things
> >   like this in my build:
> >
> > scripts/kconfig/conf --silentoldconfig Kconfig
> > include/config/auto.conf:986:warning: symbol value 'm' invalid for BT_SCO
> > include/config/auto.conf:3156:warning: symbol value 'm' invalid for BT_L2CAP
> >
> > Reported-by: David S. Miller <davem@davemloft.net>
> > Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
> > ---
> >  net/bluetooth/Kconfig |    6 ++++--
> >  1 files changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
> > index c6f9c2f..6ae5ec5 100644
> > --- a/net/bluetooth/Kconfig
> > +++ b/net/bluetooth/Kconfig
> > @@ -31,9 +31,10 @@ menuconfig BT
> >          to Bluetooth kernel modules are provided in the BlueZ packages.  For
> >          more information, see <http://www.bluez.org/>.
> >
> > +if BT != n
> > +
> >  config BT_L2CAP
> >        bool "L2CAP protocol support"
> > -       depends on BT
> >        select CRC16
> >        help
> >          L2CAP (Logical Link Control and Adaptation Protocol) provides
> > @@ -42,11 +43,12 @@ config BT_L2CAP
> >
> >  config BT_SCO
> >        bool "SCO links support"
> > -       depends on BT
> >        help
> >          SCO link provides voice transport over Bluetooth.  SCO support is
> >          required for voice applications like Headset and Audio.
> >
> > +endif
> > +
> 
> Ugh, isn't it far cleaner to change initial dependencies to "depends
> on BT != n" ?

I just followed the same approach as net/ipv6/Kconfig and
net/mac80211/Kconfig. 

Dave, how do you prefer this?

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH] work around for l2cap NULL dereference in l2cap_conn_start
From: Gustavo F. Padovan @ 2011-02-27 19:15 UTC (permalink / raw)
  To: Liang Bao; +Cc: David Fries, Andrei Warkentin, linux-bluetooth, linux-kernel
In-Reply-To: <AANLkTi=b5UCdyc3ZtUFCx23uYygM7eRyGu-y_wdJ5JXi@mail.gmail.com>

Hi David and Liang,

* Liang Bao <tim.bao@gmail.com> [2011-02-21 14:41:29 +0800]:

> Hi, David, Andrew et al.
> 
> 2011/2/21 David Fries <david@fries.net>:
> > bt_sk(sk)->parent can be NULL in l2cap_conn_start in state BT_CONNECT2
> > at least when a headset device pairs and the play button was pressed
> > right before pairing.
> >
> > Signed-off-by: David Fries <david@fries.net>
> > ---
> > I removed the printk, can this be merged to the bluetooth next tree?
> >
> > On Mon, Feb 14, 2011 at 03:40:46PM -0600, Andrei Warkentin wrote:
> >> FWIW still need it in 2.6.36.
> >
> > Andrei, I'm curious, what's your hardware hardware and bluetooth
> > device that's trigginer the crash?
> I  once submitted an issue observed with Android+Motorola S305 stereo
> headset. It's still open in launchpad:
> https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/513642. Hope this
> helps. Thanks.
> >
> >> On Mon, Feb 14, 2011 at 8:56 AM, Gustavo F. Padovan
> >> <padovan@profusion.mobi> wrote:
> >> > Hi David,
> >> >
> >> > * David Fries <david@fries.net> [2011-02-10 21:53:09 -0600]:
> >> >
> >> >> Here's a patch to avoid a very repeatable crash in the N900.  If I
> >> >> take a Motorola S305 bluetooth headset that was previously paried with
> >> >> the N900, turn it on, and press the play button before the headphones
> >> >> automatically pair with the cell phone, the N900 will crash (and
> >> >> reboot) in pairing.  If I wait until after they have paired there
> >> >> isn't any problem.  The patch is against the kernel-power
> >> >> 2.6.28-maemo46 by Thomas Tanner, the stock Nokia PR1.2 oops looked
> >> >> the same, I just haven't gone back to that kernel.
> >> >
> >> > This is a very old kernel. You need to check this issue against
> >> > bluetooth-next-2.6.
> >
> >  net/bluetooth/l2cap.c |    3 ++-
> >  1 files changed, 2 insertions(+), 1 deletions(-)
> >
> > diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> > index ed83c1f..a7aa4d9 100644
> > --- a/net/bluetooth/l2cap.c
> > +++ b/net/bluetooth/l2cap.c
> > @@ -408,7 +408,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
> >                                        struct sock *parent = bt_sk(sk)->parent;
> >                                        rsp.result = cpu_to_le16(L2CAP_CR_PEND);
> >                                        rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
> > -                                       parent->sk_data_ready(parent, 0);
> > +                                       if(parent)
> > +                                               parent->sk_data_ready(parent,0);
> >
> >                                } else {
> >                                        sk->sk_state = BT_CONFIG;

I pushed the following patch to bluetooth-2.6 tree. It should fix the problem
by avoiding connections to be accepted before a L2CAP info response comes:

commit 743400e01a33779f93b79c84a1b0d1a2d27338c8
Author: Gustavo F. Padovan <padovan@profusion.mobi>
Date:   Sun Feb 27 16:05:07 2011 -0300

    Bluetooth: Don't accept l2cap connection before info_rsp
    
    When using defer_setup accepting a connection before receive the L2CAP
    Info Response for the connection lead us to a crash in l2cap_conn_start(.
    
    Reported-by: David Fries <david@fries.net>
    Reported-by: Liang Bao <tim.bao@gmail.com>
    Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>

diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index c4cf3f5..a8ca42b 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -211,8 +211,8 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
                        continue;
                }
 
-               if (sk->sk_state == BT_CONNECTED || !newsock ||
-                                               bt_sk(parent)->defer_setup) {
+               if ((bt_sk(parent)->defer_setup && sk->sk_state == BT_CONNECT2)
+                               || sk->sk_state == BT_CONNECTED || !newsock) {
                        bt_accept_unlink(sk);
                        if (newsock)
                                sock_graft(sk, newsock);


-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply related

* Re: HCI core error recovery.
From: Andrei Warkentin @ 2011-02-27 11:30 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <AANLkTikW1upXoEX05vVepE+GFHoFk4_X6m0ur1PYEHFz@mail.gmail.com>

On Fri, Feb 18, 2011 at 2:21 PM, Andrei Warkentin <andreiw@motorola.com> wrote:
> On Mon, Feb 14, 2011 at 4:23 PM, Andrei Warkentin <andreiw@motorola.com> wrote:
>> On Sat, Feb 12, 2011 at 12:47 AM, Andrei Warkentin <andreiw@motorola.com> wrote:
>>> On Fri, Feb 11, 2011 at 5:07 PM, Andrei Warkentin <andreiw@motorola.com> wrote:
>>>> Dear List,
>>>>
>>>> I've run into an interesting problem. Excuse me in advance if this was
>>>> already covered here, or for my explanations, since I'm not too
>>>> familiar with overall flow within BlueZ or Bluetooth specifics...
>>>> We've had some hardware config issues that resulted in garbage/malformed
>>>> messages arriving via H4 into the HCI layer. We've since resolved
>>>> these, but it got me thinking. The issues would result in certain HCI
>>>> messages being missed, including occasionally disconnect events being
>>>> missed, and a subsequent connect event would result in a double add.
>>>>
>>>> I was thinking about how to fix at the very least the crash. The sysfs
>>>> object is created as a last step after getting a "connection
>>>> completed" HCI message, I think. What I am unsure about is if it's
>>>> safe to just ignore the add if there is already a sysfs entry...
>>>>
>>>> So I would think the HCI core needs some resiliency against
>>>> bad/malignant bluetooth controllers, and perform error
>>>> recovery/resynchronization. Perhaps maybe there is room for a virtual
>>>> hci controller that just injects various message types to see how well
>>>> the core can cope?
>>>>
>>>> Thanks in advance,
>>>> A
>>>
>>> To further explain the issue, here is what was happening -
>>>
>>> 0) A BT device is paired.
>>> 1) Host goes into sleep mode.
>>> 2) BT device turns off.
>>> 3) Host wakes up due to BT waking the host. Due to UART resume issues,
>>> HCI message corrupted. hci_disconn_complete_evt never gets called.
>>> 4) BT device turns on.
>>> 5) devref gets incremented in  hci_conn_complete_evt, and is now 2.
>>> 6) BT device turns off. hci_disconn_complete_evt is called, conn hash
>>> is deleted, but sysfs entry not cleaned up since
>>> atomic_dec_and_test(&conn->devref) != 0.
>>> 7) BT device turns on. sysfs add fails since it never was cleaned up.
>>>
>>> The attached patch takes care of that. I'm not too familiar with BlueZ
>>> (or bluetooth :-(), so I would like your feedback. In particular, I am
>>> unsure about sync connections.
>>> The primary issue overall is that HCI core doesn't handle HCI issues
>>> (whether caused by transport issues, or bad/malicious BT controller).
>>> I am curious if there are other ways to break the core.
>>>
>>> Thanks,
>>> A
>>>
>>
>> Anyone?
>>
>
> Anyone? Who should I talk to about HCI?
>

Anyone pretty please :)? I'm positive what I'm doing isn't necessarily
right, but I do think this is a real issue in current BlueZ code that
needs work. HCI core should be more resilient to HCI transport issues,
after all, the BT HCI spec does mandate specific behavior.

A

^ permalink raw reply

* Re: Linux 2.6.28-10 Oops in hci_send_to_sock
From: lundman @ 2011-02-27  6:25 UTC (permalink / raw)
  To: linux-bluetooth


Linux-2.6.28 CE41xx kernel, sodaville board.

I turned on more debugging, and added a print for each SK and peppered 
the logic a little:

[code]
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
{
[snip]

         BT_DBG("filter");

         /* Apply filter */
         flt = &hci_pi(sk)->filter;

  [snip]

         BT_DBG("type");

         if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
             register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);

             if (!hci_test_bit(evt, &flt->event_mask))
                 continue;

             if (flt->opcode &&
                 ((evt == HCI_EV_CMD_COMPLETE &&
                   flt->opcode !=                  get_unaligned((__le16 
*)(skb->data + 3))) ||
                  (evt == HCI_EV_CMD_STATUS &&
                   flt->opcode !=
                   get_unaligned((__le16 *)(skb->data + 4)))))
                 continue;
         }

         BT_DBG("clone");


[/code]


When I start bluetoothd, the panic looks like:


[code]
hci_send_to_sock: hdev 00000000 len 8
usbcore: registered new interface driver btusb
hci_sock_create: sock cbd6dd80
hci_sock_bind: sock cbd6dd80 sk cab87c00
hci_sock_sendmsg: sock cbd6dd80 sk cab87c00
hci_sock_release: sock cbd6dd80 sk cab87c00
hci_sock_create: sock cbd6dd80
hci_sock_setsockopt: sk cab87e00, opt 2
hci_sock_bind: sock cbd6dd80 sk cab87e00
hci_sock_ioctl: cmd 800448d2 arg b7f37208
hci_sock_create: sock cbdb9000
hci_sock_bind: sock cbdb9000 sk ca2cd400
hci_dev_get: 0
hci_sock_setsockopt: sk ca2cd400, opt 2
hci_sock_ioctl: cmd 400448e2 arg bff12038
hci_dev_get: 0
hci_sock_ioctl: cmd 400448c9 arg 0
hci_dev_get: 0
hci_dev_open: hci0 cc308c00
btusb_open: hci0
btusb_submit_intr_urb: hci0
__hci_request: hci0 start
btusb_intr_complete: hci0 urb ca3bec80 status 0 count 6
hci_rx_task: hci0
hci_send_to_sock: hdev cc308c00 len 6
hci_send_to_sock: skb ca2cd400
hci_send_to_sock: filter
hci_send_to_sock: type
BUG: unable to handle kernel NULL pointer dereference at 00000008
IP: [<cf108fc8>] hci_send_to_sock+0x83/0x153 [bluetooth]
*pdpt = 000000000a3d6001 *pde = 0000000000000000
Oops: 0000 [#1] PREEMPT
last sysfs file: /sys/class/vc/vcsa1/dev
Modules linked in: btusb bluetooth fusion pvrsrvkm alsa_shim 
snd_usb_audio snd_x

Pid: 1783, comm: bluetoothd Not tainted (2.6.28 #1)
EIP: 0060:[<cf108fc8>] EFLAGS: 00010246 CPU: 0
EIP is at hci_send_to_sock+0x83/0x153 [bluetooth]
EAX: 00000008 EBX: ca2cd400 ECX: 00000004 EDX: ffffffff
ESI: ca2cd408 EDI: 00000102 EBP: cc2a1480 ESP: ca3cbd4c
  DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
Process bluetoothd (pid: 1783, ti=ca3ca000 task=ca0e6e60 task.ti=ca3ca000)
Call Trace:
  [<cf103ef1>] hci_rx_task+0x54/0x286 [bluetooth]
  [<c011ee03>] tasklet_action+0x34/0x69
  [<c011ec7e>] __do_softirq+0x53/0xe7
  [<cfb2b989>] SystemISRWrapper+0xe/0x24 [pvrsrvkm]
  [<c013a8dc>] handle_IRQ_event+0x25/0x4a
  [<c011ed39>] do_softirq+0x27/0x29
  [<c011ef52>] irq_exit+0x32/0x34
  [<c0104ed8>] do_IRQ+0x4c/0x94
  [<c0298eef>] serial8250_console_putchar+0x0/0x1d
  [<c01039bf>] common_interrupt+0x23/0x28
  [<c011b494>] vprintk+0x1d3/0x300
  [<c011b525>] vprintk+0x264/0x300
  [<c013fe13>] filemap_fault+0x119/0x466
  [<c011b5dc>] printk+0x1b/0x1f
  [<cf102fba>] __hci_request+0x48/0xfb [bluetooth]
  [<cf1034e8>] hci_init_req+0x0/0x158 [bluetooth]
  [<c01179c5>] default_wake_function+0x0/0x8
  [<cf103902>] hci_dev_open+0x9a/0x197 [bluetooth]
  [<c035c98f>] sock_ioctl+0xb0/0x1fc
  [<c035c8df>] sock_ioctl+0x0/0x1fc
  [<c016d5f6>] vfs_ioctl+0x1f/0x6d
  [<c016d7a7>] do_vfs_ioctl+0x52/0x471
  [<c0111f41>] do_page_fault+0x1b2/0x881
  [<c0111d8f>] do_page_fault+0x0/0x881
  [<c043a1c2>] error_code+0x6a/0x70
  [<c016dbfa>] sys_ioctl+0x34/0x50
  [<c0102e71>] sysenter_do_call+0x12/0x25
  [<c0430000>] pci_scan_bridge+0x40/0x3c7
[/code]


Somewhere between 'type' and 'clone', anyone want to throw me a bone?;)

Lund


^ permalink raw reply

* [PATCH 2/2] Remove redundante check for server when checking for usb
From: luiz.dentz @ 2011-02-26 19:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Luiz Augusto von Dentz
In-Reply-To: <1298749782-24129-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

There is a check for this already on Makefile.am
---
 configure.ac |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index a17d0ca..9194843 100644
--- a/configure.ac
+++ b/configure.ac
@@ -155,8 +155,7 @@ AC_ARG_ENABLE(usb, AC_HELP_STRING([--enable-usb],
 				[enable usb plugin]), [
 	enable_usb=${enableval}
 ])
-AM_CONDITIONAL(USB, test "${enable_usb}" = "yes" &&
-				test "${enable_server}" != "no")
+AM_CONDITIONAL(USB, test "${enable_usb}" = "yes")
 
 AC_ARG_ENABLE(pcsuite, AC_HELP_STRING([--enable-pcsuite],
 				[enable Nokia PcSuite plugin]), [
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/2] Move pcsuite drivers to its own plugin
From: luiz.dentz @ 2011-02-26 19:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Luiz Augusto von Dentz
In-Reply-To: <1298749782-24129-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

This make it easier to enable/disable this funcionality as a whole.
---
 Makefile.am            |    6 +-
 configure.ac           |    9 +-
 plugins/ftp.c          |  165 +---------------
 plugins/ftp.h          |   30 +++
 plugins/nokia-backup.c |  309 -----------------------------
 plugins/pcsuite.c      |  515 ++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 561 insertions(+), 473 deletions(-)
 create mode 100644 plugins/ftp.h
 delete mode 100644 plugins/nokia-backup.c
 create mode 100644 plugins/pcsuite.c

diff --git a/Makefile.am b/Makefile.am
index fc996ec..d32d613 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -43,9 +43,9 @@ endif
 builtin_modules += filesystem
 builtin_sources += plugins/filesystem.c plugins/filesystem.h
 
-if NOKIA_BACKUP
-builtin_modules += backup
-builtin_sources += plugins/nokia-backup.c
+if NOKIA_PCSUITE
+builtin_modules += pcsuite
+builtin_sources += plugins/pcsuite.c
 endif
 
 builtin_modules += opp
diff --git a/configure.ac b/configure.ac
index da8fb64..a17d0ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,12 +158,11 @@ AC_ARG_ENABLE(usb, AC_HELP_STRING([--enable-usb],
 AM_CONDITIONAL(USB, test "${enable_usb}" = "yes" &&
 				test "${enable_server}" != "no")
 
-AC_ARG_ENABLE(nokia_backup, AC_HELP_STRING([--enable-nokia-backup],
-				[enable nokia-backup plugin]), [
-	enable_nokia_backup=${enableval}
+AC_ARG_ENABLE(pcsuite, AC_HELP_STRING([--enable-pcsuite],
+				[enable Nokia PcSuite plugin]), [
+	enable_pcsuite=${enableval}
 ])
-AM_CONDITIONAL(NOKIA_BACKUP, test "${enable_nokia_backup}" = "yes" &&
-				test "${enable_server}" != "no")
+AM_CONDITIONAL(NOKIA_PCSUITE, test "${enable_pcsuite}" = "yes")
 
 AC_ARG_ENABLE(client, AC_HELP_STRING([--disable-client],
 				[disable compilation of OBEX client]), [
diff --git a/plugins/ftp.c b/plugins/ftp.c
index 633abf3..79223bf 100644
--- a/plugins/ftp.c
+++ b/plugins/ftp.c
@@ -50,6 +50,7 @@
 #include "dbus.h"
 #include "mimetype.h"
 #include "service.h"
+#include "ftp.h"
 
 #define LST_TYPE "x-obex/folder-listing"
 #define CAP_TYPE "x-obex/capability"
@@ -189,7 +190,7 @@ static int get_by_type(struct ftp_session *ftp, const char *type)
 	return err;
 }
 
-static void *ftp_connect(struct obex_session *os, int *err)
+void *ftp_connect(struct obex_session *os, int *err)
 {
 	struct ftp_session *ftp;
 	const char *root_folder;
@@ -212,8 +213,8 @@ static void *ftp_connect(struct obex_session *os, int *err)
 	return ftp;
 }
 
-static int ftp_get(struct obex_session *os, obex_object_t *obj,
-					gboolean *stream, void *user_data)
+int ftp_get(struct obex_session *os, obex_object_t *obj, gboolean *stream,
+							void *user_data)
 {
 	struct ftp_session *ftp = user_data;
 	const char *type = obex_get_type(os);
@@ -254,7 +255,7 @@ static int ftp_delete(struct ftp_session *ftp, const char *name)
 	return ret;
 }
 
-static int ftp_chkput(struct obex_session *os, void *user_data)
+int ftp_chkput(struct obex_session *os, void *user_data)
 {
 	struct ftp_session *ftp = user_data;
 	const char *name = obex_get_name(os);
@@ -278,8 +279,7 @@ static int ftp_chkput(struct obex_session *os, void *user_data)
 	return ret;
 }
 
-static int ftp_put(struct obex_session *os, obex_object_t *obj,
-						void *user_data)
+int ftp_put(struct obex_session *os, obex_object_t *obj, void *user_data)
 {
 	struct ftp_session *ftp = user_data;
 	const char *name = obex_get_name(os);
@@ -299,8 +299,7 @@ static int ftp_put(struct obex_session *os, obex_object_t *obj,
 	return 0;
 }
 
-static int ftp_setpath(struct obex_session *os, obex_object_t *obj,
-							void *user_data)
+int ftp_setpath(struct obex_session *os, obex_object_t *obj, void *user_data)
 {
 	struct ftp_session *ftp = user_data;
 	const char *root_folder, *name;
@@ -404,7 +403,7 @@ done:
 	return err;
 }
 
-static void ftp_disconnect(struct obex_session *os, void *user_data)
+void ftp_disconnect(struct obex_session *os, void *user_data)
 {
 	struct ftp_session *ftp = user_data;
 
@@ -416,145 +415,6 @@ static void ftp_disconnect(struct obex_session *os, void *user_data)
 	g_free(ftp);
 }
 
-static void *pcsuite_connect(struct obex_session *os, int *err)
-{
-	struct pcsuite_session *pcsuite;
-	struct ftp_session *ftp;
-	int fd;
-	char *filename;
-
-	DBG("");
-
-	ftp = ftp_connect(os, err);
-	if (ftp == NULL)
-		return NULL;
-
-	filename = g_build_filename(g_get_home_dir(), ".pcsuite", NULL);
-
-	fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644);
-	if (fd < 0 && errno != EEXIST) {
-		error("open(%s): %s(%d)", filename, strerror(errno), errno);
-		goto fail;
-	}
-
-	/* Try to remove the file before retrying since it could be
-	   that some process left/crash without removing it */
-	if (fd < 0) {
-		if (remove(filename) < 0) {
-			error("remove(%s): %s(%d)", filename, strerror(errno),
-									errno);
-			goto fail;
-		}
-
-		fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644);
-		if (fd < 0) {
-			error("open(%s): %s(%d)", filename, strerror(errno),
-									errno);
-			goto fail;
-		}
-	}
-
-	DBG("%s created", filename);
-
-	pcsuite = g_new0(struct pcsuite_session, 1);
-	pcsuite->ftp = ftp;
-	pcsuite->lock_file = filename;
-	pcsuite->fd = fd;
-
-	DBG("session %p created", pcsuite);
-
-	if (err)
-		*err = 0;
-
-	return pcsuite;
-
-fail:
-	if (ftp)
-		ftp_disconnect(os, ftp);
-	if (err)
-		*err = -errno;
-
-	g_free(filename);
-
-	return NULL;
-}
-
-static int pcsuite_get(struct obex_session *os, obex_object_t *obj,
-					gboolean *stream, void *user_data)
-{
-	struct pcsuite_session *pcsuite = user_data;
-
-	DBG("%p", pcsuite);
-
-	return ftp_get(os, obj, stream, pcsuite->ftp);
-}
-
-static int pcsuite_chkput(struct obex_session *os, void *user_data)
-{
-	struct pcsuite_session *pcsuite = user_data;
-
-	DBG("%p", pcsuite);
-
-	return ftp_chkput(os, pcsuite->ftp);
-}
-
-static int pcsuite_put(struct obex_session *os, obex_object_t *obj,
-							void *user_data)
-{
-	struct pcsuite_session *pcsuite = user_data;
-
-	DBG("%p", pcsuite);
-
-	return ftp_put(os, obj, pcsuite->ftp);
-}
-
-static int pcsuite_setpath(struct obex_session *os, obex_object_t *obj,
-							void *user_data)
-{
-	struct pcsuite_session *pcsuite = user_data;
-
-	DBG("%p", pcsuite);
-
-	return ftp_setpath(os, obj, pcsuite->ftp);
-}
-
-static void pcsuite_disconnect(struct obex_session *os, void *user_data)
-{
-	struct pcsuite_session *pcsuite = user_data;
-
-	DBG("%p", pcsuite);
-
-	if (pcsuite->fd >= 0)
-		close(pcsuite->fd);
-
-	if (pcsuite->lock_file) {
-		remove(pcsuite->lock_file);
-		g_free(pcsuite->lock_file);
-	}
-
-	if (pcsuite->ftp)
-		ftp_disconnect(os, pcsuite->ftp);
-
-	g_free(pcsuite);
-}
-
-static struct obex_service_driver pcsuite = {
-	.name = "Nokia OBEX PC Suite Services",
-	.service = OBEX_PCSUITE,
-	.channel = PCSUITE_CHANNEL,
-	.record = PCSUITE_RECORD,
-	.target = FTP_TARGET,
-	.target_size = TARGET_SIZE,
-	.who = PCSUITE_WHO,
-	.who_size = PCSUITE_WHO_SIZE,
-	.connect = pcsuite_connect,
-	.get = pcsuite_get,
-	.put = pcsuite_put,
-	.chkput = pcsuite_chkput,
-	.setpath = pcsuite_setpath,
-	.disconnect = pcsuite_disconnect
-};
-
 static struct obex_service_driver ftp = {
 	.name = "File Transfer server",
 	.service = OBEX_FTP,
@@ -572,19 +432,12 @@ static struct obex_service_driver ftp = {
 
 static int ftp_init(void)
 {
-	int err;
-
-	err = obex_service_driver_register(&ftp);
-	if (err < 0)
-		return err;
-
-	return obex_service_driver_register(&pcsuite);
+	return obex_service_driver_register(&ftp);
 }
 
 static void ftp_exit(void)
 {
 	obex_service_driver_unregister(&ftp);
-	obex_service_driver_unregister(&pcsuite);
 }
 
 OBEX_PLUGIN_DEFINE(ftp, ftp_init, ftp_exit)
diff --git a/plugins/ftp.h b/plugins/ftp.h
new file mode 100644
index 0000000..2374125
--- /dev/null
+++ b/plugins/ftp.h
@@ -0,0 +1,30 @@
+/*
+ *
+ *  OBEX Server
+ *
+ *  Copyright (C) 2007-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
+ *
+ */
+
+void *ftp_connect(struct obex_session *os, int *err);
+int ftp_get(struct obex_session *os, obex_object_t *obj, gboolean *stream,
+							void *user_data);
+int ftp_chkput(struct obex_session *os, void *user_data);
+int ftp_put(struct obex_session *os, obex_object_t *obj, void *user_data);
+int ftp_setpath(struct obex_session *os, obex_object_t *obj, void *user_data);
+void ftp_disconnect(struct obex_session *os, void *user_data);
diff --git a/plugins/nokia-backup.c b/plugins/nokia-backup.c
deleted file mode 100644
index cf17e16..0000000
--- a/plugins/nokia-backup.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- *
- *  OBEX Server
- *
- *  Copyright (C) 2010  Nokia Corporation
- *  Copyright (C) 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 <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <fcntl.h>
-#include <wait.h>
-
-#include <glib.h>
-#include "gdbus.h"
-
-
-#include <openobex/obex.h>
-#include <openobex/obex_const.h>
-
-#include "plugin.h"
-#include "log.h"
-#include "obex.h"
-#include "mimetype.h"
-#include "service.h"
-
-#define BACKUP_BUS_NAME		"com.nokia.backup.plugin"
-#define BACKUP_PATH		"/com/nokia/backup"
-#define BACKUP_PLUGIN_INTERFACE	"com.nokia.backup.plugin"
-#define BACKUP_DBUS_TIMEOUT	(1000 * 60 * 15)
-
-static const uint8_t FTP_TARGET[TARGET_SIZE] = {
-	0xF9, 0xEC, 0x7B, 0xC4,  0x95, 0x3C, 0x11, 0xD2,
-	0x98, 0x4E, 0x52, 0x54,  0x00, 0xDC, 0x9E, 0x09  };
-
-struct backup_object{
-	gchar *cmd;
-	int fd;
-	int oflag;
-	int error_code;
-	mode_t mode;
-	DBusPendingCall *pending_call;
-	DBusConnection *conn;
-};
-
-static void on_backup_dbus_notify(DBusPendingCall *pending_call,
-					void *user_data)
-{
-	struct backup_object *obj = user_data;
-	DBusMessage *reply;
-	const char *filename;
-	int error_code;
-
-	DBG("Notification received for pending call - %s", obj->cmd);
-
-	reply = dbus_pending_call_steal_reply(pending_call);
-
-	if (reply && dbus_message_get_args(reply, NULL, DBUS_TYPE_INT32,
-					&error_code, DBUS_TYPE_STRING,
-					&filename, DBUS_TYPE_INVALID)) {
-
-		obj->error_code = error_code;
-
-		if (filename) {
-			DBG("Notification - file path = %s, error_code = %d",
-					filename, error_code);
-			if (error_code == 0)
-				obj->fd = open(filename,obj->oflag,obj->mode);
-		}
-
-	} else
-		DBG("Notification timed out or connection got closed");
-
-	if (reply)
-		dbus_message_unref(reply);
-
-	dbus_pending_call_unref(pending_call);
-	obj->pending_call = NULL;
-	dbus_connection_unref(obj->conn);
-	obj->conn = NULL;
-
-	if (obj->fd >= 0) {
-		DBG("File opened, setting io flags, cmd = %s",
-				obj->cmd);
-		if (obj->oflag == O_RDONLY)
-			obex_object_set_io_flags(user_data, G_IO_IN, 0);
-		else
-			obex_object_set_io_flags(user_data, G_IO_OUT, 0);
-	} else {
-		DBG("File open error, setting io error, cmd = %s",
-				obj->cmd);
-		obex_object_set_io_flags(user_data, G_IO_ERR, -EPERM);
-	}
-}
-
-static gboolean send_backup_dbus_message(const char *oper,
-					struct backup_object *obj,
-					size_t *size)
-{
-	DBusConnection *conn;
-	DBusMessage *msg;
-	DBusPendingCall *pending_call;
-	gboolean ret = FALSE;
-	dbus_uint32_t file_size;
-
-	file_size = size ? *size : 0;
-
-	conn = g_dbus_setup_bus(DBUS_BUS_SESSION, NULL, NULL);
-
-	if (conn == NULL)
-		return FALSE;
-
-	msg = dbus_message_new_method_call(BACKUP_BUS_NAME, BACKUP_PATH,
-						BACKUP_PLUGIN_INTERFACE,
-						"request");
-	if (msg == NULL) {
-		dbus_connection_unref(conn);
-		return FALSE;
-	}
-
-	dbus_message_append_args(msg, DBUS_TYPE_STRING, &oper,
-					DBUS_TYPE_STRING, &obj->cmd,
-					DBUS_TYPE_INT32, &file_size,
-					DBUS_TYPE_INVALID);
-
-	if (strcmp(oper, "open") == 0) {
-		ret = dbus_connection_send_with_reply(conn, msg, &pending_call,
-							BACKUP_DBUS_TIMEOUT);
-		dbus_message_unref(msg);
-		if (ret) {
-			obj->conn = conn;
-			obj->pending_call = pending_call;
-			ret = dbus_pending_call_set_notify(pending_call,
-							on_backup_dbus_notify,
-							obj, NULL);
-		} else
-			dbus_connection_unref(conn);
-	} else {
-		ret = dbus_connection_send(conn, msg, NULL);
-		dbus_message_unref(msg);
-		dbus_connection_unref(conn);
-	}
-
-	return ret;
-}
-
-static void *backup_open(const char *name, int oflag, mode_t mode,
-				void *context, size_t *size, int *err)
-{
-	struct backup_object *obj = g_new0(struct backup_object, 1);
-
-	DBG("cmd = %s", name);
-
-	obj->cmd = g_path_get_basename(name);
-	obj->oflag = oflag;
-	obj->mode = mode;
-	obj->fd = -1;
-	obj->pending_call = NULL;
-	obj->conn = NULL;
-	obj->error_code = 0;
-
-	if (send_backup_dbus_message("open", obj, size) == FALSE) {
-		g_free(obj);
-		obj = NULL;
-	}
-
-	if (err)
-		*err = 0;
-
-	return obj;
-}
-
-static int backup_close(void *object)
-{
-	struct backup_object *obj = object;
-	size_t size = 0;
-
-	DBG("cmd = %s", obj->cmd);
-
-	if (obj->fd != -1)
-		close(obj->fd);
-
-	if (obj->pending_call) {
-		dbus_pending_call_cancel(obj->pending_call);
-		dbus_pending_call_unref(obj->pending_call);
-		dbus_connection_unref(obj->conn);
-	}
-
-	send_backup_dbus_message("close", obj, &size);
-
-	g_free(obj->cmd);
-	g_free(obj);
-
-	return 0;
-}
-
-static ssize_t backup_read(void *object, void *buf, size_t count,
-					uint8_t *hi, unsigned int *flags)
-{
-	struct backup_object *obj = object;
-	ssize_t ret = 0;
-
-	*hi = OBEX_HDR_BODY;
-
-	if (flags)
-		*flags = 0;
-
-	if (obj->pending_call) {
-		DBG("cmd = %s, IN WAITING STAGE", obj->cmd);
-		return -EAGAIN;
-	}
-
-	if (obj->fd != -1) {
-		DBG("cmd = %s, READING DATA", obj->cmd);
-		ret = read(obj->fd, buf, count);
-		if (ret < 0)
-			ret = -errno;
-	} else {
-		DBG("cmd = %s, PERMANENT FAILURE", obj->cmd);
-		ret = obj->error_code ? -obj->error_code : -ENOENT;
-	}
-
-	return ret;
-}
-
-static ssize_t backup_write(void *object, const void *buf, size_t count)
-{
-	struct backup_object *obj = object;
-	ssize_t ret = 0;
-
-	if (obj->pending_call) {
-		DBG("cmd = %s, IN WAITING STAGE", obj->cmd);
-		return -EAGAIN;
-	}
-
-	if (obj->fd != -1) {
-		ret = write(obj->fd, buf, count);
-
-		DBG("cmd = %s, WRITTING", obj->cmd);
-
-		if (ret < 0) {
-			error("backup: cmd = %s", obj->cmd);
-			ret = -errno;
-		}
-	} else {
-		error("backup: cmd = %s", obj->cmd);
-		ret = obj->error_code ? -obj->error_code : -ENOENT;
-	}
-
-	return ret;
-}
-
-static int backup_flush(void *object)
-{
-	DBG("%p", object);
-
-	return 0;
-}
-
-static struct obex_mime_type_driver backup = {
-	.target = FTP_TARGET,
-	.target_size = TARGET_SIZE,
-	.mimetype = "application/vnd.nokia-backup",
-	.open = backup_open,
-	.close = backup_close,
-	.read = backup_read,
-	.write = backup_write,
-	.flush = backup_flush,
-};
-
-static int backup_init(void)
-{
-	return obex_mime_type_driver_register(&backup);
-}
-
-static void backup_exit(void)
-{
-	obex_mime_type_driver_unregister(&backup);
-}
-
-OBEX_PLUGIN_DEFINE(backup, backup_init, backup_exit)
diff --git a/plugins/pcsuite.c b/plugins/pcsuite.c
new file mode 100644
index 0000000..9cf65c9
--- /dev/null
+++ b/plugins/pcsuite.c
@@ -0,0 +1,515 @@
+/*
+ *
+ *  OBEX Server
+ *
+ *  Copyright (C) 2007-2010  Nokia Corporation
+ *  Copyright (C) 2007-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 <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <glib.h>
+#include "gdbus.h"
+
+#include <openobex/obex.h>
+#include <openobex/obex_const.h>
+
+#include "plugin.h"
+#include "log.h"
+#include "obex.h"
+#include "dbus.h"
+#include "mimetype.h"
+#include "service.h"
+#include "ftp.h"
+
+#define PCSUITE_CHANNEL 24
+#define PCSUITE_WHO_SIZE 8
+
+#define PCSUITE_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>	\
+<record>								\
+  <attribute id=\"0x0001\">						\
+    <sequence>								\
+      <uuid value=\"00005005-0000-1000-8000-0002ee000001\"/>		\
+    </sequence>								\
+  </attribute>								\
+									\
+  <attribute id=\"0x0004\">						\
+    <sequence>								\
+      <sequence>							\
+        <uuid value=\"0x0100\"/>					\
+      </sequence>							\
+      <sequence>							\
+        <uuid value=\"0x0003\"/>					\
+        <uint8 value=\"%u\" name=\"channel\"/>				\
+      </sequence>							\
+      <sequence>							\
+        <uuid value=\"0x0008\"/>					\
+      </sequence>							\
+    </sequence>								\
+  </attribute>								\
+									\
+  <attribute id=\"0x0005\">						\
+    <sequence>								\
+      <uuid value=\"0x1002\"/>						\
+    </sequence>								\
+  </attribute>								\
+									\
+  <attribute id=\"0x0009\">						\
+    <sequence>								\
+      <sequence>							\
+        <uuid value=\"00005005-0000-1000-8000-0002ee000001\"/>		\
+        <uint16 value=\"0x0100\" name=\"version\"/>			\
+      </sequence>							\
+    </sequence>								\
+  </attribute>								\
+									\
+  <attribute id=\"0x0100\">						\
+    <text value=\"%s\" name=\"name\"/>					\
+  </attribute>								\
+</record>"
+
+#define BACKUP_BUS_NAME		"com.nokia.backup.plugin"
+#define BACKUP_PATH		"/com/nokia/backup"
+#define BACKUP_PLUGIN_INTERFACE	"com.nokia.backup.plugin"
+#define BACKUP_DBUS_TIMEOUT	(1000 * 60 * 15)
+
+static const uint8_t FTP_TARGET[TARGET_SIZE] = {
+			0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2,
+			0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 };
+
+static const uint8_t PCSUITE_WHO[PCSUITE_WHO_SIZE] = {
+			'P','C',' ','S','u','i','t','e' };
+
+struct pcsuite_session {
+	struct ftp_session *ftp;
+	char *lock_file;
+	int fd;
+};
+
+static void *pcsuite_connect(struct obex_session *os, int *err)
+{
+	struct pcsuite_session *pcsuite;
+	struct ftp_session *ftp;
+	int fd;
+	char *filename;
+
+	DBG("");
+
+	ftp = ftp_connect(os, err);
+	if (ftp == NULL)
+		return NULL;
+
+	filename = g_build_filename(g_get_home_dir(), ".pcsuite", NULL);
+
+	fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644);
+	if (fd < 0 && errno != EEXIST) {
+		error("open(%s): %s(%d)", filename, strerror(errno), errno);
+		goto fail;
+	}
+
+	/* Try to remove the file before retrying since it could be
+	   that some process left/crash without removing it */
+	if (fd < 0) {
+		if (remove(filename) < 0) {
+			error("remove(%s): %s(%d)", filename, strerror(errno),
+									errno);
+			goto fail;
+		}
+
+		fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644);
+		if (fd < 0) {
+			error("open(%s): %s(%d)", filename, strerror(errno),
+									errno);
+			goto fail;
+		}
+	}
+
+	DBG("%s created", filename);
+
+	pcsuite = g_new0(struct pcsuite_session, 1);
+	pcsuite->ftp = ftp;
+	pcsuite->lock_file = filename;
+	pcsuite->fd = fd;
+
+	DBG("session %p created", pcsuite);
+
+	if (err)
+		*err = 0;
+
+	return pcsuite;
+
+fail:
+	if (ftp)
+		ftp_disconnect(os, ftp);
+	if (err)
+		*err = -errno;
+
+	g_free(filename);
+
+	return NULL;
+}
+
+static int pcsuite_get(struct obex_session *os, obex_object_t *obj,
+					gboolean *stream, void *user_data)
+{
+	struct pcsuite_session *pcsuite = user_data;
+
+	DBG("%p", pcsuite);
+
+	return ftp_get(os, obj, stream, pcsuite->ftp);
+}
+
+static int pcsuite_chkput(struct obex_session *os, void *user_data)
+{
+	struct pcsuite_session *pcsuite = user_data;
+
+	DBG("%p", pcsuite);
+
+	return ftp_chkput(os, pcsuite->ftp);
+}
+
+static int pcsuite_put(struct obex_session *os, obex_object_t *obj,
+							void *user_data)
+{
+	struct pcsuite_session *pcsuite = user_data;
+
+	DBG("%p", pcsuite);
+
+	return ftp_put(os, obj, pcsuite->ftp);
+}
+
+static int pcsuite_setpath(struct obex_session *os, obex_object_t *obj,
+							void *user_data)
+{
+	struct pcsuite_session *pcsuite = user_data;
+
+	DBG("%p", pcsuite);
+
+	return ftp_setpath(os, obj, pcsuite->ftp);
+}
+
+static void pcsuite_disconnect(struct obex_session *os, void *user_data)
+{
+	struct pcsuite_session *pcsuite = user_data;
+
+	DBG("%p", pcsuite);
+
+	if (pcsuite->fd >= 0)
+		close(pcsuite->fd);
+
+	if (pcsuite->lock_file) {
+		remove(pcsuite->lock_file);
+		g_free(pcsuite->lock_file);
+	}
+
+	if (pcsuite->ftp)
+		ftp_disconnect(os, pcsuite->ftp);
+
+	g_free(pcsuite);
+}
+
+static struct obex_service_driver pcsuite = {
+	.name = "Nokia OBEX PC Suite Services",
+	.service = OBEX_PCSUITE,
+	.channel = PCSUITE_CHANNEL,
+	.record = PCSUITE_RECORD,
+	.target = FTP_TARGET,
+	.target_size = TARGET_SIZE,
+	.who = PCSUITE_WHO,
+	.who_size = PCSUITE_WHO_SIZE,
+	.connect = pcsuite_connect,
+	.get = pcsuite_get,
+	.put = pcsuite_put,
+	.chkput = pcsuite_chkput,
+	.setpath = pcsuite_setpath,
+	.disconnect = pcsuite_disconnect
+};
+
+struct backup_object{
+	gchar *cmd;
+	int fd;
+	int oflag;
+	int error_code;
+	mode_t mode;
+	DBusPendingCall *pending_call;
+	DBusConnection *conn;
+};
+
+static void on_backup_dbus_notify(DBusPendingCall *pending_call,
+					void *user_data)
+{
+	struct backup_object *obj = user_data;
+	DBusMessage *reply;
+	const char *filename;
+	int error_code;
+
+	DBG("Notification received for pending call - %s", obj->cmd);
+
+	reply = dbus_pending_call_steal_reply(pending_call);
+
+	if (reply && dbus_message_get_args(reply, NULL, DBUS_TYPE_INT32,
+					&error_code, DBUS_TYPE_STRING,
+					&filename, DBUS_TYPE_INVALID)) {
+
+		obj->error_code = error_code;
+
+		if (filename) {
+			DBG("Notification - file path = %s, error_code = %d",
+					filename, error_code);
+			if (error_code == 0)
+				obj->fd = open(filename,obj->oflag,obj->mode);
+		}
+
+	} else
+		DBG("Notification timed out or connection got closed");
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_pending_call_unref(pending_call);
+	obj->pending_call = NULL;
+	dbus_connection_unref(obj->conn);
+	obj->conn = NULL;
+
+	if (obj->fd >= 0) {
+		DBG("File opened, setting io flags, cmd = %s",
+				obj->cmd);
+		if (obj->oflag == O_RDONLY)
+			obex_object_set_io_flags(user_data, G_IO_IN, 0);
+		else
+			obex_object_set_io_flags(user_data, G_IO_OUT, 0);
+	} else {
+		DBG("File open error, setting io error, cmd = %s",
+				obj->cmd);
+		obex_object_set_io_flags(user_data, G_IO_ERR, -EPERM);
+	}
+}
+
+static gboolean send_backup_dbus_message(const char *oper,
+					struct backup_object *obj,
+					size_t *size)
+{
+	DBusConnection *conn;
+	DBusMessage *msg;
+	DBusPendingCall *pending_call;
+	gboolean ret = FALSE;
+	dbus_uint32_t file_size;
+
+	file_size = size ? *size : 0;
+
+	conn = g_dbus_setup_bus(DBUS_BUS_SESSION, NULL, NULL);
+
+	if (conn == NULL)
+		return FALSE;
+
+	msg = dbus_message_new_method_call(BACKUP_BUS_NAME, BACKUP_PATH,
+						BACKUP_PLUGIN_INTERFACE,
+						"request");
+	if (msg == NULL) {
+		dbus_connection_unref(conn);
+		return FALSE;
+	}
+
+	dbus_message_append_args(msg, DBUS_TYPE_STRING, &oper,
+					DBUS_TYPE_STRING, &obj->cmd,
+					DBUS_TYPE_INT32, &file_size,
+					DBUS_TYPE_INVALID);
+
+	if (strcmp(oper, "open") == 0) {
+		ret = dbus_connection_send_with_reply(conn, msg, &pending_call,
+							BACKUP_DBUS_TIMEOUT);
+		dbus_message_unref(msg);
+		if (ret) {
+			obj->conn = conn;
+			obj->pending_call = pending_call;
+			ret = dbus_pending_call_set_notify(pending_call,
+							on_backup_dbus_notify,
+							obj, NULL);
+		} else
+			dbus_connection_unref(conn);
+	} else {
+		ret = dbus_connection_send(conn, msg, NULL);
+		dbus_message_unref(msg);
+		dbus_connection_unref(conn);
+	}
+
+	return ret;
+}
+
+static void *backup_open(const char *name, int oflag, mode_t mode,
+				void *context, size_t *size, int *err)
+{
+	struct backup_object *obj = g_new0(struct backup_object, 1);
+
+	DBG("cmd = %s", name);
+
+	obj->cmd = g_path_get_basename(name);
+	obj->oflag = oflag;
+	obj->mode = mode;
+	obj->fd = -1;
+	obj->pending_call = NULL;
+	obj->conn = NULL;
+	obj->error_code = 0;
+
+	if (send_backup_dbus_message("open", obj, size) == FALSE) {
+		g_free(obj);
+		obj = NULL;
+	}
+
+	if (err)
+		*err = 0;
+
+	return obj;
+}
+
+static int backup_close(void *object)
+{
+	struct backup_object *obj = object;
+	size_t size = 0;
+
+	DBG("cmd = %s", obj->cmd);
+
+	if (obj->fd != -1)
+		close(obj->fd);
+
+	if (obj->pending_call) {
+		dbus_pending_call_cancel(obj->pending_call);
+		dbus_pending_call_unref(obj->pending_call);
+		dbus_connection_unref(obj->conn);
+	}
+
+	send_backup_dbus_message("close", obj, &size);
+
+	g_free(obj->cmd);
+	g_free(obj);
+
+	return 0;
+}
+
+static ssize_t backup_read(void *object, void *buf, size_t count,
+					uint8_t *hi, unsigned int *flags)
+{
+	struct backup_object *obj = object;
+	ssize_t ret = 0;
+
+	*hi = OBEX_HDR_BODY;
+
+	if (flags)
+		*flags = 0;
+
+	if (obj->pending_call) {
+		DBG("cmd = %s, IN WAITING STAGE", obj->cmd);
+		return -EAGAIN;
+	}
+
+	if (obj->fd != -1) {
+		DBG("cmd = %s, READING DATA", obj->cmd);
+		ret = read(obj->fd, buf, count);
+		if (ret < 0)
+			ret = -errno;
+	} else {
+		DBG("cmd = %s, PERMANENT FAILURE", obj->cmd);
+		ret = obj->error_code ? -obj->error_code : -ENOENT;
+	}
+
+	return ret;
+}
+
+static ssize_t backup_write(void *object, const void *buf, size_t count)
+{
+	struct backup_object *obj = object;
+	ssize_t ret = 0;
+
+	if (obj->pending_call) {
+		DBG("cmd = %s, IN WAITING STAGE", obj->cmd);
+		return -EAGAIN;
+	}
+
+	if (obj->fd != -1) {
+		ret = write(obj->fd, buf, count);
+
+		DBG("cmd = %s, WRITTING", obj->cmd);
+
+		if (ret < 0) {
+			error("backup: cmd = %s", obj->cmd);
+			ret = -errno;
+		}
+	} else {
+		error("backup: cmd = %s", obj->cmd);
+		ret = obj->error_code ? -obj->error_code : -ENOENT;
+	}
+
+	return ret;
+}
+
+static int backup_flush(void *object)
+{
+	DBG("%p", object);
+
+	return 0;
+}
+
+static struct obex_mime_type_driver backup = {
+	.target = FTP_TARGET,
+	.target_size = TARGET_SIZE,
+	.mimetype = "application/vnd.nokia-backup",
+	.open = backup_open,
+	.close = backup_close,
+	.read = backup_read,
+	.write = backup_write,
+	.flush = backup_flush,
+};
+
+static int pcsuite_init(void)
+{
+	int err;
+
+	err = obex_service_driver_register(&pcsuite);
+	if (err < 0)
+		return err;
+
+	err = obex_mime_type_driver_register(&backup);
+	if (err < 0)
+		obex_service_driver_unregister(&pcsuite);
+
+	return err;
+}
+
+static void pcsuite_exit(void)
+{
+	obex_mime_type_driver_unregister(&backup);
+	obex_service_driver_unregister(&pcsuite);
+}
+
+OBEX_PLUGIN_DEFINE(pcsuite, pcsuite_init, pcsuite_exit)
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/2] Remove redundante check for server when checking for usb
From: luiz.dentz @ 2011-02-26 19:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Luiz Augusto von Dentz
In-Reply-To: <1298749782-24129-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

There is a check for this already on Makefile.am
---
 configure.ac |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index a17d0ca..9194843 100644
--- a/configure.ac
+++ b/configure.ac
@@ -155,8 +155,7 @@ AC_ARG_ENABLE(usb, AC_HELP_STRING([--enable-usb],
 				[enable usb plugin]), [
 	enable_usb=${enableval}
 ])
-AM_CONDITIONAL(USB, test "${enable_usb}" = "yes" &&
-				test "${enable_server}" != "no")
+AM_CONDITIONAL(USB, test "${enable_usb}" = "yes")
 
 AC_ARG_ENABLE(pcsuite, AC_HELP_STRING([--enable-pcsuite],
 				[enable Nokia PcSuite plugin]), [
-- 
1.7.1


^ 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