Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 1/2] android: Shutdown if IPC command for unregistered service is received
From: Szymon Janc @ 2013-11-13 14:47 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Sending commands to not registered services is violation of IPC spec
and should result in daemon shutdown.
---
 android/main.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/android/main.c b/android/main.c
index 36cc8aa..12284f7 100644
--- a/android/main.c
+++ b/android/main.c
@@ -252,6 +252,12 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
 	DBG("service_id %u opcode %u len %u", msg->service_id, msg->opcode,
 								msg->len);
 
+	if (msg->service_id > HAL_SERVICE_ID_MAX ||
+						!services[msg->service_id]) {
+		error("HAL command of not registered service, terminating");
+		goto fail;
+	}
+
 	switch (msg->service_id) {
 	case HAL_SERVICE_ID_CORE:
 		handle_service_core(msg->opcode, msg->payload, msg->len);
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 2/2] android: Core service should be always registered
From: Szymon Janc @ 2013-11-13 14:47 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384354033-21724-1-git-send-email-szymon.janc@tieto.com>

Core service is used to register other services and shall be always
consider registered.
---
 android/main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/android/main.c b/android/main.c
index 12284f7..03720e8 100644
--- a/android/main.c
+++ b/android/main.c
@@ -74,7 +74,8 @@ static guint adapter_timeout = 0;
 static GIOChannel *hal_cmd_io = NULL;
 static GIOChannel *hal_notif_io = NULL;
 
-static bool services[HAL_SERVICE_ID_MAX + 1] = { false };
+/* Core Service (ID=0) should be always consider registered */
+static bool services[HAL_SERVICE_ID_MAX + 1] = { true, false };
 
 static void service_register(void *buf, uint16_t len)
 {
-- 
1.8.4.2


^ permalink raw reply related

* Re: [PATCH 1/2] android/hidhost: Fix memory leak
From: Johan Hedberg @ 2013-11-13 14:48 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1384352974-24036-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Wed, Nov 13, 2013, Andrei Emeltchenko wrote:
> ---
>  android/hidhost.c |    1 +
>  1 file changed, 1 insertion(+)

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ] audio/A2DP: Return -ENOPROTOOPT if record doesn't exist
From: Johan Hedberg @ 2013-11-13 14:49 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1384349196-18190-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Wed, Nov 13, 2013, Luiz Augusto von Dentz wrote:
> In case record is not registered it means no endpoint is available so
> return -ENOPROTOOPT to indicate that it is currently not available.
> ---
>  profiles/audio/a2dp.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: bluetoothd failure after a "malloc retun NULL" injection (attachment fix)
From: Luiz Augusto von Dentz @ 2013-11-13 15:03 UTC (permalink / raw)
  To: Oprisenescu, CatalinX; +Cc: linux-bluetooth@vger.kernel.org, Trandafir, IonutX
In-Reply-To: <6522C4F948C6F5419BA5943E1E79DD2A8ABBAE@IRSMSX104.ger.corp.intel.com>

Hi,

On Wed, Nov 13, 2013 at 4:09 PM, Oprisenescu, CatalinX
<catalinx.oprisenescu@intel.com> wrote:
> Hello,
>
> Following is an issue encountered and handled using bluez-5.10 on a 32bit Tizen 2.0 IVI based distribution.
>
> If malloc returns a random NULL bluetoothd exits with core dumped.
> In this case we do the following:
>       -start bluetoothd,
>       -at a random malloc call from any library (*lib*.so*), a random NULL will be returned by bluetoothd with a ld_preloaded library.
>
> ~# LD_PRELOAD=/root/lib_wrapper.so /usr/libexec/bluetooth/bluetoothd -E
>
> Analyzing the dump, it points directly to a DBUS_ERROR_NO_MEMORY which, after handling, keeps bluetoothd from dumping and allowing it to return the fatal error occurred as exit status, thus failing gracefully.
>
> A fix proposal, handling the use-case is attached.

Im afraid if we start treating all the out of memory cases we wont
have time to do anything else, and quite frankly if this happens for
real the least concern would be bluetoothd, so I believe we should
just treat OOM cases as unrecoverable. Since this can happen with any
dbus_error, I would probably suggest to wrap it perhaps we a
g_dbus_error API that does assert in OOM.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH 1/2] android: Shutdown if IPC command for unregistered service is received
From: Johan Hedberg @ 2013-11-13 17:50 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1384354033-21724-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Wed, Nov 13, 2013, Szymon Janc wrote:
> Sending commands to not registered services is violation of IPC spec
> and should result in daemon shutdown.
> ---
>  android/main.c | 6 ++++++
>  1 file changed, 6 insertions(+)

Both patches have been applied (with some minor tweaks). Thanks.

Johan

^ permalink raw reply

* Re: Adapter name reset on suspend/resume
From: Marcel Holtmann @ 2013-11-13 23:28 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384350278.5071.6.camel@nuvo>

Hi Bastien,

> After suspending and resuming my laptop, hci0's name is reset to what
> looks like the factory name:
> $ hciconfig -a | grep Name
> 	Name: 'BCM20702A'
> 
> This is the device in question:
> Bus 001 Device 004: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 [ThinkPad]
> 
> And my laptop is a Lenovo X1 Carbon.
> 
> Neither udevadm nor btmon show the device going away on suspend and
> coming back on resume.

can you start btmon, call hciconfig hci0 name, then suspend, then resume, call hciconfig hci0 name again.

I am wondering if for some reason the suspend/resume actually does a HCI Reset without telling us. The name normally only gets reset to BCM20702A when doing a full reset.

Another possibility is that we actually forgot to set it in the first place. I am pretty sure I have intensively tested and that should not happen, but you might just found a corner case.

Regards

Marcel


^ permalink raw reply

* [PATCH] linux-firmware: Update Intel Bluetooth devices firmware patch files
From: Tedd Ho-Jeong An @ 2013-11-14  1:21 UTC (permalink / raw)
  To: dwmw2, ben; +Cc: don.try, tedd.an, linux-bluetooth

From: Tedd Ho-Jeong An <tedd.an@intel.com>

This patch updates firmware patch files for following Intel Bluetooth devices:
- Intel Wireless Bluetooth 7260
- Intel Wireless Bluetooth 3160

This patch fixes
- sometimes device doesn't response to HCI_reset after multiple reboot
- issue with HCI stress testing
- issue with some multi profile cases

Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
---
 WHENCE                                  |   4 ++--
 intel/ibt-hw-37.7.10-fw-1.0.2.3.d.bseq  | Bin 16761 -> 18145 bytes
 intel/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq | Bin 16516 -> 17917 bytes
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/WHENCE b/WHENCE
index 2d52804..b4429ca 100644
--- a/WHENCE
+++ b/WHENCE
@@ -2195,9 +2195,9 @@ Driver: btusb - Bluetooth USB driver
 File: intel/ibt-hw-37.7.bseq
 Version: 1316.02.00
 File: intel/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq
-Version: 1334.02.2E
+Version: 1344.01.33
 File: intel/ibt-hw-37.7.10-fw-1.0.2.3.d.bseq
-Version: 1334.02.2E
+Version: 1344.01.33
 
 Licence: Redistributable. See LICENCE.ibt_firmware for details
 
diff --git a/intel/ibt-hw-37.7.10-fw-1.0.2.3.d.bseq b/intel/ibt-hw-37.7.10-fw-1.0.2.3.d.bseq
index cd23169b8bd7ef8b7bfa2ddaed0c44dc52910ffc..49554882ae6a94e9943d7d69c37f935c814f2aed 100644
GIT binary patch
delta 6475
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
KUs-C+XZ|0#s4+eO

delta 5183
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
WGyt^ZR)v<3%6zKmo%bru)c*tjvYT!I

diff --git a/intel/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq b/intel/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq
index 44736e45b6764b8aa3369ec0a2c18f4657e02ef9..ac13fab3fcc85efe1898f7399eb7b255002cb98a 100644
GIT binary patch
delta 6429
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

delta 5038
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

-- 
1.8.1.2


^ permalink raw reply related

* [PATCH] android/debug: Move debug functions to hal-utils.c
From: Andrei Emeltchenko @ 2013-11-14  7:14 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Debug functions will be used by HALs and haltest.
---
 android/Android.mk        |    2 -
 android/Makefile.am       |    3 -
 android/client/if-av.c    |    1 +
 android/client/if-bt.c    |    1 +
 android/client/if-hf.c    |    1 +
 android/client/if-hh.c    |    1 +
 android/client/if-main.h  |    2 -
 android/client/if-pan.c   |    1 +
 android/client/if-sock.c  |    1 +
 android/client/textconv.c |  300 ---------------------------------------------
 android/client/textconv.h |  120 ------------------
 android/hal-bluetooth.c   |    3 +-
 android/hal-utils.c       |  269 ++++++++++++++++++++++++++++++++++++++++
 android/hal-utils.h       |  103 ++++++++++++++++
 14 files changed, 379 insertions(+), 429 deletions(-)
 delete mode 100644 android/client/textconv.c
 delete mode 100644 android/client/textconv.h

diff --git a/android/Android.mk b/android/Android.mk
index 0bc0e82..53c766b 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -87,7 +87,6 @@ LOCAL_SRC_FILES := \
 	hal-hidhost.c \
 	hal-pan.c \
 	hal-a2dp.c \
-	client/textconv.c \
 	hal-utils.c \
 
 LOCAL_C_INCLUDES += \
@@ -118,7 +117,6 @@ LOCAL_SRC_FILES := \
 	client/pollhandler.c \
 	client/terminal.c \
 	client/history.c \
-	client/textconv.c \
 	client/tabcompletion.c \
 	client/if-av.c \
 	client/if-bt.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index debe7c1..e81d1a5 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -59,7 +59,6 @@ android_haltest_SOURCES = android/client/haltest.c \
 				android/client/pollhandler.c \
 				android/client/terminal.c \
 				android/client/history.c \
-				android/client/textconv.c \
 				android/client/tabcompletion.c \
 				android/client/if-av.c \
 				android/client/if-bt.c \
@@ -102,9 +101,7 @@ EXTRA_DIST += android/client/terminal.c \
 		android/client/if-hh.c \
 		android/client/if-pan.c \
 		android/client/if-sock.c \
-		android/client/textconv.c \
 		android/client/tabcompletion.c \
-		android/client/textconv.h \
 		android/client/if-main.h \
 		android/client/pollhandler.h \
 		android/client/history.h \
diff --git a/android/client/if-av.c b/android/client/if-av.c
index 3f133eb..0470e0d 100644
--- a/android/client/if-av.c
+++ b/android/client/if-av.c
@@ -16,6 +16,7 @@
  */
 
 #include "if-main.h"
+#include "../hal-utils.h"
 
 const btav_interface_t *if_av = NULL;
 
diff --git a/android/client/if-bt.c b/android/client/if-bt.c
index 10ae125..0cd43db 100644
--- a/android/client/if-bt.c
+++ b/android/client/if-bt.c
@@ -17,6 +17,7 @@
 
 #include "if-main.h"
 #include "terminal.h"
+#include "../hal-utils.h"
 
 const bt_interface_t *if_bluetooth;
 
diff --git a/android/client/if-hf.c b/android/client/if-hf.c
index c23fb13..d0e7a66 100644
--- a/android/client/if-hf.c
+++ b/android/client/if-hf.c
@@ -16,6 +16,7 @@
  */
 
 #include "if-main.h"
+#include "../hal-utils.h"
 
 const bthf_interface_t *if_hf = NULL;
 
diff --git a/android/client/if-hh.c b/android/client/if-hh.c
index 005b13a..b8ebc8e 100644
--- a/android/client/if-hh.c
+++ b/android/client/if-hh.c
@@ -23,6 +23,7 @@
 
 #include "if-main.h"
 #include "pollhandler.h"
+#include "../hal-utils.h"
 
 const bthh_interface_t *if_hh = NULL;
 
diff --git a/android/client/if-main.h b/android/client/if-main.h
index dea7237..a83f48b 100644
--- a/android/client/if-main.h
+++ b/android/client/if-main.h
@@ -44,8 +44,6 @@
 #include <hardware/bt_gatt_server.h>
 #endif
 
-#include "textconv.h"
-
 /* Interfaces from hal that can be populated during application lifetime */
 extern const bt_interface_t *if_bluetooth;
 extern const btav_interface_t *if_av;
diff --git a/android/client/if-pan.c b/android/client/if-pan.c
index dcc7e80..a11f2a3 100644
--- a/android/client/if-pan.c
+++ b/android/client/if-pan.c
@@ -18,6 +18,7 @@
 #include <hardware/bluetooth.h>
 
 #include "if-main.h"
+#include "../hal-utils.h"
 
 const btpan_interface_t *if_pan = NULL;
 
diff --git a/android/client/if-sock.c b/android/client/if-sock.c
index dcaf048..2cd06e8 100644
--- a/android/client/if-sock.c
+++ b/android/client/if-sock.c
@@ -21,6 +21,7 @@
 
 #include "if-main.h"
 #include "pollhandler.h"
+#include "../hal-utils.h"
 
 const btsock_interface_t *if_sock = NULL;
 
diff --git a/android/client/textconv.c b/android/client/textconv.c
deleted file mode 100644
index dcbe53e..0000000
--- a/android/client/textconv.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2013 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <hardware/bluetooth.h>
-
-#include "../hal-utils.h"
-
-#include "textconv.h"
-
-/*
- * Following are maps of defines found in bluetooth header files to strings
- *
- * Those mappings are used to accurately use defines as input parameters in
- * command line as well as for printing of statuses
- */
-
-INTMAP(bt_status_t, -1, "(unknown)")
-	DELEMENT(BT_STATUS_SUCCESS),
-	DELEMENT(BT_STATUS_FAIL),
-	DELEMENT(BT_STATUS_NOT_READY),
-	DELEMENT(BT_STATUS_NOMEM),
-	DELEMENT(BT_STATUS_BUSY),
-	DELEMENT(BT_STATUS_DONE),
-	DELEMENT(BT_STATUS_UNSUPPORTED),
-	DELEMENT(BT_STATUS_PARM_INVALID),
-	DELEMENT(BT_STATUS_UNHANDLED),
-	DELEMENT(BT_STATUS_AUTH_FAILURE),
-	DELEMENT(BT_STATUS_RMT_DEV_DOWN),
-ENDMAP
-
-INTMAP(bt_state_t, -1, "(unknown)")
-	DELEMENT(BT_STATE_OFF),
-	DELEMENT(BT_STATE_ON),
-ENDMAP
-
-INTMAP(bt_device_type_t, -1, "(unknown)")
-	DELEMENT(BT_DEVICE_DEVTYPE_BREDR),
-	DELEMENT(BT_DEVICE_DEVTYPE_BLE),
-	DELEMENT(BT_DEVICE_DEVTYPE_DUAL),
-ENDMAP
-
-INTMAP(bt_scan_mode_t, -1, "(unknown)")
-	DELEMENT(BT_SCAN_MODE_NONE),
-	DELEMENT(BT_SCAN_MODE_CONNECTABLE),
-	DELEMENT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE),
-ENDMAP
-
-INTMAP(bt_discovery_state_t, -1, "(unknown)")
-	DELEMENT(BT_DISCOVERY_STOPPED),
-	DELEMENT(BT_DISCOVERY_STARTED),
-ENDMAP
-
-INTMAP(bt_acl_state_t, -1, "(unknown)")
-	DELEMENT(BT_ACL_STATE_CONNECTED),
-	DELEMENT(BT_ACL_STATE_DISCONNECTED),
-ENDMAP
-
-INTMAP(bt_bond_state_t, -1, "(unknown)")
-	DELEMENT(BT_BOND_STATE_NONE),
-	DELEMENT(BT_BOND_STATE_BONDING),
-	DELEMENT(BT_BOND_STATE_BONDED),
-ENDMAP
-
-INTMAP(bt_ssp_variant_t, -1, "(unknown)")
-	DELEMENT(BT_SSP_VARIANT_PASSKEY_CONFIRMATION),
-	DELEMENT(BT_SSP_VARIANT_PASSKEY_ENTRY),
-	DELEMENT(BT_SSP_VARIANT_CONSENT),
-	DELEMENT(BT_SSP_VARIANT_PASSKEY_NOTIFICATION),
-ENDMAP
-
-INTMAP(bt_property_type_t, -1, "(unknown)")
-	DELEMENT(BT_PROPERTY_BDNAME),
-	DELEMENT(BT_PROPERTY_BDADDR),
-	DELEMENT(BT_PROPERTY_UUIDS),
-	DELEMENT(BT_PROPERTY_CLASS_OF_DEVICE),
-	DELEMENT(BT_PROPERTY_TYPE_OF_DEVICE),
-	DELEMENT(BT_PROPERTY_SERVICE_RECORD),
-	DELEMENT(BT_PROPERTY_ADAPTER_SCAN_MODE),
-	DELEMENT(BT_PROPERTY_ADAPTER_BONDED_DEVICES),
-	DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT),
-	DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME),
-	DELEMENT(BT_PROPERTY_REMOTE_RSSI),
-#if PLATFORM_SDK_VERSION > 17
-	DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO),
-#endif
-	DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP),
-ENDMAP
-
-INTMAP(bt_cb_thread_evt, -1, "(unknown)")
-	DELEMENT(ASSOCIATE_JVM),
-	DELEMENT(DISASSOCIATE_JVM),
-ENDMAP
-
-/* Find first index of given value in table m */
-int int2str_findint(int v, const struct int2str m[])
-{
-	int i;
-
-	for (i = 0; m[i].str; ++i) {
-		if (m[i].val == v)
-			return i;
-	}
-	return -1;
-}
-
-/* Find first index of given string in table m */
-int int2str_findstr(const char *str, const struct int2str m[])
-{
-	int i;
-
-	for (i = 0; m[i].str; ++i) {
-		if (strcmp(m[i].str, str) == 0)
-			return i;
-	}
-	return -1;
-}
-
-/*
- * convert bd_addr to string
- * buf must be at least 18 char long
- *
- * returns buf
- */
-const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf)
-{
-	const uint8_t *p = bd_addr->address;
-
-	snprintf(buf, MAX_ADDR_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
-					p[0], p[1], p[2], p[3], p[4], p[5]);
-
-	return buf;
-}
-
-/* converts string to bt_bdaddr_t */
-void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr)
-{
-	uint8_t *p = bd_addr->address;
-
-	sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
-				&p[0], &p[1], &p[2], &p[3], &p[4], &p[5]);
-}
-
-/* converts string to uuid */
-void str2bt_uuid_t(const char *str, bt_uuid_t *uuid)
-{
-	int i = 0;
-
-	memcpy(uuid, BT_BASE_UUID, sizeof(bt_uuid_t));
-
-	while (*str && i < (int) sizeof(bt_uuid_t)) {
-		while (*str == '-')
-			str++;
-
-		if (sscanf(str, "%02hhx", &uuid->uu[i]) != 1)
-			break;
-
-		i++;
-		str += 2;
-	}
-}
-
-const char *enum_defines(void *v, int i)
-{
-	const struct int2str *m = v;
-
-	return m[i].str != NULL ? m[i].str : NULL;
-}
-
-const char *enum_strings(void *v, int i)
-{
-	const char **m = v;
-
-	return m[i] != NULL ? m[i] : NULL;
-}
-
-const char *enum_one_string(void *v, int i)
-{
-	const char *m = v;
-
-	return (i == 0) && (m[0] != 0) ? m : NULL;
-}
-
-const char *bdaddr2str(const bt_bdaddr_t *bd_addr)
-{
-	static char buf[MAX_ADDR_STR_LEN];
-
-	return bt_bdaddr_t2str(bd_addr, buf);
-}
-
-const char *btproperty2str(const bt_property_t *property)
-{
-	static char buf[4096];
-	char *p;
-
-	p = buf + sprintf(buf, "type=%s len=%d val=",
-					bt_property_type_t2str(property->type),
-					property->len);
-
-	switch (property->type) {
-	case BT_PROPERTY_BDNAME:
-	case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
-		snprintf(p, property->len + 1, "%s",
-					((bt_bdname_t *) property->val)->name);
-		break;
-
-	case BT_PROPERTY_BDADDR:
-		sprintf(p, "%s", bdaddr2str((bt_bdaddr_t *) property->val));
-		break;
-
-	case BT_PROPERTY_CLASS_OF_DEVICE:
-		sprintf(p, "%06x", *((int *) property->val));
-		break;
-
-	case BT_PROPERTY_TYPE_OF_DEVICE:
-		sprintf(p, "%s", bt_device_type_t2str(
-				*((bt_device_type_t *) property->val)));
-		break;
-
-	case BT_PROPERTY_REMOTE_RSSI:
-		sprintf(p, "%d", *((char *) property->val));
-		break;
-
-	case BT_PROPERTY_ADAPTER_SCAN_MODE:
-		sprintf(p, "%s",
-			bt_scan_mode_t2str(*((bt_scan_mode_t *) property->val)));
-		break;
-
-	case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
-		sprintf(p, "%d", *((int *) property->val));
-		break;
-
-	case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
-		{
-			int count = property->len / sizeof(bt_bdaddr_t);
-			char *ptr = property->val;
-
-			strcat(p, "{");
-
-			while (count--) {
-				strcat(p, bdaddr2str((bt_bdaddr_t *) ptr));
-				if (count)
-					strcat(p, ", ");
-				ptr += sizeof(bt_bdaddr_t);
-			}
-
-			strcat(p, "}");
-
-		}
-		break;
-
-	case BT_PROPERTY_UUIDS:
-		{
-			int count = property->len / sizeof(bt_uuid_t);
-			uint8_t *ptr = property->val;
-
-			strcat(p, "{");
-
-			while (count--) {
-				strcat(p, btuuid2str(ptr));
-				if (count)
-					strcat(p, ", ");
-				ptr += sizeof(bt_uuid_t);
-			}
-
-			strcat(p, "}");
-
-		}
-		break;
-
-	case BT_PROPERTY_SERVICE_RECORD:
-		{
-			bt_service_record_t *rec = property->val;
-
-			sprintf(p, "{%s, %d, %s}", btuuid2str(rec->uuid.uu),
-						rec->channel, rec->name);
-		}
-		break;
-
-	default:
-		sprintf(p, "%p", property->val);
-	}
-
-	return buf;
-}
diff --git a/android/client/textconv.h b/android/client/textconv.h
deleted file mode 100644
index 0a72805..0000000
--- a/android/client/textconv.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2013 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/**
- * Begin mapping section
- *
- * There are some mappings between integer values (enums) and strings
- * to be presented to user. To make it easier to convert between those two
- * set of macros is given. It is specially useful when we want to have
- * strings that match constants from header files like:
- *  BT_STATUS_SUCCESS (0) and corresponding "BT_STATUS_SUCCESS"
- * Example of usage:
- *
- * INTMAP(int, -1, "invalid")
- *   DELEMENT(BT_STATUS_SUCCESS)
- *   DELEMENT(BT_STATUS_FAIL)
- *   MELEMENT(123, "Some strange value")
- * ENDMAP
- *
- * Just by doing this we have mapping table plus two functions:
- *  int str2int(const char *str);
- *  const char *int2str(int v);
- *
- * second argument to INTMAP specifies value to be returned from
- * str2int function when there is not mapping for such number
- * third argument specifies default value to be returned from int2str
- *
- * If same mapping is to be used in several source files put
- * INTMAP in c file and DECINTMAP in h file.
- *
- * For mappings that are to be used in single file only
- * use SINTMAP which will create the same but everything will be marked
- * as static.
- */
-
-struct int2str {
-	int val;		/* int value */
-	const char *str;	/* corresponding string */
-};
-
-int int2str_findint(int v, const struct int2str m[]);
-int int2str_findstr(const char *str, const struct int2str m[]);
-const char *enum_defines(void *v, int i);
-const char *enum_strings(void *v, int i);
-const char *enum_one_string(void *v, int i);
-
-#define TYPE_ENUM(type) ((void *) &__##type##2str[0])
-#define DECINTMAP(type) \
-extern struct int2str __##type##2str[]; \
-const char *type##2##str(type v); \
-type str##2##type(const char *str); \
-
-#define INTMAP(type, deft, defs) \
-const char *type##2##str(type v) \
-{ \
-	int i = int2str_findint((int) v, __##type##2str); \
-	return (i < 0) ? defs : __##type##2str[i].str; \
-} \
-type str##2##type(const char *str) \
-{ \
-	int i = int2str_findstr(str, __##type##2str); \
-	return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
-} \
-struct int2str __##type##2str[] = {
-
-#define SINTMAP(type, deft, defs) \
-static struct int2str __##type##2str[]; \
-static inline const char *type##2##str(type v) \
-{ \
-	int i = int2str_findint((int) v, __##type##2str); \
-	return (i < 0) ? defs : __##type##2str[i].str; \
-} \
-static inline type str##2##type(const char *str) \
-{ \
-	int i = int2str_findstr(str, __##type##2str); \
-	return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
-} \
-static struct int2str __##type##2str[] = {
-
-#define ENDMAP {0, NULL} };
-
-/* use this to generate string from header file constant */
-#define MELEMENT(v, s) {v, s}
-/* use this to have arbitrary mapping from int to string */
-#define DELEMENT(s) {s, #s}
-/* End of mapping section */
-
-#define MAX_ADDR_STR_LEN 18
-const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf);
-void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr);
-
-void str2bt_uuid_t(const char *str, bt_uuid_t *uuid);
-
-const char *btproperty2str(const bt_property_t *property);
-const char *bdaddr2str(const bt_bdaddr_t *bd_addr);
-
-DECINTMAP(bt_status_t);
-DECINTMAP(bt_state_t);
-DECINTMAP(bt_device_type_t);
-DECINTMAP(bt_scan_mode_t);
-DECINTMAP(bt_discovery_state_t);
-DECINTMAP(bt_acl_state_t);
-DECINTMAP(bt_bond_state_t);
-DECINTMAP(bt_ssp_variant_t);
-DECINTMAP(bt_property_type_t);
-DECINTMAP(bt_cb_thread_evt);
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 1cfd994..078d537 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -24,8 +24,7 @@
 #include "hal.h"
 #include "hal-msg.h"
 #include "hal-ipc.h"
-
-#include "client/textconv.h"
+#include "hal-utils.h"
 
 static const bt_callbacks_t *bt_hal_cbacks = NULL;
 
diff --git a/android/hal-utils.c b/android/hal-utils.c
index 7ac5047..4f44d98 100644
--- a/android/hal-utils.c
+++ b/android/hal-utils.c
@@ -55,3 +55,272 @@ const char *btuuid2str(const uint8_t *uuid)
 
 	return bt_uuid_t2str(uuid, buf);
 }
+
+INTMAP(bt_status_t, -1, "(unknown)")
+	DELEMENT(BT_STATUS_SUCCESS),
+	DELEMENT(BT_STATUS_FAIL),
+	DELEMENT(BT_STATUS_NOT_READY),
+	DELEMENT(BT_STATUS_NOMEM),
+	DELEMENT(BT_STATUS_BUSY),
+	DELEMENT(BT_STATUS_DONE),
+	DELEMENT(BT_STATUS_UNSUPPORTED),
+	DELEMENT(BT_STATUS_PARM_INVALID),
+	DELEMENT(BT_STATUS_UNHANDLED),
+	DELEMENT(BT_STATUS_AUTH_FAILURE),
+	DELEMENT(BT_STATUS_RMT_DEV_DOWN),
+ENDMAP
+
+INTMAP(bt_state_t, -1, "(unknown)")
+	DELEMENT(BT_STATE_OFF),
+	DELEMENT(BT_STATE_ON),
+ENDMAP
+
+INTMAP(bt_device_type_t, -1, "(unknown)")
+	DELEMENT(BT_DEVICE_DEVTYPE_BREDR),
+	DELEMENT(BT_DEVICE_DEVTYPE_BLE),
+	DELEMENT(BT_DEVICE_DEVTYPE_DUAL),
+ENDMAP
+
+INTMAP(bt_scan_mode_t, -1, "(unknown)")
+	DELEMENT(BT_SCAN_MODE_NONE),
+	DELEMENT(BT_SCAN_MODE_CONNECTABLE),
+	DELEMENT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE),
+ENDMAP
+
+INTMAP(bt_discovery_state_t, -1, "(unknown)")
+	DELEMENT(BT_DISCOVERY_STOPPED),
+	DELEMENT(BT_DISCOVERY_STARTED),
+ENDMAP
+
+INTMAP(bt_acl_state_t, -1, "(unknown)")
+	DELEMENT(BT_ACL_STATE_CONNECTED),
+	DELEMENT(BT_ACL_STATE_DISCONNECTED),
+ENDMAP
+
+INTMAP(bt_bond_state_t, -1, "(unknown)")
+	DELEMENT(BT_BOND_STATE_NONE),
+	DELEMENT(BT_BOND_STATE_BONDING),
+	DELEMENT(BT_BOND_STATE_BONDED),
+ENDMAP
+
+INTMAP(bt_ssp_variant_t, -1, "(unknown)")
+	DELEMENT(BT_SSP_VARIANT_PASSKEY_CONFIRMATION),
+	DELEMENT(BT_SSP_VARIANT_PASSKEY_ENTRY),
+	DELEMENT(BT_SSP_VARIANT_CONSENT),
+	DELEMENT(BT_SSP_VARIANT_PASSKEY_NOTIFICATION),
+ENDMAP
+
+INTMAP(bt_property_type_t, -1, "(unknown)")
+	DELEMENT(BT_PROPERTY_BDNAME),
+	DELEMENT(BT_PROPERTY_BDADDR),
+	DELEMENT(BT_PROPERTY_UUIDS),
+	DELEMENT(BT_PROPERTY_CLASS_OF_DEVICE),
+	DELEMENT(BT_PROPERTY_TYPE_OF_DEVICE),
+	DELEMENT(BT_PROPERTY_SERVICE_RECORD),
+	DELEMENT(BT_PROPERTY_ADAPTER_SCAN_MODE),
+	DELEMENT(BT_PROPERTY_ADAPTER_BONDED_DEVICES),
+	DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT),
+	DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME),
+	DELEMENT(BT_PROPERTY_REMOTE_RSSI),
+#if PLATFORM_SDK_VERSION > 17
+	DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO),
+#endif
+	DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP),
+ENDMAP
+
+INTMAP(bt_cb_thread_evt, -1, "(unknown)")
+	DELEMENT(ASSOCIATE_JVM),
+	DELEMENT(DISASSOCIATE_JVM),
+ENDMAP
+
+/* Find first index of given value in table m */
+int int2str_findint(int v, const struct int2str m[])
+{
+	int i;
+
+	for (i = 0; m[i].str; ++i) {
+		if (m[i].val == v)
+			return i;
+	}
+	return -1;
+}
+
+/* Find first index of given string in table m */
+int int2str_findstr(const char *str, const struct int2str m[])
+{
+	int i;
+
+	for (i = 0; m[i].str; ++i) {
+		if (strcmp(m[i].str, str) == 0)
+			return i;
+	}
+	return -1;
+}
+
+/*
+ * convert bd_addr to string
+ * buf must be at least 18 char long
+ *
+ * returns buf
+ */
+const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf)
+{
+	const uint8_t *p = bd_addr->address;
+
+	snprintf(buf, MAX_ADDR_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
+					p[0], p[1], p[2], p[3], p[4], p[5]);
+
+	return buf;
+}
+
+/* converts string to bt_bdaddr_t */
+void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr)
+{
+	uint8_t *p = bd_addr->address;
+
+	sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+				&p[0], &p[1], &p[2], &p[3], &p[4], &p[5]);
+}
+
+/* converts string to uuid */
+void str2bt_uuid_t(const char *str, bt_uuid_t *uuid)
+{
+	int i = 0;
+
+	memcpy(uuid, BT_BASE_UUID, sizeof(bt_uuid_t));
+
+	while (*str && i < (int) sizeof(bt_uuid_t)) {
+		while (*str == '-')
+			str++;
+
+		if (sscanf(str, "%02hhx", &uuid->uu[i]) != 1)
+			break;
+
+		i++;
+		str += 2;
+	}
+}
+
+const char *enum_defines(void *v, int i)
+{
+	const struct int2str *m = v;
+
+	return m[i].str != NULL ? m[i].str : NULL;
+}
+
+const char *enum_strings(void *v, int i)
+{
+	const char **m = v;
+
+	return m[i] != NULL ? m[i] : NULL;
+}
+
+const char *enum_one_string(void *v, int i)
+{
+	const char *m = v;
+
+	return (i == 0) && (m[0] != 0) ? m : NULL;
+}
+
+const char *bdaddr2str(const bt_bdaddr_t *bd_addr)
+{
+	static char buf[MAX_ADDR_STR_LEN];
+
+	return bt_bdaddr_t2str(bd_addr, buf);
+}
+
+const char *btproperty2str(const bt_property_t *property)
+{
+	static char buf[4096];
+	char *p;
+
+	p = buf + sprintf(buf, "type=%s len=%d val=",
+					bt_property_type_t2str(property->type),
+					property->len);
+
+	switch (property->type) {
+	case BT_PROPERTY_BDNAME:
+	case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+		snprintf(p, property->len + 1, "%s",
+					((bt_bdname_t *) property->val)->name);
+		break;
+
+	case BT_PROPERTY_BDADDR:
+		sprintf(p, "%s", bdaddr2str((bt_bdaddr_t *) property->val));
+		break;
+
+	case BT_PROPERTY_CLASS_OF_DEVICE:
+		sprintf(p, "%06x", *((int *) property->val));
+		break;
+
+	case BT_PROPERTY_TYPE_OF_DEVICE:
+		sprintf(p, "%s", bt_device_type_t2str(
+				*((bt_device_type_t *) property->val)));
+		break;
+
+	case BT_PROPERTY_REMOTE_RSSI:
+		sprintf(p, "%d", *((char *) property->val));
+		break;
+
+	case BT_PROPERTY_ADAPTER_SCAN_MODE:
+		sprintf(p, "%s",
+			bt_scan_mode_t2str(*((bt_scan_mode_t *) property->val)));
+		break;
+
+	case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+		sprintf(p, "%d", *((int *) property->val));
+		break;
+
+	case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+		{
+			int count = property->len / sizeof(bt_bdaddr_t);
+			char *ptr = property->val;
+
+			strcat(p, "{");
+
+			while (count--) {
+				strcat(p, bdaddr2str((bt_bdaddr_t *) ptr));
+				if (count)
+					strcat(p, ", ");
+				ptr += sizeof(bt_bdaddr_t);
+			}
+
+			strcat(p, "}");
+
+		}
+		break;
+
+	case BT_PROPERTY_UUIDS:
+		{
+			int count = property->len / sizeof(bt_uuid_t);
+			uint8_t *ptr = property->val;
+
+			strcat(p, "{");
+
+			while (count--) {
+				strcat(p, btuuid2str(ptr));
+				if (count)
+					strcat(p, ", ");
+				ptr += sizeof(bt_uuid_t);
+			}
+
+			strcat(p, "}");
+
+		}
+		break;
+
+	case BT_PROPERTY_SERVICE_RECORD:
+		{
+			bt_service_record_t *rec = property->val;
+
+			sprintf(p, "{%s, %d, %s}", btuuid2str(rec->uuid.uu),
+						rec->channel, rec->name);
+		}
+		break;
+
+	default:
+		sprintf(p, "%p", property->val);
+	}
+
+	return buf;
+}
diff --git a/android/hal-utils.h b/android/hal-utils.h
index 8c74653..75de7e9 100644
--- a/android/hal-utils.h
+++ b/android/hal-utils.h
@@ -15,8 +15,11 @@
  *
  */
 
+#include <hardware/bluetooth.h>
+
 #define MAX_UUID_STR_LEN	37
 #define HAL_UUID_LEN		16
+#define MAX_ADDR_STR_LEN	18
 
 static const char BT_BASE_UUID[] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
@@ -25,3 +28,103 @@ static const char BT_BASE_UUID[] = {
 
 const char *bt_uuid_t2str(const uint8_t *uuid, char *buf);
 const char *btuuid2str(const uint8_t *uuid);
+const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf);
+void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr);
+void str2bt_uuid_t(const char *str, bt_uuid_t *uuid);
+const char *btproperty2str(const bt_property_t *property);
+const char *bdaddr2str(const bt_bdaddr_t *bd_addr);
+
+/**
+ * Begin mapping section
+ *
+ * There are some mappings between integer values (enums) and strings
+ * to be presented to user. To make it easier to convert between those two
+ * set of macros is given. It is specially useful when we want to have
+ * strings that match constants from header files like:
+ *  BT_STATUS_SUCCESS (0) and corresponding "BT_STATUS_SUCCESS"
+ * Example of usage:
+ *
+ * INTMAP(int, -1, "invalid")
+ *   DELEMENT(BT_STATUS_SUCCESS)
+ *   DELEMENT(BT_STATUS_FAIL)
+ *   MELEMENT(123, "Some strange value")
+ * ENDMAP
+ *
+ * Just by doing this we have mapping table plus two functions:
+ *  int str2int(const char *str);
+ *  const char *int2str(int v);
+ *
+ * second argument to INTMAP specifies value to be returned from
+ * str2int function when there is not mapping for such number
+ * third argument specifies default value to be returned from int2str
+ *
+ * If same mapping is to be used in several source files put
+ * INTMAP in c file and DECINTMAP in h file.
+ *
+ * For mappings that are to be used in single file only
+ * use SINTMAP which will create the same but everything will be marked
+ * as static.
+ */
+
+struct int2str {
+	int val;		/* int value */
+	const char *str;	/* corresponding string */
+};
+
+int int2str_findint(int v, const struct int2str m[]);
+int int2str_findstr(const char *str, const struct int2str m[]);
+const char *enum_defines(void *v, int i);
+const char *enum_strings(void *v, int i);
+const char *enum_one_string(void *v, int i);
+
+#define TYPE_ENUM(type) ((void *) &__##type##2str[0])
+#define DECINTMAP(type) \
+extern struct int2str __##type##2str[]; \
+const char *type##2##str(type v); \
+type str##2##type(const char *str); \
+
+#define INTMAP(type, deft, defs) \
+const char *type##2##str(type v) \
+{ \
+	int i = int2str_findint((int) v, __##type##2str); \
+	return (i < 0) ? defs : __##type##2str[i].str; \
+} \
+type str##2##type(const char *str) \
+{ \
+	int i = int2str_findstr(str, __##type##2str); \
+	return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
+} \
+struct int2str __##type##2str[] = {
+
+#define SINTMAP(type, deft, defs) \
+static struct int2str __##type##2str[]; \
+static inline const char *type##2##str(type v) \
+{ \
+	int i = int2str_findint((int) v, __##type##2str); \
+	return (i < 0) ? defs : __##type##2str[i].str; \
+} \
+static inline type str##2##type(const char *str) \
+{ \
+	int i = int2str_findstr(str, __##type##2str); \
+	return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
+} \
+static struct int2str __##type##2str[] = {
+
+#define ENDMAP {0, NULL} };
+
+/* use this to generate string from header file constant */
+#define MELEMENT(v, s) {v, s}
+/* use this to have arbitrary mapping from int to string */
+#define DELEMENT(s) {s, #s}
+/* End of mapping section */
+
+DECINTMAP(bt_status_t);
+DECINTMAP(bt_state_t);
+DECINTMAP(bt_device_type_t);
+DECINTMAP(bt_scan_mode_t);
+DECINTMAP(bt_discovery_state_t);
+DECINTMAP(bt_acl_state_t);
+DECINTMAP(bt_bond_state_t);
+DECINTMAP(bt_ssp_variant_t);
+DECINTMAP(bt_property_type_t);
+DECINTMAP(bt_cb_thread_evt);
-- 
1.7.10.4


^ permalink raw reply related

* Re: bluetoothd failure after a "malloc retun NULL" injection (attachment fix)
From: Marcel Holtmann @ 2013-11-14  7:33 UTC (permalink / raw)
  To: Luiz Augusto von Dentz
  Cc: Oprisenescu, CatalinX, linux-bluetooth@vger.kernel.org,
	Trandafir, IonutX
In-Reply-To: <CABBYNZJSdzsuuzEJctKo_UiKExX4_XXW+zzphhZcHzCuOoLBwg@mail.gmail.com>

Hi Luiz,

>> Following is an issue encountered and handled using bluez-5.10 on a 32bit Tizen 2.0 IVI based distribution.
>> 
>> If malloc returns a random NULL bluetoothd exits with core dumped.
>> In this case we do the following:
>>      -start bluetoothd,
>>      -at a random malloc call from any library (*lib*.so*), a random NULL will be returned by bluetoothd with a ld_preloaded library.
>> 
>> ~# LD_PRELOAD=/root/lib_wrapper.so /usr/libexec/bluetooth/bluetoothd -E
>> 
>> Analyzing the dump, it points directly to a DBUS_ERROR_NO_MEMORY which, after handling, keeps bluetoothd from dumping and allowing it to return the fatal error occurred as exit status, thus failing gracefully.
>> 
>> A fix proposal, handling the use-case is attached.
> 
> Im afraid if we start treating all the out of memory cases we wont
> have time to do anything else, and quite frankly if this happens for
> real the least concern would be bluetoothd, so I believe we should
> just treat OOM cases as unrecoverable. Since this can happen with any
> dbus_error, I would probably suggest to wrap it perhaps we a
> g_dbus_error API that does assert in OOM.

I am fine with fixing obvious ones. However long-term these tiny sized memory allocation must just abort the program if we run out of memory. Since there is no recovery from it anyway.

Regards

Marcel


^ permalink raw reply

* Re: [RFC v4 3/6] Bluetooth: Initial skeleton code for BT 6LoWPAN
From: Marcel Holtmann @ 2013-11-14  7:58 UTC (permalink / raw)
  To: Jukka Rissanen; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384337495-9043-4-git-send-email-jukka.rissanen@linux.intel.com>

Hi Jukka,

> Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
> ---
> include/net/bluetooth/l2cap.h |   1 +
> net/bluetooth/6lowpan.c       | 544 ++++++++++++++++++++++++++++++++++++++++++
> net/bluetooth/6lowpan.h       |  26 ++
> net/bluetooth/Makefile        |   2 +-
> net/bluetooth/l2cap_core.c    |  22 +-
> 5 files changed, 593 insertions(+), 2 deletions(-)
> create mode 100644 net/bluetooth/6lowpan.c
> create mode 100644 net/bluetooth/6lowpan.h
> 
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 5132990..c28ac0d 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -133,6 +133,7 @@ struct l2cap_conninfo {
> #define L2CAP_FC_L2CAP		0x02
> #define L2CAP_FC_CONNLESS	0x04
> #define L2CAP_FC_A2MP		0x08
> +#define L2CAP_FC_6LOWPAN        0x3e

can you add a comment here that 0x3e is the reserved value and temporary. Just to make it clear to everybody looking and using this code.

> /* L2CAP Control Field bit masks */
> #define L2CAP_CTRL_SAR			0xC000
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> new file mode 100644
> index 0000000..85754e2
> --- /dev/null
> +++ b/net/bluetooth/6lowpan.c
> @@ -0,0 +1,544 @@
> +/*
> +   Copyright (c) 2013 Intel Corp.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License version 2 and
> +   only version 2 as published by the Free Software Foundation.
> +
> +   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.
> +*/
> +
> +#include <linux/version.h>
> +#include <linux/bitops.h>
> +#include <linux/if_arp.h>
> +#include <linux/netdevice.h>
> +#include <linux/etherdevice.h>
> +
> +#include <net/ipv6.h>
> +#include <net/ip6_route.h>
> +#include <net/addrconf.h>
> +
> +#include <net/af_ieee802154.h>

What are we using this one for? Just curious.

> +
> +#include <net/bluetooth/bluetooth.h>
> +#include <net/bluetooth/hci_core.h>
> +#include <net/bluetooth/l2cap.h>
> +
> +#include "../ieee802154/6lowpan.h" /* for the compression defines */
> +
> +#define IFACE_NAME_TEMPLATE "bt%d"
> +#define EUI64_ADDR_LEN 8
> +
> +struct skb_cb {
> +	struct in6_addr addr;
> +	struct l2cap_conn *conn;
> +};
> +#define lowpan_cb(skb) ((struct skb_cb *)((skb)->cb))
> +
> +/*
> + * The devices list contains those devices that we are acting
> + * as a proxy. The BT 6LoWPAN device is a virtual device that
> + * connects to the Bluetooth LE device. The real connection to
> + * BT device is done via l2cap layer. There exists one
> + * virtual device / one BT 6LoWPAN network (=hciX device).
> + * The list contains struct lowpan_dev elements.
> + */
> +static LIST_HEAD(bt_6lowpan_devices);
> +static DEFINE_RWLOCK(devices_lock);
> +
> +struct lowpan_dev {
> +	struct net_device *dev;
> +	struct work_struct delete_netdev;
> +	struct list_head list;
> +};
> +
> +struct peer {

Maybe lowpan_peer is a better name. peer sounds a bit too general.

> +	struct list_head list;
> +	struct l2cap_conn *conn;
> +
> +	/* peer addresses in various formats */
> +	unsigned char eui64_addr[EUI64_ADDR_LEN];
> +	struct in6_addr peer_addr;
> +};
> +
> +struct lowpan_info {
> +	struct net_device *net;
> +	struct list_head peers;
> +	int peer_count;

What are we using the peer_count for? Would a kref be useful?

> +};
> +
> +static inline struct lowpan_info *lowpan_info(const struct net_device *dev)
> +{
> +	return netdev_priv(dev);
> +}
> +
> +static inline void peer_add(struct lowpan_info *info, struct peer *peer)
> +{
> +	list_add(&peer->list, &info->peers);
> +	info->peer_count++;
> +}
> +
> +static inline void peer_del(struct lowpan_info *info, struct peer *peer)
> +{
> +	list_del(&peer->list);
> +	info->peer_count--;
> +	if (info->peer_count < 0) {
> +		BT_ERR("peer count underflow");
> +		info->peer_count = 0;
> +	}
> +}
> +
> +static inline struct peer *peer_lookup_ba(struct lowpan_info *info,
> +						__u8 type, bdaddr_t *ba)

You need to get the coding style fixed here. Please make sure you clean these up.

In addition, I think we used the order of BD_ADDR first and then address type. Check what we do in the core and in SMP. I just want to make sure that we do this consistently.

> +{
> +	struct peer *peer, *tmp;
> +
> +	BT_DBG("peers %d addr %pMR type %d", info->peer_count, ba, type);
> +
> +	list_for_each_entry_safe(peer, tmp, &info->peers, list) {
> +		BT_DBG("addr %pMR type %d",
> +			&peer->conn->hcon->dst, peer->conn->hcon->dst_type);
> +
> +		if (!bacmp(&peer->conn->hcon->dst, ba))
> +			return peer;
> +	}
> +
> +	return NULL;
> +}
> +
> +static inline struct peer *peer_lookup_conn(struct lowpan_info *info,
> +						struct l2cap_conn *conn)
> +{
> +	struct peer *peer, *tmp;
> +
> +	list_for_each_entry_safe(peer, tmp, &info->peers, list) {
> +		if (peer->conn == conn)
> +			return peer;
> +	}
> +
> +	return NULL;
> +}
> +
> +static struct peer *lookup_peer(struct l2cap_conn *conn,
> +				struct lowpan_info **dev)
> +{
> +	struct lowpan_dev *entry, *tmp;
> +	struct peer *peer = NULL;
> +
> +	write_lock(&devices_lock);
> +
> +	list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) {
> +		struct lowpan_info *info = lowpan_info(entry->dev);
> +
> +		if (dev)
> +			*dev = info;
> +
> +		peer = peer_lookup_conn(info, conn);
> +		if (peer)
> +			break;

Don’t we want to move the *dev assignment only when we find a match?

> +	}
> +
> +	write_unlock(&devices_lock);
> +
> +	return peer;
> +}
> +
> +/* print data in line */
> +static inline void raw_dump_inline(const char *caller, char *msg,
> +				   unsigned char *buf, int len)
> +{
> +	if (msg)
> +		pr_debug("%s():%s: ", caller, msg);
> +	print_hex_dump_debug("", DUMP_PREFIX_NONE,
> +		       16, 1, buf, len, false);
> +}
> +
> +/*
> + * print data in a table format:
> + *
> + * addr: xx xx xx xx xx xx
> + * addr: xx xx xx xx xx xx
> + * ...
> + */
> +static inline void raw_dump_table(const char *caller, char *msg,
> +				unsigned char *buf, int len)
> +{
> +	if (msg)
> +		pr_debug("%s():%s:\n", caller, msg);
> +	print_hex_dump_debug("\t", DUMP_PREFIX_OFFSET,
> +		       16, 1, buf, len, false);
> +}
> +
> +static int recv_pkt(struct sk_buff *skb, struct net_device *dev)
> +{
> +	kfree_skb(skb);
> +	return NET_RX_DROP;
> +}
> +
> +/* Packet from BT LE device */
> +int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb)
> +{
> +	struct lowpan_info *info = NULL;
> +	struct peer *peer;
> +	int err = -ENOENT;
> +
> +	peer = lookup_peer(conn, &info);
> +	if (!peer)
> +		return -ENOENT;
> +
> +	if (info && info->net) {
> +		err = recv_pkt(skb, info->net, conn);
> +		BT_DBG("recv pkt %d", err);
> +	}

	} else {
		err = -ENOENT;
	}

And remove the assignment at the top.

Can info really be ever NULL?

> +
> +	return err;
> +}
> +
> +static void do_send(struct l2cap_conn *conn, struct sk_buff *skb)
> +{
> +	BT_DBG("conn %p, skb %p len %d priority %u", conn, skb, skb->len,
> +	       skb->priority);
> +
> +	return;

Remove the return here. That is against the coding style.

> +}
> +
> +static int conn_send(struct l2cap_conn *conn,
> +			void *msg, size_t len, u32 priority,
> +			struct net_device *dev)
> +{
> +	struct sk_buff *skb = {0};

No idea how the {0} works here. I am not sure we really should be doing that. Why do we need that? And how do we ensure that not accidentally call a kfree_skb() on it.

> +
> +	do_send(conn, skb);
> +	return 0;
> +}
> +
> +/* Packet to BT LE device */
> +static int send_pkt(struct l2cap_conn *conn, const void *saddr,
> +		const void *daddr, struct sk_buff *skb,
> +		struct net_device *dev)
> +{
> +	raw_dump_table(__func__, "raw skb data dump before fragmentation",
> +				skb->data, skb->len);
> +
> +	return conn_send(conn, skb->data, skb->len, 0, dev);
> +}

Within this patch, I can not really see the point in having 3 function to just do the send. Hope in the final code it makes sense.

> +
> +static int send_mcast_pkt(struct sk_buff *skb, struct net_device *dev)
> +{
> +	struct sk_buff *local_skb;
> +	struct lowpan_dev *entry, *tmp;
> +	int err = 0;
> +
> +	write_lock(&devices_lock);
> +
> +	list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) {
> +		struct peer *pentry, *ptmp;
> +		struct lowpan_info *info;
> +
> +		if (entry->dev != dev)
> +			continue;
> +
> +		info = lowpan_info(entry->dev);
> +
> +		list_for_each_entry_safe(pentry, ptmp, &info->peers, list) {
> +			local_skb = skb_clone(skb, GFP_ATOMIC);
> +
> +			err = send_pkt(pentry->conn, dev->dev_addr,
> +					pentry->eui64_addr,
> +					local_skb, dev);
> +
> +			kfree_skb(local_skb);
> +		}
> +	}
> +
> +	write_unlock(&devices_lock);
> +
> +	return err;
> +}
> +
> +static netdev_tx_t xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> +	int err = -ENOENT;
> +	unsigned char *eui64_addr;
> +	struct lowpan_info *info;
> +	struct peer *peer;
> +	bdaddr_t addr;
> +	u8 addr_type;
> +
> +	if (ipv6_addr_is_multicast(&lowpan_cb(skb)->addr)) {
> +		/*
> +		 * We need to send the packet to every device
> +		 * behind this interface.
> +		 */
> +		err = send_mcast_pkt(skb, dev);
> +	} else {
> +		get_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type);
> +		eui64_addr = lowpan_cb(skb)->addr.s6_addr + 8;
> +		info = lowpan_info(dev);
> +
> +		write_lock(&devices_lock);
> +		peer = peer_lookup_ba(info, addr_type, &addr);
> +		write_unlock(&devices_lock);
> +
> +		BT_DBG("xmit from %s to %pMR (%pI6c), peer %p", dev->name,
> +			&addr, &lowpan_cb(skb)->addr, peer);
> +
> +		if (peer && peer->conn)
> +			err = send_pkt(peer->conn,
> +					dev->dev_addr,
> +					eui64_addr,
> +					skb,
> +					dev);

This breaking looks excessive. Do we need it? Does it not fit on two lines?

> +	}
> +	dev_kfree_skb(skb);
> +
> +	if (err)
> +		BT_DBG("ERROR: xmit failed (%d)", err);
> +
> +	return (err < 0) ? NET_XMIT_DROP : err;
> +}
> +
> +static const struct net_device_ops netdev_ops = {
> +	.ndo_start_xmit		= xmit,
> +};
> +
> +static void netdev_setup(struct net_device *dev)
> +{
> +	dev->addr_len		= EUI64_ADDR_LEN;
> +	dev->type		= ARPHRD_RAWIP;
> +
> +	dev->hard_header_len	= 0;
> +	dev->needed_tailroom	= 0;
> +	dev->mtu		= IPV6_MIN_MTU;
> +	dev->tx_queue_len	= 0;
> +	dev->flags		= IFF_RUNNING | IFF_POINTOPOINT;
> +	dev->watchdog_timeo	= 0;
> +
> +	dev->netdev_ops		= &netdev_ops;
> +	dev->destructor		= free_netdev;
> +}
> +
> +static struct device_type bt_type = {
> +	.name	= "bluetooth",
> +};
> +
> +static void set_addr(u8 *eui, u8 *addr, u8 addr_type)
> +{
> +	/* addr is the BT address in little-endian format */
> +	eui[0] = addr[5];
> +	eui[1] = addr[4];
> +	eui[2] = addr[3];
> +	eui[3] = 0xFF;
> +	eui[4] = 0xFE;
> +	eui[5] = addr[2];
> +	eui[6] = addr[1];
> +	eui[7] = addr[0];
> +
> +	eui[0] ^= 2;
> +
> +	/*
> +	 * Universal/local bit set, RFC 4291
> +	 */
> +	if (addr_type == BDADDR_LE_PUBLIC)
> +		eui[0] |= 1;
> +	else
> +		eui[0] &= ~1;
> +}
> +
> +static void set_dev_addr(struct net_device *net, bdaddr_t *addr,
> +			u8 addr_type)
> +{
> +	net->addr_assign_type = NET_ADDR_PERM;
> +	set_addr(net->dev_addr, addr->b, addr_type);
> +	net->dev_addr[0] ^= 2;
> +}
> +
> +static void ifup(struct net_device *net)
> +{
> +	int err;
> +
> +	rtnl_lock();
> +	err = dev_open(net);
> +	if (err < 0)
> +		BT_INFO("iface %s cannot be opened (%d)", net->name, err);
> +	rtnl_unlock();
> +}
> +
> +/*
> + * This gets called when BT LE 6LoWPAN device is connected. We then
> + * create network device that acts as a proxy between BT LE device
> + * and kernel network stack.
> + */
> +int bt_6lowpan_add_conn(struct l2cap_conn *conn)
> +{
> +	struct lowpan_info *dev = NULL;
> +	struct peer *peer = NULL;
> +	struct net_device *net;
> +	struct lowpan_dev *entry;
> +	int err = 0;
> +
> +	peer = lookup_peer(conn, &dev);
> +	if (peer)
> +		return -EEXIST;
> +
> +	/*
> +	 * If net device exists already, just add route.
> +	 */
> +	if (dev && !peer)
> +		goto add_peer;
> +
> +	net = alloc_netdev(sizeof(struct lowpan_info), IFACE_NAME_TEMPLATE,
> +			netdev_setup);
> +	if (!net)
> +		return -ENOMEM;
> +
> +	dev = netdev_priv(net);
> +	dev->net = net;
> +	INIT_LIST_HEAD(&dev->peers);
> +
> +	set_dev_addr(net, &conn->hcon->src, conn->hcon->src_type);
> +
> +	net->netdev_ops = &netdev_ops;
> +	SET_NETDEV_DEV(net, &conn->hcon->dev);
> +	SET_NETDEV_DEVTYPE(net, &bt_type);
> +
> +	err = register_netdev(net);
> +	if (err < 0) {
> +		BT_INFO("register_netdev failed %d", err);
> +		free_netdev(net);
> +		goto out;
> +	}
> +
> +	BT_DBG("ifindex %d peer bdaddr %pMR my addr %pMR",
> +		net->ifindex, &conn->hcon->dst, &conn->hcon->src);
> +	set_bit(__LINK_STATE_PRESENT, &net->state);
> +
> +	entry = kzalloc(sizeof(struct lowpan_dev), GFP_KERNEL);
> +	if (!entry) {
> +		unregister_netdev(net);
> +		return -ENOMEM;
> +	}
> +
> +	entry->dev = net;
> +
> +	write_lock(&devices_lock);
> +	INIT_LIST_HEAD(&entry->list);
> +	list_add(&entry->list, &bt_6lowpan_devices);
> +	write_unlock(&devices_lock);
> +
> +	ifup(net);
> +
> +add_peer:
> +	peer = kzalloc(sizeof(struct peer), GFP_KERNEL);
> +	if (!peer)
> +		return -ENOMEM;
> +
> +	peer->conn = conn;
> +	memset(&peer->peer_addr, 0, sizeof(struct in6_addr));
> +
> +	/* RFC 2464 ch. 5 */
> +	peer->peer_addr.s6_addr[0] = 0xFE;
> +	peer->peer_addr.s6_addr[1] = 0x80;
> +	set_addr((u8 *)&peer->peer_addr.s6_addr + 8, conn->hcon->dst.b,
> +		conn->hcon->dst_type);
> +
> +	memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8,
> +		EUI64_ADDR_LEN);
> +
> +	write_lock(&devices_lock);
> +	INIT_LIST_HEAD(&peer->list);
> +	peer_add(dev, peer);
> +	write_unlock(&devices_lock);
> +
> +	netdev_notify_peers(dev->net); /* send neighbour adv at startup */
> +
> +out:
> +	return err;
> +}
> +
> +static void delete_netdev(struct work_struct *work)
> +{
> +	struct lowpan_dev *entry = container_of(work, struct lowpan_dev,
> +						delete_netdev);
> +
> +	unregister_netdev(entry->dev);
> +
> +	/* The entry pointer is deleted in device_event() */
> +}
> +
> +int bt_6lowpan_del_conn(struct l2cap_conn *conn)
> +{
> +	struct lowpan_dev *entry, *tmp;
> +	struct lowpan_info *info = NULL;
> +	struct peer *peer;
> +	int err = -ENOENT;
> +
> +	write_lock(&devices_lock);
> +
> +	list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) {
> +		info = lowpan_info(entry->dev);
> +		peer = peer_lookup_conn(info, conn);
> +		if (peer) {
> +			peer_del(info, peer);
> +			err = 0;
> +			break;
> +		}
> +	}
> +
> +	write_unlock(&devices_lock);
> +
> +	if (!err && info && info->peer_count == 0) {
> +		/*
> +		 * This function is called with hci dev lock held which means
> +		 * that we must delete the netdevice in worker thread.
> +		 */
> +		INIT_WORK(&entry->delete_netdev, delete_netdev);
> +		schedule_work(&entry->delete_netdev);
> +	}
> +
> +	return err;
> +}
> +
> +static int device_event(struct notifier_block *unused,
> +				unsigned long event, void *ptr)
> +{
> +	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
> +	struct lowpan_dev *entry, *tmp;
> +
> +	if (dev->type != ARPHRD_RAWIP)
> +		return NOTIFY_DONE;
> +
> +	switch (event) {
> +	case NETDEV_UNREGISTER:
> +		write_lock(&devices_lock);
> +		list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices,
> +					list) {
> +			if (entry->dev == dev) {
> +				list_del(&entry->list);
> +				kfree(entry);
> +				break;
> +			}
> +		}
> +		write_unlock(&devices_lock);
> +		break;
> +	}
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block bt_6lowpan_dev_notifier = {
> +	.notifier_call = device_event,
> +};
> +
> +int bt_6lowpan_init(void)
> +{
> +	return register_netdevice_notifier(&bt_6lowpan_dev_notifier);
> +}
> +
> +void bt_6lowpan_cleanup(void)
> +{
> +	unregister_netdevice_notifier(&bt_6lowpan_dev_notifier);
> +}
> diff --git a/net/bluetooth/6lowpan.h b/net/bluetooth/6lowpan.h
> new file mode 100644
> index 0000000..680eac8
> --- /dev/null
> +++ b/net/bluetooth/6lowpan.h
> @@ -0,0 +1,26 @@
> +/*
> +   Copyright (c) 2013 Intel Corp.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License version 2 and
> +   only version 2 as published by the Free Software Foundation.
> +
> +   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.
> +*/
> +
> +#ifndef __6LOWPAN_H
> +#define __6LOWPAN_H
> +
> +#include <linux/skbuff.h>
> +#include <net/bluetooth/l2cap.h>
> +
> +int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb);
> +int bt_6lowpan_add_conn(struct l2cap_conn *conn);
> +int bt_6lowpan_del_conn(struct l2cap_conn *conn);
> +int bt_6lowpan_init(void);
> +void bt_6lowpan_cleanup(void);
> +
> +#endif /* __6LOWPAN_H */
> diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
> index 6a791e7..80cb215 100644
> --- a/net/bluetooth/Makefile
> +++ b/net/bluetooth/Makefile
> @@ -10,6 +10,6 @@ obj-$(CONFIG_BT_HIDP)	+= hidp/
> 
> bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
> 	hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \
> -	a2mp.o amp.o
> +	a2mp.o amp.o 6lowpan.o
> 
> subdir-ccflags-y += -D__CHECK_ENDIAN__
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index 4af3821..155485f 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -40,6 +40,7 @@
> #include "smp.h"
> #include "a2mp.h"
> #include "amp.h"
> +#include "6lowpan.h"
> 
> bool disable_ertm;
> 
> @@ -6473,6 +6474,10 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
> 			l2cap_conn_del(conn->hcon, EACCES);
> 		break;
> 
> +	case L2CAP_FC_6LOWPAN:
> +		bt_6lowpan_recv(conn, skb);
> +		break;
> +
> 	default:
> 		l2cap_data_channel(conn, cid, skb);
> 		break;
> @@ -6510,6 +6515,11 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
> 	return exact ? lm1 : lm2;
> }
> 
> +static bool is_bt_6lowpan(struct hci_conn *hcon)
> +{
> +	return false;
> +}
> +
> void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
> {
> 	struct l2cap_conn *conn;
> @@ -6518,8 +6528,12 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
> 
> 	if (!status) {
> 		conn = l2cap_conn_add(hcon);
> -		if (conn)
> +		if (conn) {
> 			l2cap_conn_ready(conn);
> +
> +			if (is_bt_6lowpan(hcon))
> +				bt_6lowpan_add_conn(conn);
> +		}

At the end, is this not the only location that checks if 6loWPAN is enabled? I would not bother with the is_bt_6lowpan helper and just do it right away in bt_6lowpan_add_conn.

> 	} else {
> 		l2cap_conn_del(hcon, bt_to_errno(status));
> 	}
> @@ -6540,6 +6554,9 @@ void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
> {
> 	BT_DBG("hcon %p reason %d", hcon, reason);
> 
> +	if (is_bt_6lowpan(hcon))
> +		bt_6lowpan_del_conn(hcon->l2cap_data);
> +

Same here. Do it inside bt_6lowpan_del_conn.

> 	l2cap_conn_del(hcon, bt_to_errno(reason));
> }
> 
> @@ -6817,11 +6834,14 @@ int __init l2cap_init(void)
> 	l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
> 					    NULL, &l2cap_debugfs_fops);
> 
> +	bt_6lowpan_init();
> +
> 	return 0;
> }
> 
> void l2cap_exit(void)
> {
> +	bt_6lowpan_cleanup();
> 	debugfs_remove(l2cap_debugfs);
> 	l2cap_cleanup_sockets();
> }

Regards

Marcel


^ permalink raw reply

* Re: [RFC v4 6/6] Bluetooth: Manually enable or disable 6LoWPAN between devices
From: Marcel Holtmann @ 2013-11-14  8:07 UTC (permalink / raw)
  To: Jukka Rissanen; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384337495-9043-7-git-send-email-jukka.rissanen@linux.intel.com>

Hi Jukka,

> This is a temporary patch where user can manually enable or
> disable BT 6LoWPAN functionality between devices.
> Eventually the connection is established automatically if
> the devices are advertising suitable capability and this patch
> can be removed.
> 
> Before connecting the devices do this
> 
> echo 1 > /sys/kernel/debug/bluetooth/hci0/6lowpan
> 
> This enables 6LoWPAN support and creates the bt0 interface
> automatically when devices are finally connected.
> 
> Rebooting or unloading the bluetooth kernel module will also clear the
> settings from the kernel.
> 
> Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
> ---
> net/bluetooth/6lowpan.c  | 105 +++++++++++++++++++++++++++++++++++++++++++++++
> net/bluetooth/6lowpan.h  |   1 +
> net/bluetooth/hci_core.c |   4 ++
> 3 files changed, 110 insertions(+)
> 
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index 5f0489c..579a75f 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -26,6 +26,8 @@
>  */
> 
> #include <linux/version.h>
> +#include <linux/debugfs.h>
> +#include <linux/string.h>
> #include <linux/bitops.h>
> #include <linux/if_arp.h>
> #include <linux/netdevice.h>
> @@ -1571,6 +1573,109 @@ static struct notifier_block bt_6lowpan_dev_notifier = {
> 	.notifier_call = device_event,
> };
> 
> +static LIST_HEAD(user_enabled);
> +DEFINE_RWLOCK(enabled_lock);

make this one static as well.

> +
> +struct lowpan_enabled {
> +	__u8 dev_name[HCI_MAX_NAME_LENGTH];
> +	bool enabled;
> +	struct list_head list;
> +};
> +
> +static int debugfs_show(struct seq_file *f, void *p)
> +{
> +	struct lowpan_enabled *entry, *tmp;
> +	bool found = false;
> +
> +	write_lock(&enabled_lock);
> +	list_for_each_entry_safe(entry, tmp, &user_enabled, list) {
> +		seq_printf(f, "%d\n", entry->enabled);
> +		found = true;
> +	}
> +	write_unlock(&enabled_lock);
> +
> +	if (!found)
> +		seq_printf(f, "0\n");
> +
> +	return 0;
> +}

So I do not get this one. Why not just use the bit set in hci_dev. This looks like just wrong.

> +
> +static int debugfs_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, debugfs_show, inode->i_private);
> +}
> +
> +static ssize_t writer(struct file *fp, const char __user *user_buffer,
> +		size_t count, loff_t *position)
> +{
> +	struct hci_dev *hdev = fp->f_inode->i_private;
> +	struct lowpan_enabled *entry = NULL, *tmp;
> +	bool new_value, old_value;
> +	char buf[3] = { 0 };
> +	ssize_t ret;
> +
> +	BT_DBG("dev %s count %zd", hdev->dev_name, count);
> +
> +        ret = simple_write_to_buffer(buf, 2, position, user_buffer, count);
> +	if (ret <= 0)
> +		return ret;
> +
> +	if (strtobool(buf, &new_value) < 0)
> +		return -EINVAL;
> +
> +	ret = -ENOENT;
> +
> +	write_lock(&enabled_lock);
> +	list_for_each_entry_safe(entry, tmp, &user_enabled, list) {
> +		if (!strncmp(entry->dev_name, hdev->dev_name,
> +						HCI_MAX_NAME_LENGTH)) {
> +			old_value = entry->enabled;
> +			entry->enabled = new_value;
> +			ret = 0;
> +			break;
> +		}
> +	}
> +	write_unlock(&enabled_lock);
> +
> +	if (ret == 0 && old_value == new_value)
> +		return count;
> +
> +	if (ret < 0) {
> +		entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> +		if (!entry)
> +			return -ENOMEM;
> +
> +		strncpy(entry->dev_name, hdev->dev_name, HCI_MAX_NAME_LENGTH);
> +		entry->enabled = new_value;
> +
> +		write_lock(&enabled_lock);
> +		INIT_LIST_HEAD(&entry->list);
> +		list_add(&entry->list, &user_enabled);
> +		write_unlock(&enabled_lock);
> +	}
> +
> +	if (new_value == true)
> +		set_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags);
> +	else
> +		clear_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags);
> +
> +	return count;
> +}
> +
> +static const struct file_operations ble_6lowpan_debugfs_fops = {
> +	.open		= debugfs_open,
> +	.read		= seq_read,
> +	.write		= writer,
> +	.llseek		= seq_lseek,
> +	.release	= single_release,
> +};
> +
> +void bt_6lowpan_add_debugfs(struct hci_dev *hdev)
> +{
> +	debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
> +			&ble_6lowpan_debugfs_fops);
> +}
> +
> int bt_6lowpan_init(void)
> {
> 	return register_netdevice_notifier(&bt_6lowpan_dev_notifier);
> diff --git a/net/bluetooth/6lowpan.h b/net/bluetooth/6lowpan.h
> index 680eac8..5f60cf2 100644
> --- a/net/bluetooth/6lowpan.h
> +++ b/net/bluetooth/6lowpan.h
> @@ -22,5 +22,6 @@ int bt_6lowpan_add_conn(struct l2cap_conn *conn);
> int bt_6lowpan_del_conn(struct l2cap_conn *conn);
> int bt_6lowpan_init(void);
> void bt_6lowpan_cleanup(void);
> +void bt_6lowpan_add_debugfs(struct hci_dev *hdev);
> 
> #endif /* __6LOWPAN_H */
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 03e8355..a229ce0 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -34,6 +34,8 @@
> #include <net/bluetooth/bluetooth.h>
> #include <net/bluetooth/hci_core.h>
> 
> +#include "6lowpan.h"
> +
> static void hci_rx_work(struct work_struct *work);
> static void hci_cmd_work(struct work_struct *work);
> static void hci_tx_work(struct work_struct *work);
> @@ -1408,6 +1410,8 @@ static int __hci_init(struct hci_dev *hdev)
> 				    hdev, &conn_max_interval_fops);
> 	}
> 
> +	bt_6lowpan_add_debugfs(hdev);
> +

Since we only set the HCI_6LOWPAN_ENABLED bit, why not move this whole code into hci_core.c. It is just setting the bit, right?

Regards

Marcel


^ permalink raw reply

* Re: bluetoothd failure after a "malloc retun NULL" injection (attachment fix)
From: Johan Hedberg @ 2013-11-14  8:19 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Luiz Augusto von Dentz, Oprisenescu, CatalinX,
	linux-bluetooth@vger.kernel.org, Trandafir, IonutX
In-Reply-To: <E03FE70C-ECC4-4D7D-917E-6F3E92297C1C@holtmann.org>

Hi Marcel,

On Thu, Nov 14, 2013, Marcel Holtmann wrote:
> >> Following is an issue encountered and handled using bluez-5.10 on a
> >> 32bit Tizen 2.0 IVI based distribution.
> >> 
> >> If malloc returns a random NULL bluetoothd exits with core dumped.
> >> In this case we do the following:
> >>      -start bluetoothd,
> >>      -at a random malloc call from any library (*lib*.so*), a random NULL will be returned by bluetoothd with a ld_preloaded library.
> >> 
> >> ~# LD_PRELOAD=/root/lib_wrapper.so /usr/libexec/bluetooth/bluetoothd -E
> >> 
> >> Analyzing the dump, it points directly to a DBUS_ERROR_NO_MEMORY
> >> which, after handling, keeps bluetoothd from dumping and allowing
> >> it to return the fatal error occurred as exit status, thus failing
> >> gracefully.
> >> 
> >> A fix proposal, handling the use-case is attached.
> > 
> > Im afraid if we start treating all the out of memory cases we wont
> > have time to do anything else, and quite frankly if this happens for
> > real the least concern would be bluetoothd, so I believe we should
> > just treat OOM cases as unrecoverable. Since this can happen with any
> > dbus_error, I would probably suggest to wrap it perhaps we a
> > g_dbus_error API that does assert in OOM.
> 
> I am fine with fixing obvious ones. However long-term these tiny sized
> memory allocation must just abort the program if we run out of memory.
> Since there is no recovery from it anyway.

Did you actually take a look at the patch? It's not exactly fixing any
missing error checks but only modifying the behavior if the error is OOM
by not doing a g_printerr call in that case. However, the main()
function still does an error() call when connect_dbus() returns failure
(even if it's -ENOMEM) so I don't really see how this particular patch
would fix any obvious OOM handling issue.

Johan

^ permalink raw reply

* Re: [PATCH] Enable autosuspend for Intel Bluetooth device
From: Marcel Holtmann @ 2013-11-14  8:19 UTC (permalink / raw)
  To: Tedd Ho-Jeong An; +Cc: linux-bluetooth@vger.kernel.org development, Don Fry
In-Reply-To: <20131112131641.76cd6c5f@han1-desk-dev>

Hi Tedd,

> This patch enables autosuspend for Intel Bluetooth device.
> 
> After btusb is loaded for Intel Bluetooth device, the power/control
> attribute contains "on" value by default which disables the autosuspend.
> Based on the USB PM document(Documentation/usb/power-management.txt),
> kernel disabled the autosuspend for all devices other than hub by default.
> 
> "The USB specification states that all USB devices must support power
> management.  Nevertheless, the sad fact is that many devices do not
> support it very well.  You can suspend them all right, but when you
> try to resume them they disconnect themselves from the USB bus or
> they stop working entirely.  This seems to be especially prevalent
> among printers and scanners, but plenty of other types of device have
> the same deficiency.
> 
> For this reason, by default the kernel disables autosuspend (the
> power/control attribute is initialized to "on") for all devices other
> than hubs.  Hubs, at least, appear to be reasonably well-behaved in
> this regard."
> 
> This document also described how the driver can enables the autosuspend
> by using an USB api.
> 
> "Drivers can enable autosuspend for their devices by calling
> 
> 	usb_enable_autosuspend(struct usb_device *udev);
> 
> in their probe() routine, if they know that the device is capable of
> suspending and resuming correctly.  This is exactly equivalent to
> writing "auto" to the device's power/control attribute."
> 
> For Intel Bluetooth device, the autosuspend needs to be enabled so the
> device can transit to LPM(Low Power Mode) and ULPM(Ultra LPM) states after
> receiving suspend message from the host.
> 
> Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
> ---
> drivers/bluetooth/btusb.c |    4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH] Bluetooth: Add support for Intel Bluetooth device [8087:0a2a]
From: Marcel Holtmann @ 2013-11-14  8:20 UTC (permalink / raw)
  To: Tedd Ho-Jeong An; +Cc: linux-bluetooth@vger.kernel.org development, Don Fry
In-Reply-To: <20131112131058.6c23affb@han1-desk-dev>

Hi Tedd,

> This patch adds support for new Intel Bluetooth device.
> 
> T:  Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  4 Spd=12   MxCh= 0
> D:  Ver= 2.01 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
> P:  Vendor=8087 ProdID=0a2a Rev= 0.01
> C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
> I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=81(I) Atr=03(Int.) MxPS=  64 Ivl=1ms
> E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
> E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
> I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
> E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
> I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
> E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
> I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
> I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
> I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
> I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
> 
> Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
> ---
> drivers/bluetooth/btusb.c |    1 +
> 1 file changed, 1 insertion(+)

patch has been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH] android/debug: Move debug functions to hal-utils.c
From: Johan Hedberg @ 2013-11-14  9:05 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1384413276-29884-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Thu, Nov 14, 2013, Andrei Emeltchenko wrote:
> Debug functions will be used by HALs and haltest.
> ---
>  android/Android.mk        |    2 -
>  android/Makefile.am       |    3 -
>  android/client/if-av.c    |    1 +
>  android/client/if-bt.c    |    1 +
>  android/client/if-hf.c    |    1 +
>  android/client/if-hh.c    |    1 +
>  android/client/if-main.h  |    2 -
>  android/client/if-pan.c   |    1 +
>  android/client/if-sock.c  |    1 +
>  android/client/textconv.c |  300 ---------------------------------------------
>  android/client/textconv.h |  120 ------------------
>  android/hal-bluetooth.c   |    3 +-
>  android/hal-utils.c       |  269 ++++++++++++++++++++++++++++++++++++++++
>  android/hal-utils.h       |  103 ++++++++++++++++
>  14 files changed, 379 insertions(+), 429 deletions(-)
>  delete mode 100644 android/client/textconv.c
>  delete mode 100644 android/client/textconv.h

Applied. Thanks.

Johan

^ permalink raw reply

* Re: Adapter name reset on suspend/resume
From: Bastien Nocera @ 2013-11-14  9:31 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <130CE89B-A508-4FB9-B7EA-35D500742EC1@holtmann.org>

On Thu, 2013-11-14 at 08:28 +0900, Marcel Holtmann wrote:
> Hi Bastien,
> 
> > After suspending and resuming my laptop, hci0's name is reset to what
> > looks like the factory name:
> > $ hciconfig -a | grep Name
> > 	Name: 'BCM20702A'
> > 
> > This is the device in question:
> > Bus 001 Device 004: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 [ThinkPad]
> > 
> > And my laptop is a Lenovo X1 Carbon.
> > 
> > Neither udevadm nor btmon show the device going away on suspend and
> > coming back on resume.
> 
> can you start btmon, call hciconfig hci0 name, then suspend, then
> resume, call hciconfig hci0 name again.

Bluetooth monitor ver 5.10
= New Index: F4:B7:E2:E8:99:E2 (BR/EDR,USB,hci0)                   [hci0] 0.176335
< HCI Command: Read Local Name (0x03|0x0014) plen 0                [hci0] 9.797930
> HCI Event: Command Complete (0x0e) plen 252                      [hci0] 9.813834
      Read Local Name (0x03|0x0014) ncmd 1
        Status: Success (0x00)
        Name: nuvo
< HCI Command: Read Local Name (0x03|0x0014) plen 0               [hci0] 33.109166
> HCI Event: Command Complete (0x0e) plen 252                     [hci0] 33.125157
      Read Local Name (0x03|0x0014) ncmd 1
        Status: Success (0x00)
        Name: BCM20702A

> I am wondering if for some reason the suspend/resume actually does a
> HCI Reset without telling us. The name normally only gets reset to
> BCM20702A when doing a full reset.

Looks like that's what it's doing.

> Another possibility is that we actually forgot to set it in the first
> place. I am pretty sure I have intensively tested and that should not
> happen, but you might just found a corner case.

It's set on a normal boot, it seems to be reset only when suspending.

Cheers

^ permalink raw reply

* Re: bluetoothd failure after a "malloc retun NULL" injection (attachment fix)
From: Luiz Augusto von Dentz @ 2013-11-14  9:37 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Oprisenescu, CatalinX,
	linux-bluetooth@vger.kernel.org, Trandafir, IonutX
In-Reply-To: <20131114081937.GA2019@x220.p-661hnu-f1>

Hi Johan,

On Thu, Nov 14, 2013 at 10:19 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Marcel,
>
> On Thu, Nov 14, 2013, Marcel Holtmann wrote:
>> >> Following is an issue encountered and handled using bluez-5.10 on a
>> >> 32bit Tizen 2.0 IVI based distribution.
>> >>
>> >> If malloc returns a random NULL bluetoothd exits with core dumped.
>> >> In this case we do the following:
>> >>      -start bluetoothd,
>> >>      -at a random malloc call from any library (*lib*.so*), a random NULL will be returned by bluetoothd with a ld_preloaded library.
>> >>
>> >> ~# LD_PRELOAD=/root/lib_wrapper.so /usr/libexec/bluetooth/bluetoothd -E
>> >>
>> >> Analyzing the dump, it points directly to a DBUS_ERROR_NO_MEMORY
>> >> which, after handling, keeps bluetoothd from dumping and allowing
>> >> it to return the fatal error occurred as exit status, thus failing
>> >> gracefully.
>> >>
>> >> A fix proposal, handling the use-case is attached.
>> >
>> > Im afraid if we start treating all the out of memory cases we wont
>> > have time to do anything else, and quite frankly if this happens for
>> > real the least concern would be bluetoothd, so I believe we should
>> > just treat OOM cases as unrecoverable. Since this can happen with any
>> > dbus_error, I would probably suggest to wrap it perhaps we a
>> > g_dbus_error API that does assert in OOM.
>>
>> I am fine with fixing obvious ones. However long-term these tiny sized
>> memory allocation must just abort the program if we run out of memory.
>> Since there is no recovery from it anyway.
>
> Did you actually take a look at the patch? It's not exactly fixing any
> missing error checks but only modifying the behavior if the error is OOM
> by not doing a g_printerr call in that case. However, the main()
> function still does an error() call when connect_dbus() returns failure
> (even if it's -ENOMEM) so I don't really see how this particular patch
> would fix any obvious OOM handling issue.

Yep, I was thinking more in the following:

diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 9542109..ced55d9 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -216,6 +216,7 @@ struct GDBusSecurityTable {
        .flags = G_DBUS_SIGNAL_FLAG_EXPERIMENTAL

 void g_dbus_set_flags(int flags);
+gboolean g_dbus_error_is_set(DBusError *err);

 gboolean g_dbus_register_interface(DBusConnection *connection,
                                        const char *path, const char *name,
diff --git a/gdbus/object.c b/gdbus/object.c
index b248cbb..699c7e2 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -27,6 +27,7 @@

 #include <stdio.h>
 #include <string.h>
+#include <assert.h>

 #include <glib.h>
 #include <dbus/dbus.h>
@@ -1820,3 +1821,16 @@ void g_dbus_set_flags(int flags)
 {
        global_flags = flags;
 }
+
+gboolean g_dbus_error_is_set(DBusError *err)
+{
+       dbus_bool_t ret;
+
+       ret = dbus_error_is_set(err);
+       if (!ret)
+               return FALSE;
+
+       assert(!dbus_error_has_name(err, DBUS_ERROR_NO_MEMORY));
+
+       return TRUE;
+}

But perhaps there is a way to set libdbus to not handle OOM cases and
just assert/exit, the interesting part is that even in dbus code
itself there are comments like this:

     /* FIXME have less lame handling for OOM, we just silently fail to
      * watch.  (In reality though, the whole OOM handling in dbus is
      * stupid but we won't go into that in this comment =) )
      */


-- 
Luiz Augusto von Dentz

^ permalink raw reply related

* [PATCH BlueZ 1/7] android/hal-a2dp: Use conn_state instead of connection_state
From: Luiz Augusto von Dentz @ 2013-11-14 10:18 UTC (permalink / raw)
  To: linux-bluetooth

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

This is shorter and more consistent with other HAL such as HID.
---
 android/hal-a2dp.c | 8 ++++----
 android/hal-msg.h  | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/android/hal-a2dp.c b/android/hal-a2dp.c
index 4fe7c20..cdb5229 100644
--- a/android/hal-a2dp.c
+++ b/android/hal-a2dp.c
@@ -31,9 +31,9 @@ static bool interface_ready(void)
 	return cbs != NULL;
 }
 
-static void handle_connection_state(void *buf)
+static void handle_conn_state(void *buf)
 {
-	struct hal_ev_a2dp_connection_state *ev = buf;
+	struct hal_ev_a2dp_conn_state *ev = buf;
 
 	if (cbs->connection_state_cb)
 		cbs->connection_state_cb(ev->state,
@@ -55,8 +55,8 @@ void bt_notify_a2dp(uint8_t opcode, void *buf, uint16_t len)
 		return;
 
 	switch (opcode) {
-	case HAL_EV_A2DP_CONNECTION_STATE:
-		handle_connection_state(buf);
+	case HAL_EV_A2DP_CONN_STATE:
+		handle_conn_state(buf);
 		break;
 	case HAL_EV_A2DP_AUDIO_STATE:
 		handle_audio_state(buf);
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 847cc1f..30fe624 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -530,13 +530,13 @@ struct hal_ev_pan_conn_state {
 	uint8_t  remote_role;
 } __attribute__((packed));
 
-#define HAL_EV_A2DP_CONNECTION_STATE	0x81
-struct hal_ev_a2dp_connection_state {
+#define HAL_EV_A2DP_CONN_STATE			0x81
+struct hal_ev_a2dp_conn_state {
 	uint8_t state;
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_EV_A2DP_AUDIO_STATE	0x82
+#define HAL_EV_A2DP_AUDIO_STATE			0x82
 struct hal_ev_a2dp_audio_state {
 	uint8_t state;
 	uint8_t bdaddr[6];
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 2/7] android/hal-a2dp: Add implemention of .init
From: Luiz Augusto von Dentz @ 2013-11-14 10:18 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384424301-31265-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/hal-a2dp.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/android/hal-a2dp.c b/android/hal-a2dp.c
index cdb5229..50a36fb 100644
--- a/android/hal-a2dp.c
+++ b/android/hal-a2dp.c
@@ -99,13 +99,16 @@ static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
 
 static bt_status_t init(btav_callbacks_t *callbacks)
 {
+	struct hal_cmd_register_module cmd;
+
 	DBG("");
 
 	cbs = callbacks;
 
-	/* TODO: enable service */
+	cmd.service_id = HAL_SERVICE_ID_A2DP;
 
-	return BT_STATUS_SUCCESS;
+	return hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
+					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static void cleanup()
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 3/7] android/hal-a2dp: Add implemention of .cleanup
From: Luiz Augusto von Dentz @ 2013-11-14 10:18 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384424301-31265-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/hal-a2dp.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/android/hal-a2dp.c b/android/hal-a2dp.c
index 50a36fb..e9fadb7 100644
--- a/android/hal-a2dp.c
+++ b/android/hal-a2dp.c
@@ -113,14 +113,19 @@ static bt_status_t init(btav_callbacks_t *callbacks)
 
 static void cleanup()
 {
+	struct hal_cmd_unregister_module cmd;
+
 	DBG("");
 
 	if (!interface_ready())
 		return;
 
-	/* TODO: disable service */
-
 	cbs = NULL;
+
+	cmd.service_id = HAL_SERVICE_ID_A2DP;
+
+	hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
+					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static btav_interface_t iface = {
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 4/7] android/hal-a2dp: Add defines for possible connection states
From: Luiz Augusto von Dentz @ 2013-11-14 10:18 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384424301-31265-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/hal-msg.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 30fe624..44fd5c8 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -530,6 +530,11 @@ struct hal_ev_pan_conn_state {
 	uint8_t  remote_role;
 } __attribute__((packed));
 
+#define HAL_A2DP_STATE_DISCONNECTED		0x00
+#define HAL_A2DP_STATE_CONNECTING		0x01
+#define HAL_A2DP_STATE_CONNECTED		0x02
+#define HAL_A2DP_STATE_DISCONNECTING		0x03
+
 #define HAL_EV_A2DP_CONN_STATE			0x81
 struct hal_ev_a2dp_conn_state {
 	uint8_t state;
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 5/7] android/a2dp: Add initial implementation of socket handling
From: Luiz Augusto von Dentz @ 2013-11-14 10:18 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384424301-31265-1-git-send-email-luiz.dentz@gmail.com>

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

This adds initial code to handle incoming connection and notifying
connection states.
---
 android/a2dp.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index 052f4f3..5ffb8ae 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -32,13 +32,77 @@
 #include <fcntl.h>
 #include <glib.h>
 
+#include "btio/btio.h"
 #include "lib/bluetooth.h"
 #include "log.h"
 #include "a2dp.h"
 #include "hal-msg.h"
 #include "ipc.h"
+#include "utils.h"
+
+#define L2CAP_PSM_AVDTP 0x19
 
 static int notification_sk = -1;
+static GIOChannel *io = NULL;
+static GSList *devices = NULL;
+
+struct a2dp_device {
+	bdaddr_t	dst;
+	uint8_t		state;
+	GIOChannel	*io;
+	guint		watch;
+};
+
+static int device_cmp(gconstpointer s, gconstpointer user_data)
+{
+	const struct a2dp_device *dev = s;
+	const bdaddr_t *dst = user_data;
+
+	return bacmp(&dev->dst, dst);
+}
+
+static void a2dp_device_free(struct a2dp_device *dev)
+{
+	if (dev->watch > 0)
+		g_source_remove(dev->watch);
+
+	if (dev->io)
+		g_io_channel_unref(dev->io);
+
+	devices = g_slist_remove(devices, dev);
+	g_free(dev);
+}
+
+static struct a2dp_device *a2dp_device_new(const bdaddr_t *dst)
+{
+	struct a2dp_device *dev;
+
+	dev = g_new0(struct a2dp_device, 1);
+	bacpy(&dev->dst, dst);
+	devices = g_slist_prepend(devices, dev);
+
+	return dev;
+}
+
+static void bt_a2dp_notify_state(struct a2dp_device *dev, uint8_t state)
+{
+	struct hal_ev_a2dp_conn_state ev;
+	char address[18];
+
+	if (dev->state == state)
+		return;
+
+	dev->state = state;
+
+	ba2str(&dev->dst, address);
+	DBG("device %s state %u", address, state);
+
+	bdaddr2android(&dev->dst, ev.bdaddr);
+	ev.state = state;
+
+	ipc_send(notification_sk, HAL_SERVICE_ID_A2DP,
+			HAL_EV_A2DP_CONN_STATE, sizeof(ev), &ev, -1);
+}
 
 static uint8_t bt_a2dp_connect(struct hal_cmd_a2dp_connect *cmd, uint16_t len)
 {
@@ -74,10 +138,72 @@ void bt_a2dp_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
 	ipc_send_rsp(sk, HAL_SERVICE_ID_A2DP, status);
 }
 
+static gboolean watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
+{
+	struct a2dp_device *dev = data;
+
+	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+
+	a2dp_device_free(dev);
+
+	return FALSE;
+}
+
+static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
+{
+	struct a2dp_device *dev;
+	bdaddr_t src, dst;
+	char address[18];
+	GError *gerr = NULL;
+	GSList *l;
+
+	if (err) {
+		error("%s", err->message);
+		return;
+	}
+
+	bt_io_get(chan, &gerr,
+			BT_IO_OPT_SOURCE_BDADDR, &src,
+			BT_IO_OPT_DEST_BDADDR, &dst,
+			BT_IO_OPT_INVALID);
+	if (gerr) {
+		error("%s", gerr->message);
+		g_error_free(gerr);
+		g_io_channel_shutdown(chan, TRUE, NULL);
+		return;
+	}
+
+	l = g_slist_find_custom(devices, &dst, device_cmp);
+	if (l)
+		return;
+
+	ba2str(&dst, address);
+	DBG("Incoming connection from %s", address);
+
+	dev = a2dp_device_new(&dst);
+	dev->watch = g_io_add_watch(dev->io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+								watch_cb, dev);
+
+	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTED);
+}
+
 bool bt_a2dp_register(int sk, const bdaddr_t *addr)
 {
+	GError *err = NULL;
+
 	DBG("");
 
+	io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, addr,
+				BT_IO_OPT_PSM, L2CAP_PSM_AVDTP,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+				BT_IO_OPT_INVALID);
+	if (!io) {
+		error("Failed to listen on AVDTP channel: %s", err->message);
+		g_error_free(err);
+		return false;
+	}
+
 	notification_sk = sk;
 
 	return true;
@@ -88,4 +214,10 @@ void bt_a2dp_unregister(void)
 	DBG("");
 
 	notification_sk = -1;
+
+	if (io) {
+		g_io_channel_shutdown(io, TRUE, NULL);
+		g_io_channel_unref(io);
+		io = NULL;
+	}
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 6/7] android/a2dp: Add initial implementation of HAL_OP_A2DP_CONNECT
From: Luiz Augusto von Dentz @ 2013-11-14 10:18 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384424301-31265-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 71 insertions(+), 18 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 5ffb8ae..adbad05 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -45,6 +45,7 @@
 static int notification_sk = -1;
 static GIOChannel *io = NULL;
 static GSList *devices = NULL;
+static const bdaddr_t *adapter_addr = NULL;
 
 struct a2dp_device {
 	bdaddr_t	dst;
@@ -104,11 +105,74 @@ static void bt_a2dp_notify_state(struct a2dp_device *dev, uint8_t state)
 			HAL_EV_A2DP_CONN_STATE, sizeof(ev), &ev, -1);
 }
 
+static gboolean watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
+{
+	struct a2dp_device *dev = data;
+
+	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+
+	a2dp_device_free(dev);
+
+	return FALSE;
+}
+
+static void signaling_connect_cb(GIOChannel *chan, GError *err,
+							gpointer user_data)
+{
+	struct a2dp_device *dev = user_data;
+
+	if (err) {
+		bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+		error("%s", err->message);
+		a2dp_device_free(dev);
+		return;
+	}
+
+	dev->watch = g_io_add_watch(dev->io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+								watch_cb, dev);
+
+	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTED);
+}
+
 static uint8_t bt_a2dp_connect(struct hal_cmd_a2dp_connect *cmd, uint16_t len)
 {
-	DBG("Not Implemented");
+	struct a2dp_device *dev;
+	char addr[18];
+	bdaddr_t dst;
+	GSList *l;
+	GError *err = NULL;
 
-	return HAL_STATUS_FAILED;
+	DBG("");
+
+	if (len < sizeof(*cmd))
+		return HAL_STATUS_INVALID;
+
+	android2bdaddr(&cmd->bdaddr, &dst);
+
+	l = g_slist_find_custom(devices, &dst, device_cmp);
+	if (l)
+		return HAL_STATUS_FAILED;
+
+	dev = a2dp_device_new(&dst);
+	dev->io = bt_io_connect(signaling_connect_cb, dev, NULL, &err,
+					BT_IO_OPT_SOURCE_BDADDR, adapter_addr,
+					BT_IO_OPT_DEST_BDADDR, &dev->dst,
+					BT_IO_OPT_PSM, L2CAP_PSM_AVDTP,
+					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+					BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", err->message);
+		g_error_free(err);
+		a2dp_device_free(dev);
+		return HAL_STATUS_FAILED;
+	}
+
+	ba2str(&dev->dst, addr);
+	DBG("connecting to %s", addr);
+
+	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTING);
+
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t bt_a2dp_disconnect(struct hal_cmd_a2dp_connect *cmd,
@@ -138,17 +202,6 @@ void bt_a2dp_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
 	ipc_send_rsp(sk, HAL_SERVICE_ID_A2DP, status);
 }
 
-static gboolean watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
-{
-	struct a2dp_device *dev = data;
-
-	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
-
-	a2dp_device_free(dev);
-
-	return FALSE;
-}
-
 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	struct a2dp_device *dev;
@@ -181,10 +234,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	DBG("Incoming connection from %s", address);
 
 	dev = a2dp_device_new(&dst);
-	dev->watch = g_io_add_watch(dev->io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-								watch_cb, dev);
-
-	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTED);
+	signaling_connect_cb(chan, err, dev);
 }
 
 bool bt_a2dp_register(int sk, const bdaddr_t *addr)
@@ -193,8 +243,10 @@ bool bt_a2dp_register(int sk, const bdaddr_t *addr)
 
 	DBG("");
 
+	adapter_addr = addr;
+
 	io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, addr,
+				BT_IO_OPT_SOURCE_BDADDR, adapter_addr,
 				BT_IO_OPT_PSM, L2CAP_PSM_AVDTP,
 				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
 				BT_IO_OPT_INVALID);
@@ -213,6 +265,7 @@ void bt_a2dp_unregister(void)
 {
 	DBG("");
 
+	adapter_addr = NULL;
 	notification_sk = -1;
 
 	if (io) {
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 7/7] android/a2dp: Add initial implementation of HAL_OP_A2DP_DISCONNECT
From: Luiz Augusto von Dentz @ 2013-11-14 10:18 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384424301-31265-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index adbad05..6d2f8a3 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -178,9 +178,30 @@ static uint8_t bt_a2dp_connect(struct hal_cmd_a2dp_connect *cmd, uint16_t len)
 static uint8_t bt_a2dp_disconnect(struct hal_cmd_a2dp_connect *cmd,
 								uint16_t len)
 {
-	DBG("Not Implemented");
+	struct a2dp_device *dev;
+	GSList *l;
+	bdaddr_t dst;
+
+	DBG("");
+
+	if (len < sizeof(*cmd))
+		return HAL_STATUS_INVALID;
+
+	android2bdaddr(&cmd->bdaddr, &dst);
+
+	l = g_slist_find_custom(devices, &dst, device_cmp);
+	if (!l)
+		return HAL_STATUS_FAILED;
+
+	dev = l->data;
 
-	return HAL_STATUS_FAILED;
+	/* Wait signaling channel to HUP */
+	if (dev->io)
+		g_io_channel_shutdown(dev->io, TRUE, NULL);
+
+	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTING);
+
+	return HAL_STATUS_SUCCESS;
 }
 
 void bt_a2dp_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
-- 
1.8.3.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