Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH v3] android: Fix build error for Android
From: Johan Hedberg @ 2013-10-23 12:59 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth, szymon.janc, andrei.emeltchenko
In-Reply-To: <1382532559-25830-1-git-send-email-lukasz.rymanowski@tieto.com>

Hi Lukasz,

On Wed, Oct 23, 2013, Lukasz Rymanowski wrote:
> Android uses functions and defines from sys/capability.h which
> requires additional include. However file capability.h shows up
> in bionic in version Android 4.3, therefore we do check
> PLATFORM_SDK_VERSION to no break builds of previous Android versions.
> In previous Android version unistd.h contain this functionality.
> ---
>  android/Android.mk | 3 ++-
>  android/main.c     | 6 ++++++
>  2 files changed, 8 insertions(+), 1 deletion(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] android: Make use of Android system headers instead of local one
From: Johan Hedberg @ 2013-10-23 12:59 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1382532281-5445-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Wed, Oct 23, 2013, Andrei Emeltchenko wrote:
> Since the headers were copied to android/ folder Android build started
> to use those instead of original Android system headers. The patch
> puts Android system headers first.
> ---
>  android/Android.mk | 3 +++
>  1 file changed, 3 insertions(+)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] android: Make use of Android system headers instead of local one
From: Szymon Janc @ 2013-10-23 12:54 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1382532281-5445-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi,

On Wednesday 23 of October 2013 15:44:41 Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> Since the headers were copied to android/ folder Android build started
> to use those instead of original Android system headers. The patch
> puts Android system headers first.
> ---
>  android/Android.mk | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/android/Android.mk b/android/Android.mk
> index 3163763..0640842 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -71,6 +71,9 @@ LOCAL_SRC_FILES := \
>  	hal-pan.c \
>  	hal-av.c \
>  
> +LOCAL_C_INCLUDES += \
> +	system/core/include \
> +

We could use include-path-for to not hardcode path to core
LOCAL_C_INCLUDES += $(call include-path-for, system-core)

>  LOCAL_SHARED_LIBRARIES := \
>  	libcutils \
>  
> 


-- 
BR
Szymon Janc

^ permalink raw reply

* [PATCH] android: Fix compilation error
From: Andrei Emeltchenko @ 2013-10-23 12:53 UTC (permalink / raw)
  To: linux-bluetooth

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

The patch fixes errors with undefined symbols EXIT_FAILURE on Android.
---
 android/hal-ipc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 2d58038..1e32774 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -24,6 +24,7 @@
 #include <poll.h>
 #include <unistd.h>
 #include <stdint.h>
+#include <stdlib.h>
 
 #include <cutils/properties.h>
 
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH v3] android: Fix build error for Android
From: Lukasz Rymanowski @ 2013-10-23 12:49 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, andrei.emeltchenko, johan.hedberg, Lukasz Rymanowski

Android uses functions and defines from sys/capability.h which
requires additional include. However file capability.h shows up
in bionic in version Android 4.3, therefore we do check
PLATFORM_SDK_VERSION to no break builds of previous Android versions.
In previous Android version unistd.h contain this functionality.
---
 android/Android.mk | 3 ++-
 android/main.c     | 6 ++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/android/Android.mk b/android/Android.mk
index c4b0621..a569650 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -36,7 +36,8 @@ LOCAL_C_INCLUDES += \
 	$(LOCAL_PATH)/../src \
 	$(LOCAL_PATH)/../lib \
 
-LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
+LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\" \
+	-DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION)
 
 LOCAL_SHARED_LIBRARIES := \
 	libglib \
diff --git a/android/main.c b/android/main.c
index 988d08b..5a85f74 100644
--- a/android/main.c
+++ b/android/main.c
@@ -52,6 +52,12 @@
 #include "hal-msg.h"
 #include "ipc.h"
 
+/* TODO: Consider to remove PLATFORM_SDKVERSION check if requirement
+*  for minimal Android platform version increases. */
+#if defined(ANDROID) && PLATFORM_SDK_VERSION >= 18
+#include <sys/capability.h>
+#endif
+
 static GMainLoop *event_loop;
 static struct mgmt *mgmt_if = NULL;
 
-- 
1.8.4


^ permalink raw reply related

* [PATCH] android: Make use of Android system headers instead of local one
From: Andrei Emeltchenko @ 2013-10-23 12:44 UTC (permalink / raw)
  To: linux-bluetooth

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

Since the headers were copied to android/ folder Android build started
to use those instead of original Android system headers. The patch
puts Android system headers first.
---
 android/Android.mk | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index 3163763..0640842 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -71,6 +71,9 @@ LOCAL_SRC_FILES := \
 	hal-pan.c \
 	hal-av.c \
 
+LOCAL_C_INCLUDES += \
+	system/core/include \
+
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
 
-- 
1.8.1.2


^ permalink raw reply related

* Re: [RFC 3/5] route: Exporting ip6_route_add() so that BLE 6LoWPAN can use it
From: Jukka Rissanen @ 2013-10-23 12:41 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <30925AE8-AE7B-43D9-9E5D-4898C0CF8390@holtmann.org>

Hi Marcel,

On 23.10.2013 15:00, Marcel Holtmann wrote:
> Hi Jukka,
>
>> net/ipv6/route.c | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
>> index c979dd9..d7c200f 100644
>> --- a/net/ipv6/route.c
>> +++ b/net/ipv6/route.c
>> @@ -1662,6 +1662,7 @@ out:
>> 		dst_free(&rt->dst);
>> 	return err;
>> }
>> +EXPORT_SYMBOL_GPL(ip6_route_add);
>
> check with netdev is this is something that would be accepted upstream.

We could also tell userspace (bluez or connman) to create the route if 
needed.

>
> For the time being, can we work around this internally for testing? I like to just build and load a new Bluetooth module for testing and not have to replace IPv6 as well.

Sure, just do

ip -6 route add <peer>

after connecting the devices.

The peer link local address is perhaps easiest to get by using online 
calculator like http://ben.akrin.com/?p=1347



-- 
Cheers,
Jukka

^ permalink raw reply

* Re: [RFC 5/5] Bluetooth: Manually enable or disable 6LoWPAN between devices
From: Marcel Holtmann @ 2013-10-23 12:09 UTC (permalink / raw)
  To: Jukka Rissanen; +Cc: linux-bluetooth
In-Reply-To: <1382511164-1989-6-git-send-email-jukka.rissanen@linux.intel.com>

Hi Jukka,

> This is a temporary patch where user can manually enable or
> disable BT LE 6LoWPAN functionality between devices.
> Eventually the connection is established automatically if
> the devices are advertising suitable capability and this patch
> can be removed.
> 
> If you have two devices with these BT addresses
>        device1  00:11:22:33:44:55
>        device2  66:77:88:99:00:11
> 
> First add the desired devices manually into kernel
> 
> root@dev1# echo 66:77:88:99:00:11 > /sys/kernel/debug/bluetooth/hci0/ble6lowpan
> root@dev2# echo 00:11:22:33:44:55 > /sys/kernel/debug/bluetooth/hci0/ble6lowpan
> 
> then connect the devices
> 
> root@dev1# hciconfig hci0 leadv
> root@dev2# hcitool lecc 00:11:22:33:44:55
> 
> if the connection is established, then you can send IPv6 packets
> between these two systems using the link local addresses
> 
> root@dev1# ping6 fe80::6477:88ff:fe99:0011
> root@dev2# ping6 fe80::211:22ff:fe33:4455
> 
> By default 6LoWPAN connection is not established between devices,
> so you need to add the MAC addresses manually into the
> /sys/kernel/debug/bluetooth/hci0/ble6lowpan file.
> If you want to prevent further connections you can remove
> MAC address from the debugfs file like this
> echo "00:11:22:33:44:55 d" > /sys/kernel/debug/bluetooth/hci0/ble6lowpan
> Rebooting or unloading the bluetooth kernel module will also clear the
> settings from the kernel.
> ---
> net/bluetooth/ble_6lowpan.c | 164 ++++++++++++++++++++++++++++++++++++++++++++
> net/bluetooth/ble_6lowpan.h |   1 +
> net/bluetooth/hci_core.c    |   4 ++
> net/bluetooth/l2cap_core.c  |  12 ++--
> 4 files changed, 174 insertions(+), 7 deletions(-)
> 
> diff --git a/net/bluetooth/ble_6lowpan.c b/net/bluetooth/ble_6lowpan.c
> index 44d65b3..0baf211 100644
> --- a/net/bluetooth/ble_6lowpan.c
> +++ b/net/bluetooth/ble_6lowpan.c
> @@ -12,6 +12,7 @@
> */
> 
> #include <linux/version.h>
> +#include <linux/debugfs.h>
> #include <linux/bitops.h>
> #include <linux/if_arp.h>
> #include <linux/netdevice.h>
> @@ -1535,6 +1536,169 @@ static struct notifier_block ble_6lowpan_dev_notifier = {
> 	.notifier_call = ble_6lowpan_device_event,
> };
> 
> +static LIST_HEAD(user_enabled);
> +DEFINE_RWLOCK(user_enabled_list_lock);
> +
> +struct ble_6lowpan_enabled {
> +	__u8 dev_name[HCI_MAX_NAME_LENGTH];
> +	bdaddr_t addr;
> +	struct list_head list;
> +};
> +
> +bool ble_6lowpan_is_enabled(struct hci_dev *hdev, bdaddr_t *dst)
> +{
> +	struct ble_6lowpan_enabled *entry, *tmp;
> +	bool found = false;
> +
> +	write_lock(&user_enabled_list_lock);
> +	list_for_each_entry_safe(entry, tmp, &user_enabled, list) {
> +		if (!strncmp(entry->dev_name, hdev->dev_name,
> +				HCI_MAX_NAME_LENGTH) &&
> +				!bacmp(dst, &entry->addr)) {
> +			found = true;
> +			break;
> +		}
> +	}
> +	write_unlock(&user_enabled_list_lock);
> +
> +	/* Check also the device list just in case we removed the
> +	 * device from debugfs before disconnecting.
> +	 */
> +	if (!found) {
> +		struct ble_6lowpan_dev_record *entry, *tmp;
> +		struct ble_6lowpan_dev_info *info;
> +
> +		write_lock(&net_dev_list_lock);
> +		list_for_each_entry_safe(entry, tmp,
> +					&ble_6lowpan_devices,
> +					list) {
> +			info = ble_6lowpan_dev_info(entry->dev);
> +			if (info->conn->hcon->hdev == hdev &&
> +						!bacmp(&info->addr, dst)) {
> +				found = true;
> +				break;
> +			}
> +		}
> +		write_unlock(&net_dev_list_lock);
> +	}
> +
> +	return found;
> +}
> +
> +static int ble_6lowpan_debugfs_show(struct seq_file *f, void *p)
> +{
> +	struct ble_6lowpan_enabled *entry, *tmp;
> +
> +	write_lock(&user_enabled_list_lock);
> +	list_for_each_entry_safe(entry, tmp, &user_enabled, list)
> +		seq_printf(f, "%pMR\n", &entry->addr);
> +
> +	write_unlock(&user_enabled_list_lock);
> +
> +	return 0;
> +}
> +
> +static int ble_6lowpan_debugfs_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, ble_6lowpan_debugfs_show, inode->i_private);
> +}
> +
> +static ssize_t ble_6lowpan_writer(struct file *fp,
> +				const char __user *user_buffer,
> +                                size_t count, loff_t *position)
> +{
> +#define MAC_STR_LEN 17
> +	char mac_buf[MAC_STR_LEN + 1];
> +	ssize_t ret;
> +	bool delete_mode = false;
> +
> +        if(count > (MAC_STR_LEN + 1))
> +		delete_mode = true;
> +	else if (count < MAC_STR_LEN)
> +		return count;
> +
> +	BT_DBG("count %zd mode %d", count, delete_mode);
> +
> +	memset(mac_buf, 0, MAC_STR_LEN + 1);
> +        ret = simple_write_to_buffer(mac_buf, MAC_STR_LEN, position,
> +							user_buffer, count);
> +	if (ret > 0) {

You need to get rid of this nesting. 

	if (ret < 0)
		return ret;

> +		struct ble_6lowpan_enabled *entry = NULL, *tmp;
> +		bdaddr_t bdaddr;
> +
> +		if (sscanf(mac_buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
> +				&bdaddr.b[5], &bdaddr.b[4],
> +				&bdaddr.b[3], &bdaddr.b[2],
> +				&bdaddr.b[1], &bdaddr.b[0]) != 6)
> +			return -EINVAL;
> +
> +		BT_DBG("user %pMR", &bdaddr);
> +
> +		write_lock(&user_enabled_list_lock);
> +		list_for_each_entry_safe(entry, tmp, &user_enabled, list) {
> +			if (!bacmp(&entry->addr, &bdaddr)) {
> +				struct hci_dev *hdev = fp->f_inode->i_private;
> +
> +				if (!strncmp(entry->dev_name, hdev->dev_name,
> +						HCI_MAX_NAME_LENGTH) &&
> +								delete_mode) {
> +					break;
> +				} else {
> +					ret = -EEXIST;
> +					break;
> +				}
> +			}
> +		}
> +		write_unlock(&user_enabled_list_lock);
> +
> +		if (ret > 0) {

And here as well. If you keep nesting, you cramp everything into 20 characters and it becomes unreadable.

> +			struct hci_dev *hdev = fp->f_inode->i_private;
> +
> +			if (delete_mode) {
> +				write_lock(&user_enabled_list_lock);
> +				list_del(&entry->list);
> +				kfree(entry);
> +				write_unlock(&user_enabled_list_lock);
> +			} else {
> +				entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> +				if (!entry)
> +					return -ENOMEM;
> +
> +				strncpy(entry->dev_name, hdev->dev_name,
> +					HCI_MAX_NAME_LENGTH);
> +				entry->addr = bdaddr;
> +
> +				write_lock(&user_enabled_list_lock);
> +				INIT_LIST_HEAD(&entry->list);
> +				list_add(&entry->list, &user_enabled);
> +				write_unlock(&user_enabled_list_lock);
> +			}
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static const struct file_operations ble_6lowpan_debugfs_fops = {
> +	.open		= ble_6lowpan_debugfs_open,
> +	.read		= seq_read,
> +	.write		= ble_6lowpan_writer,
> +	.llseek		= seq_lseek,
> +	.release	= single_release,
> +};
> +
> +static struct dentry *ble_6lowpan_debugfs;
> +
> +void ble_6lowpan_add_debugfs(struct hci_dev *hdev)
> +{
> +	if (hdev->debugfs) {

	if (!hdev->debugs)
		return;

> +		ble_6lowpan_debugfs = debugfs_create_file("ble6lowpan", 0644,

Use 6lowpan as name.

> +			hdev->debugfs, hdev, &ble_6lowpan_debugfs_fops);
> +		if (!ble_6lowpan_debugfs)
> +			BT_ERR("Failed to create 6LoWPAN debug file");

Don't bother with an error code here. We removed all of these. They are pointless and debugfs failures are not really failures.

> +	}
> +}
> +
> int ble_6lowpan_init(void)
> {
> 	int err;
> diff --git a/net/bluetooth/ble_6lowpan.h b/net/bluetooth/ble_6lowpan.h
> index 7975a55..047b8b7 100644
> --- a/net/bluetooth/ble_6lowpan.h
> +++ b/net/bluetooth/ble_6lowpan.h
> @@ -23,5 +23,6 @@ int ble_6lowpan_del_conn(struct l2cap_conn *conn);
> int ble_6lowpan_init(void);
> void ble_6lowpan_cleanup(void);
> bool ble_6lowpan_is_enabled(struct hci_dev *hdev, bdaddr_t *dst);
> +void ble_6lowpan_add_debugfs(struct hci_dev *hdev);
> 
> #endif /* __BLE_LOWPAN_H */
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 6ccc4eb..d0db818 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 "ble_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);
> @@ -1406,6 +1408,8 @@ static int __hci_init(struct hci_dev *hdev)
> 				    hdev, &conn_max_interval_fops);
> 	}
> 
> +	ble_6lowpan_add_debugfs(hdev);
> +
> 	return 0;
> }

I wonder if the list of enabled IPv6 devices should be actually part of hci_core.c. And we just have functions for it to call it. At the end of the day, we might just have a UUID in the advertising data and that will be in hci_core.c anyway.

> 
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index fb1a49c..e3b30dd 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -6542,11 +6542,6 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
> 	return exact ? lm1 : lm2;
> }
> 
> -static bool is_ble_6lowpan(void)
> -{
> -	return false;
> -}
> -
> void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
> {
> 	struct l2cap_conn *conn;
> @@ -6558,7 +6553,9 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
> 		if (conn) {
> 			l2cap_conn_ready(conn);
> 
> -			if (hcon->type == LE_LINK && is_ble_6lowpan())
> +			if (hcon->type == LE_LINK &&
> +					ble_6lowpan_is_enabled(hcon->hdev,
> +								&hcon->dst))
> 				ble_6lowpan_add_conn(conn);
> 		}

We have an l2cap_le_conn_ready function just for LE GATT. Maybe that should be used instead.

> 	} else {
> @@ -6581,7 +6578,8 @@ void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
> {
> 	BT_DBG("hcon %p reason %d", hcon, reason);
> 
> -	if (hcon->type == LE_LINK && is_ble_6lowpan())
> +	if (hcon->type == LE_LINK && ble_6lowpan_is_enabled(hcon->hdev,
> +							&hcon->dst))
> 		ble_6lowpan_del_conn(hcon->l2cap_data);
> 
> 	l2cap_conn_del(hcon, bt_to_errno(reason));

Regards

Marcel


^ permalink raw reply

* Re: [RFC 3/5] route: Exporting ip6_route_add() so that BLE 6LoWPAN can use it
From: Marcel Holtmann @ 2013-10-23 12:00 UTC (permalink / raw)
  To: Jukka Rissanen; +Cc: linux-bluetooth
In-Reply-To: <1382511164-1989-4-git-send-email-jukka.rissanen@linux.intel.com>

Hi Jukka,

> net/ipv6/route.c | 1 +
> 1 file changed, 1 insertion(+)
> 
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index c979dd9..d7c200f 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -1662,6 +1662,7 @@ out:
> 		dst_free(&rt->dst);
> 	return err;
> }
> +EXPORT_SYMBOL_GPL(ip6_route_add);

check with netdev is this is something that would be accepted upstream.

For the time being, can we work around this internally for testing? I like to just build and load a new Bluetooth module for testing and not have to replace IPv6 as well.

Regards

Marcel


^ permalink raw reply

* Re: [RFC 1/5] Bluetooth: Initial skeleton code for BT LE 6LoWPAN
From: Marcel Holtmann @ 2013-10-23 11:58 UTC (permalink / raw)
  To: Jukka Rissanen; +Cc: linux-bluetooth
In-Reply-To: <1382511164-1989-2-git-send-email-jukka.rissanen@linux.intel.com>

Hi Jukka,

> include/net/bluetooth/l2cap.h |   1 +
> net/bluetooth/Makefile        |   2 +-
> net/bluetooth/ble_6lowpan.c   | 404 ++++++++++++++++++++++++++++++++++++++++++
> net/bluetooth/ble_6lowpan.h   |  27 +++
> net/bluetooth/l2cap_core.c    |  22 ++-
> 5 files changed, 454 insertions(+), 2 deletions(-)
> create mode 100644 net/bluetooth/ble_6lowpan.c
> create mode 100644 net/bluetooth/ble_6lowpan.h
> 
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 3d922b9..645cd30 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
> 
> /* L2CAP Control Field bit masks */
> #define L2CAP_CTRL_SAR			0xC000
> diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
> index 6a791e7..a70625b 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 ble_6lowpan.o

we tried to not use ble prefix. I would just name it 6lowpan.c here.

> subdir-ccflags-y += -D__CHECK_ENDIAN__
> diff --git a/net/bluetooth/ble_6lowpan.c b/net/bluetooth/ble_6lowpan.c
> new file mode 100644
> index 0000000..0fd3302
> --- /dev/null
> +++ b/net/bluetooth/ble_6lowpan.c
> @@ -0,0 +1,404 @@
> +/*
> +   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>
> +
> +#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 "ble6lowpan%d"

Wonder what would be a good template name here. Maybe just calling them bt%d is good enough. At the end of the day nobody cares that this is 6loWPAN. We just want IPv6 over Bluetooth.

> +
> +/*
> + * The devices list contains those devices that we are acting
> + * as a proxy. The BT LE 6LoWPAN device is a virtual device that
> + * connects to the Bluetooth LE device. The real connection to
> + * BT LE device is done via l2cap layer. There exists one
> + * virtual device / one BT LE 6LoWPAN device. The list contains
> + * struct ble_6lowpan_dev_record elements.
> + */
> +static LIST_HEAD(ble_6lowpan_devices);
> +DEFINE_RWLOCK(net_dev_list_lock);
> +
> +struct ble_6lowpan_dev_record {
> +	struct net_device *dev;
> +	struct delayed_work delete_timer;
> +	struct list_head list;
> +};
> +
> +struct ble_6lowpan_dev_info {
> +	struct net_device *net;
> +	struct l2cap_conn *conn;
> +	uint16_t ifindex;
> +	bdaddr_t myaddr;
> +
> +	/* peer addresses in various formats */
> +	bdaddr_t addr;
> +	unsigned char ieee802154_addr[IEEE802154_ADDR_LEN];
> +	struct in6_addr peer;
> +};

Instead of ble_ use bt_ as prefix.

> +
> +struct lowpan_fragment {
> +	struct sk_buff		*skb;		/* skb to be assembled */
> +	u16			length;		/* length to be assemled */
> +	u32			bytes_rcv;	/* bytes received */
> +	u16			tag;		/* current fragment tag */
> +	struct timer_list	timer;		/* assembling timer */
> +	struct list_head	list;		/* fragments list */
> +};
> +
> +#define DELETE_TIMEOUT msecs_to_jiffies(1)
> +
> +/* TTL uncompression values */
> +static const u8 lowpan_ttl_values[] = {0, 1, 64, 255};
> +
> +static inline struct
> +ble_6lowpan_dev_info *ble_6lowpan_dev_info(const struct net_device *dev)
> +{
> +	return netdev_priv(dev);
> +}
> +
> +/* print data in line */
> +static inline void ble_6lowpan_raw_dump_inline(const char *caller, char *msg,
> +				   unsigned char *buf, int len)
> +{
> +#ifdef DEBUG
> +	if (msg)
> +		pr_debug("%s():%s: ", caller, msg);
> +	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE,
> +		       16, 1, buf, len, false);
> +#endif /* DEBUG */
> +}
> +
> +/*
> + * print data in a table format:
> + *
> + * addr: xx xx xx xx xx xx
> + * addr: xx xx xx xx xx xx
> + * ...
> + */
> +static inline void ble_6lowpan_raw_dump_table(const char *caller, char *msg,
> +				   unsigned char *buf, int len)
> +{
> +#ifdef DEBUG
> +	if (msg)
> +		pr_debug("%s():%s:\n", caller, msg);
> +	print_hex_dump(KERN_DEBUG, "\t", DUMP_PREFIX_OFFSET,
> +		       16, 1, buf, len, false);
> +#endif /* DEBUG */
> +}
> +
> +static int ble_6lowpan_recv_pkt(struct sk_buff *skb, struct net_device *dev)
> +{
> +	kfree_skb(skb);
> +	return NET_RX_DROP;
> +}
> +
> +/* Packet from BT LE device */
> +int ble_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb)
> +{
> +	struct ble_6lowpan_dev_record *entry, *tmp;
> +	struct net_device *dev = NULL;
> +	int status = -ENOENT;
> +
> +	write_lock(&net_dev_list_lock);
> +
> +	list_for_each_entry_safe(entry, tmp, &ble_6lowpan_devices, list) {
> +		if (ble_6lowpan_dev_info(entry->dev)->conn == conn) {
> +			dev = ble_6lowpan_dev_info(entry->dev)->net;
> +			break;
> +		}
> +	}
> +
> +	write_unlock(&net_dev_list_lock);
> +
> +	if (dev) {
> +		status = ble_6lowpan_recv_pkt(skb, dev);
> +		BT_DBG("recv pkt %d", status);
> +	}
> +
> +	return status;
> +}
> +
> +static void ble_6lowpan_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;
> +}
> +
> +static int lowpan_conn_send(struct l2cap_conn *conn,
> +			void *msg, size_t len, u32 priority,
> +			struct net_device *dev)
> +{
> +	struct sk_buff *skb = {0};
> +
> +	ble_6lowpan_do_send(conn, skb);
> +	return 0;
> +}
> +
> +/* Packet to BT LE device */
> +static int ble_6lowpan_send(struct l2cap_conn *conn, const void *saddr,
> +			const void *daddr, struct sk_buff *skb,
> +			struct net_device *dev)
> +{
> +	ble_6lowpan_raw_dump_table(__func__,
> +				"raw skb data dump before fragmentation",
> +				skb->data, skb->len);
> +
> +	return lowpan_conn_send(conn, skb->data, skb->len, 0, dev);
> +}
> +
> +static netdev_tx_t ble_6lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> +	int err = -1;
> +
> +	pr_debug("ble 6lowpan packet xmit\n");
> +
> +	if (ble_6lowpan_dev_info(dev)->conn)
> +		err = ble_6lowpan_send(ble_6lowpan_dev_info(dev)->conn,
> +				dev->dev_addr,
> +				&ble_6lowpan_dev_info(dev)->ieee802154_addr,
> +				skb,
> +				dev);
> +	else
> +		BT_DBG("ERROR: no BT LE 6LoWPAN device found");
> +
> +	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 ble_6lowpan_netdev_ops = {
> +	.ndo_start_xmit		= ble_6lowpan_xmit,
> +};
> +
> +static void ble_6lowpan_setup(struct net_device *dev)
> +{
> +	dev->addr_len		= IEEE802154_ADDR_LEN;
> +	dev->type		= ARPHRD_IEEE802154;

Seems like we need to ask for a new ARP header type included in include/linux/uapi/if_arp.h.

I wonder if this should be a generic one for 6loWPAN or a Bluetooth specific one. Maybe it is a good idea to prepare a patch for netdev mailing list and see what these people thing.

> +
> +	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		= &ble_6lowpan_netdev_ops;
> +	dev->destructor		= free_netdev;
> +}
> +
> +static struct device_type ble_type = {
> +	.name	= "ble6lowpan",
> +};
> +
> +static void set_addr(u8 *eui, u8 *addr)
> +{
> +	/* 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;
> +}
> +
> +static void set_dev_addr(struct net_device *net, bdaddr_t *addr)
> +{
> +	net->addr_assign_type = NET_ADDR_PERM;
> +	set_addr(net->dev_addr, addr->b);
> +	net->dev_addr[0] ^= 2;
> +}

So now it gets a bit tricky. LE has public and random addresses and we do now support controller having both. We also support controllers that have no public address. So question is what do we do when a controller only has a random address.

> +
> +static void ifup(struct net_device *net)
> +{
> +	int status;
> +
> +	rtnl_lock();
> +	if ((status = dev_open(net)) < 0)
> +		BT_INFO("iface %s cannot be opened (%d)", net->name,
> +			status);
> +	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 ble_6lowpan_add_conn(struct l2cap_conn *conn)
> +{
> +	struct net_device *net;
> +	struct ble_6lowpan_dev_info *dev;
> +	struct ble_6lowpan_dev_record *entry;
> +	int status;
> +
> +	net = alloc_netdev(sizeof(struct ble_6lowpan_dev_info),
> +			IFACE_NAME_TEMPLATE, ble_6lowpan_setup);
> +	if (!net)
> +		return -ENOMEM;
> +
> +	dev = netdev_priv(net);
> +	dev->net = net;
> +
> +	memcpy(&dev->myaddr, &conn->hcon->hdev->bdaddr, sizeof(bdaddr_t));
> +	memcpy(&dev->addr, &conn->hcon->dst, sizeof(bdaddr_t));

You need to use hcon->src and hcon->src_type for the source address. hdev->bdaddr is always the public address, but we not always use that. I fixed this lately to make sure that hcon->src always gives you the address that was really used when establishing the connection. There is also a hcon->dst_type for the remote address since that can be easily a random address as well.

Check own_address_type in debugfs if you want to play with using a random address. You need to first use the mgmt command set static address to program one before powering on the controller.

> +
> +	set_dev_addr(net, &dev->myaddr);
> +
> +	dev->conn = conn;
> +
> +	net->netdev_ops = &ble_6lowpan_netdev_ops;
> +	SET_NETDEV_DEV(net, &conn->hcon->dev);
> +	SET_NETDEV_DEVTYPE(net, &ble_type);

I am not sure this should be some other devtype. It should clearly not be empty since that would be confusing ConnMan. However I get the feeling this should stay as bluetooth devtype like we do for BNEP. We can use the ARP header type to see if this is an Ethernet emulation or native IP.

This reminds me, we tried to introduce a raw IP ARP header type for WiMAX. Not sure if that ever went upstream. In the end we decided for Ethernet emulation for WiMAX. For IPv6 over LE, the Ethernet emulation is clearly not an option.

> +
> +	status = register_netdev(net);
> +	if (status < 0) {
> +		BT_INFO("register_netdev failed %d", status);
> +		free_netdev(net);
> +		return status;
> +	} else {

I would just not bother with an else part here. You already left the function with return. So you can just continue.

> +		struct inet6_dev *idev;
> +
> +		BT_DBG("ifindex %d peer bdaddr %pMR my addr %pMR",
> +			net->ifindex, &dev->addr, &dev->myaddr);
> +		dev->ifindex = net->ifindex;
> +		set_bit(__LINK_STATE_PRESENT, &net->state);
> +
> +		idev = in6_dev_get(net);
> +		if (idev) {
> +			idev->cnf.autoconf = 1;
> +			idev->cnf.forwarding = 1;
> +			idev->cnf.accept_ra = 2;
> +
> +			in6_dev_put(idev);
> +		}
> +
> +		entry = kzalloc(sizeof(struct ble_6lowpan_dev_record),
> +				GFP_KERNEL);
> +		if (!entry)
> +			return -ENOMEM;
> +
> +		entry->dev = net;
> +
> +		write_lock(&net_dev_list_lock);
> +		INIT_LIST_HEAD(&entry->list);
> +		list_add(&entry->list, &ble_6lowpan_devices);
> +		write_unlock(&net_dev_list_lock);
> +
> +		ifup(net);
> +	}
> +
> +	return 0;
> +}
> +
> +static void delete_timeout(struct work_struct *work)
> +{
> +	struct ble_6lowpan_dev_record *entry = container_of(work,
> +						struct ble_6lowpan_dev_record,
> +						delete_timer.work);

You need to find a shorter struct name ;)

> +
> +	unregister_netdev(entry->dev);
> +	kfree(entry);
> +}
> +
> +int ble_6lowpan_del_conn(struct l2cap_conn *conn)
> +{
> +	struct ble_6lowpan_dev_record *entry, *tmp;
> +	int status = -ENOENT;
> +
> +	write_lock(&net_dev_list_lock);
> +
> +	list_for_each_entry_safe(entry, tmp, &ble_6lowpan_devices, list) {
> +		if (ble_6lowpan_dev_info(entry->dev)->conn == conn) {
> +			list_del(&entry->list);
> +			status = 0;
> +			break;
> +		}
> +	}
> +
> +	write_unlock(&net_dev_list_lock);
> +
> +	if (!status) {
> +		INIT_DELAYED_WORK(&entry->delete_timer, delete_timeout);
> +		schedule_delayed_work(&entry->delete_timer, DELETE_TIMEOUT);
> +	}
> +
> +	return status;
> +}
> +
> +static int ble_6lowpan_device_event(struct notifier_block *unused,
> +				unsigned long event, void *ptr)
> +{
> +	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
> +	struct ble_6lowpan_dev_record *entry, *tmp;
> +
> +	if (dev->type == ARPHRD_IEEE802154) {

Just check for the ARP header type we are looking for. If not, then just return. No need for the extra nesting here.

> +		switch (event) {
> +		case NETDEV_UNREGISTER:
> +			write_lock(&net_dev_list_lock);
> +			list_for_each_entry_safe(entry, tmp,
> +						&ble_6lowpan_devices,
> +						list) {
> +				if (entry->dev == dev) {
> +					list_del(&entry->list);
> +					kfree(entry);
> +					break;
> +				}
> +			}
> +			write_unlock(&net_dev_list_lock);
> +			break;
> +		}
> +	}
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block ble_6lowpan_dev_notifier = {
> +	.notifier_call = ble_6lowpan_device_event,
> +};
> +
> +int ble_6lowpan_init(void)
> +{
> +	int err;
> +
> +	err = register_netdevice_notifier(&ble_6lowpan_dev_notifier);
> +
> +	return err;
> +}

return register_netdevice_…

> +
> +void ble_6lowpan_cleanup(void)
> +{
> +	unregister_netdevice_notifier(&ble_6lowpan_dev_notifier);
> +}
> diff --git a/net/bluetooth/ble_6lowpan.h b/net/bluetooth/ble_6lowpan.h
> new file mode 100644
> index 0000000..7975a55
> --- /dev/null
> +++ b/net/bluetooth/ble_6lowpan.h
> @@ -0,0 +1,27 @@
> +/*
> +   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 __BLE_LOWPAN_H
> +#define __BLE_LOWPAN_H
> +
> +#include <linux/skbuff.h>
> +#include <net/bluetooth/l2cap.h>
> +
> +int ble_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb);
> +int ble_6lowpan_add_conn(struct l2cap_conn *conn);
> +int ble_6lowpan_del_conn(struct l2cap_conn *conn);
> +int ble_6lowpan_init(void);
> +void ble_6lowpan_cleanup(void);
> +bool ble_6lowpan_is_enabled(struct hci_dev *hdev, bdaddr_t *dst);
> +
> +#endif /* __BLE_LOWPAN_H */
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index d52bd0d..fb1a49c 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 "ble_6lowpan.h"
> 
> bool disable_ertm;
> 
> @@ -6500,6 +6501,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:
> +		ble_6lowpan_recv(conn, skb);
> +		break;
> +
> 	default:
> 		l2cap_data_channel(conn, cid, skb);
> 		break;
> @@ -6537,6 +6542,11 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
> 	return exact ? lm1 : lm2;
> }
> 
> +static bool is_ble_6lowpan(void)
> +{
> +	return false;
> +}
> +
> void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
> {
> 	struct l2cap_conn *conn;
> @@ -6545,8 +6555,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 (hcon->type == LE_LINK && is_ble_6lowpan())
> +				ble_6lowpan_add_conn(conn);
> +		}
> 	} else {
> 		l2cap_conn_del(hcon, bt_to_errno(status));
> 	}
> @@ -6567,6 +6581,9 @@ void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
> {
> 	BT_DBG("hcon %p reason %d", hcon, reason);
> 
> +	if (hcon->type == LE_LINK && is_ble_6lowpan())
> +		ble_6lowpan_del_conn(hcon->l2cap_data);
> +
> 	l2cap_conn_del(hcon, bt_to_errno(reason));
> }
> 
> @@ -6849,11 +6866,14 @@ int __init l2cap_init(void)
> 	l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
> 					    NULL, &l2cap_debugfs_fops);
> 
> +	ble_6lowpan_init();
> +
> 	return 0;
> }
> 
> void l2cap_exit(void)
> {
> +	ble_6lowpan_cleanup();
> 	debugfs_remove(l2cap_debugfs);
> 	l2cap_cleanup_sockets();
> }

Regards

Marcel


^ permalink raw reply

* Re: [PATCH 1/6] android: Add initial code for services register
From: Johan Hedberg @ 2013-10-23 11:29 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1382526281-19711-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Wed, Oct 23, 2013, Szymon Janc wrote:
> This will be used to enable services on respective HAL init calls.
> ---
>  android/main.c | 14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)

All six patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH 6/6] android: Add support for  registering and unregistering hid service
From: Szymon Janc @ 2013-10-23 11:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382526281-19711-1-git-send-email-szymon.janc@tieto.com>

---
 android/hid.c  | 21 +++++++++++++++++++++
 android/hid.h  |  3 +++
 android/main.c |  8 ++++++++
 3 files changed, 32 insertions(+)

diff --git a/android/hid.c b/android/hid.c
index 31de20d..2c74352 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -22,14 +22,18 @@
  */
 
 #include <stdint.h>
+#include <stdbool.h>
 
 #include <glib.h>
 
+#include "lib/bluetooth.h"
 #include "log.h"
 #include "hal-msg.h"
 #include "ipc.h"
 #include "hid.h"
 
+static GIOChannel *notification_io = NULL;
+
 void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
 {
 	uint8_t status = HAL_ERROR_FAILED;
@@ -46,3 +50,20 @@ void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
 
 	ipc_send_error(io, HAL_SERVICE_ID_HIDHOST, status);
 }
+
+bool bt_hid_register(GIOChannel *io, const bdaddr_t *addr)
+{
+	DBG("");
+
+	notification_io = g_io_channel_ref(io);
+
+	return true;
+}
+
+void bt_hid_unregister(void)
+{
+	DBG("");
+
+	g_io_channel_unref(notification_io);
+	notification_io = NULL;
+}
diff --git a/android/hid.h b/android/hid.h
index 1247488..674b35a 100644
--- a/android/hid.h
+++ b/android/hid.h
@@ -22,3 +22,6 @@
  */
 
 void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len);
+
+bool bt_hid_register(GIOChannel *io, const bdaddr_t *addr);
+void bt_hid_unregister(void);
diff --git a/android/main.c b/android/main.c
index e8b584d..edcca73 100644
--- a/android/main.c
+++ b/android/main.c
@@ -88,6 +88,11 @@ static void service_register(void *buf, uint16_t len)
 			goto error;
 
 		break;
+	case HAL_SERVICE_ID_HIDHOST:
+		if (!bt_hid_register(hal_notif_io, bt_adapter_get_address()))
+			goto error;
+
+		break;
 	default:
 		DBG("service %u not supported", m->service_id);
 		goto error;
@@ -118,6 +123,9 @@ static void service_unregister(void *buf, uint16_t len)
 	case HAL_SERVICE_ID_SOCK:
 		bt_socket_unregister();
 		break;
+	case HAL_SERVICE_ID_HIDHOST:
+		bt_hid_unregister();
+		break;
 	default:
 		/* This would indicate bug in HAL, as unregister should not be
 		 * called in init failed */
-- 
1.8.4


^ permalink raw reply related

* [PATCH 5/6] android: Add initial code for socket service
From: Szymon Janc @ 2013-10-23 11:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382526281-19711-1-git-send-email-szymon.janc@tieto.com>

Only handle register/unregister for now.
---
 Makefile.android   |  3 ++-
 android/Android.mk |  1 +
 android/main.c     | 10 ++++++++++
 android/socket.c   | 41 +++++++++++++++++++++++++++++++++++++++++
 android/socket.h   | 25 +++++++++++++++++++++++++
 5 files changed, 79 insertions(+), 1 deletion(-)
 create mode 100644 android/socket.c
 create mode 100644 android/socket.h

diff --git a/Makefile.android b/Makefile.android
index 0a05e9e..a398537 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -10,7 +10,8 @@ android_bluetoothd_SOURCES =	android/main.c \
 				src/shared/mgmt.h src/shared/mgmt.c \
 				android/adapter.h android/adapter.c \
 				android/hid.h android/hid.c \
-				android/ipc.h android/ipc.c
+				android/ipc.h android/ipc.c \
+				android/socket.h android/socket.c
 
 android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
diff --git a/android/Android.mk b/android/Android.mk
index 9f91576..dd5d6f7 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -17,6 +17,7 @@ LOCAL_SRC_FILES := \
 	log.c \
 	adapter.c \
 	hid.c \
+	socket.c \
 	ipc.c ipc.h \
 	../src/shared/mgmt.c \
 	../src/shared/util.c \
diff --git a/android/main.c b/android/main.c
index b18b8d4..e8b584d 100644
--- a/android/main.c
+++ b/android/main.c
@@ -49,6 +49,7 @@
 #include "src/shared/mgmt.h"
 
 #include "adapter.h"
+#include "socket.h"
 #include "hid.h"
 #include "hal-msg.h"
 #include "ipc.h"
@@ -81,6 +82,12 @@ static void service_register(void *buf, uint16_t len)
 			goto error;
 
 		break;
+	case HAL_SERVICE_ID_SOCK:
+		if (!bt_socket_register(hal_notif_io,
+						bt_adapter_get_address()))
+			goto error;
+
+		break;
 	default:
 		DBG("service %u not supported", m->service_id);
 		goto error;
@@ -108,6 +115,9 @@ static void service_unregister(void *buf, uint16_t len)
 	case HAL_SERVICE_ID_BLUETOOTH:
 		bt_adapter_unregister();
 		break;
+	case HAL_SERVICE_ID_SOCK:
+		bt_socket_unregister();
+		break;
 	default:
 		/* This would indicate bug in HAL, as unregister should not be
 		 * called in init failed */
diff --git a/android/socket.c b/android/socket.c
new file mode 100644
index 0000000..22d2acb
--- /dev/null
+++ b/android/socket.c
@@ -0,0 +1,41 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  Intel Corporation. All rights reserved.
+ *
+ *
+ *  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
+ *
+ */
+
+#include <glib.h>
+#include <stdbool.h>
+
+#include "lib/bluetooth.h"
+#include "log.h"
+#include "socket.h"
+
+bool bt_socket_register(GIOChannel *io, const bdaddr_t *addr)
+{
+	DBG("");
+
+	return true;
+}
+
+void bt_socket_unregister(void)
+{
+	DBG("");
+}
diff --git a/android/socket.h b/android/socket.h
new file mode 100644
index 0000000..b13e84c
--- /dev/null
+++ b/android/socket.h
@@ -0,0 +1,25 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  Intel Corporation. All rights reserved.
+ *
+ *
+ *  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
+ *
+ */
+
+bool bt_socket_register(GIOChannel *io, const bdaddr_t *addr);
+void bt_socket_unregister(void);
-- 
1.8.4


^ permalink raw reply related

* [PATCH 4/6] android: Add bt_adapter_get_address function
From: Szymon Janc @ 2013-10-23 11:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382526281-19711-1-git-send-email-szymon.janc@tieto.com>

It will be used to obtain adapter address.
---
 android/adapter.c | 5 +++++
 android/adapter.h | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index 059a5be..f9843d1 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -364,6 +364,11 @@ void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
 	ipc_send_error(io, HAL_SERVICE_ID_BLUETOOTH, status);
 }
 
+const bdaddr_t *bt_adapter_get_address(void)
+{
+	return &default_adapter->bdaddr;
+}
+
 bool bt_adapter_register(GIOChannel *io)
 {
 	DBG("");
diff --git a/android/adapter.h b/android/adapter.h
index 194950b..b8d0a58 100644
--- a/android/adapter.h
+++ b/android/adapter.h
@@ -38,5 +38,7 @@ bool bt_adapter_init(uint16_t index, struct mgmt *mgmt_if,
 void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
 								uint16_t len);
 
+const bdaddr_t *bt_adapter_get_address(void);
+
 bool bt_adapter_register(GIOChannel *io);
 void bt_adapter_unregister(void);
-- 
1.8.4


^ permalink raw reply related

* [PATCH 3/6] android: Add support for registering "bluetooth" service
From: Szymon Janc @ 2013-10-23 11:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382526281-19711-1-git-send-email-szymon.janc@tieto.com>

---
 android/adapter.c | 19 +++++++++++++++++++
 android/adapter.h |  3 +++
 android/main.c    |  8 ++++++++
 3 files changed, 30 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index de3660d..059a5be 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -33,6 +33,8 @@
 #include "ipc.h"
 #include "adapter.h"
 
+static GIOChannel *notification_io = NULL;
+
 struct bt_adapter {
 	uint16_t index;
 	struct mgmt *mgmt;
@@ -361,3 +363,20 @@ void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
 
 	ipc_send_error(io, HAL_SERVICE_ID_BLUETOOTH, status);
 }
+
+bool bt_adapter_register(GIOChannel *io)
+{
+	DBG("");
+
+	notification_io = g_io_channel_ref(io);
+
+	return true;
+}
+
+void bt_adapter_unregister(void)
+{
+	DBG("");
+
+	g_io_channel_unref(notification_io);
+	notification_io = NULL;
+}
diff --git a/android/adapter.h b/android/adapter.h
index bfd4932..194950b 100644
--- a/android/adapter.h
+++ b/android/adapter.h
@@ -37,3 +37,6 @@ bool bt_adapter_init(uint16_t index, struct mgmt *mgmt_if,
 
 void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
 								uint16_t len);
+
+bool bt_adapter_register(GIOChannel *io);
+void bt_adapter_unregister(void);
diff --git a/android/main.c b/android/main.c
index 73ff3ee..b18b8d4 100644
--- a/android/main.c
+++ b/android/main.c
@@ -76,6 +76,11 @@ static void service_register(void *buf, uint16_t len)
 		goto error;
 
 	switch (m->service_id) {
+	case HAL_SERVICE_ID_BLUETOOTH:
+		if (!bt_adapter_register(hal_notif_io))
+			goto error;
+
+		break;
 	default:
 		DBG("service %u not supported", m->service_id);
 		goto error;
@@ -100,6 +105,9 @@ static void service_unregister(void *buf, uint16_t len)
 		goto error;
 
 	switch (m->service_id) {
+	case HAL_SERVICE_ID_BLUETOOTH:
+		bt_adapter_unregister();
+		break;
 	default:
 		/* This would indicate bug in HAL, as unregister should not be
 		 * called in init failed */
-- 
1.8.4


^ permalink raw reply related

* [PATCH 2/6] android: Add initial code for services unregister
From: Szymon Janc @ 2013-10-23 11:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382526281-19711-1-git-send-email-szymon.janc@tieto.com>

This will be used to disable services on respective HAL cleanup calls.
---
 android/main.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/android/main.c b/android/main.c
index af7ebf3..73ff3ee 100644
--- a/android/main.c
+++ b/android/main.c
@@ -96,10 +96,15 @@ static void service_unregister(void *buf, uint16_t len)
 {
 	struct hal_msg_cmd_unregister_module *m = buf;
 
-	if (m->service_id > HAL_SERVICE_ID_MAX || !services[m->service_id]) {
-		ipc_send_error(hal_cmd_io, HAL_SERVICE_ID_CORE,
-							HAL_ERROR_FAILED);
-		return;
+	if (m->service_id > HAL_SERVICE_ID_MAX || !services[m->service_id])
+		goto error;
+
+	switch (m->service_id) {
+	default:
+		/* This would indicate bug in HAL, as unregister should not be
+		 * called in init failed */
+		DBG("service %u not supported", m->service_id);
+		goto error;
 	}
 
 	services[m->service_id] = false;
@@ -108,6 +113,9 @@ static void service_unregister(void *buf, uint16_t len)
 								0, NULL, -1);
 
 	info("Service ID=%u unregistered", m->service_id);
+	return;
+error:
+	ipc_send_error(hal_cmd_io, HAL_SERVICE_ID_CORE, HAL_ERROR_FAILED);
 }
 
 static void handle_service_core(uint8_t opcode, void *buf, uint16_t len)
-- 
1.8.4


^ permalink raw reply related

* [PATCH 1/6] android: Add initial code for services register
From: Szymon Janc @ 2013-10-23 11:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This will be used to enable services on respective HAL init calls.
---
 android/main.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/android/main.c b/android/main.c
index e13e5b0..af7ebf3 100644
--- a/android/main.c
+++ b/android/main.c
@@ -72,10 +72,13 @@ static void service_register(void *buf, uint16_t len)
 {
 	struct hal_msg_cmd_register_module *m = buf;
 
-	if (m->service_id > HAL_SERVICE_ID_MAX || services[m->service_id]) {
-		ipc_send_error(hal_cmd_io, HAL_SERVICE_ID_CORE,
-							HAL_ERROR_FAILED);
-		return;
+	if (m->service_id > HAL_SERVICE_ID_MAX || services[m->service_id])
+		goto error;
+
+	switch (m->service_id) {
+	default:
+		DBG("service %u not supported", m->service_id);
+		goto error;
 	}
 
 	services[m->service_id] = true;
@@ -84,6 +87,9 @@ static void service_register(void *buf, uint16_t len)
 								NULL, -1);
 
 	info("Service ID=%u registered", m->service_id);
+	return;
+error:
+	ipc_send_error(hal_cmd_io, HAL_SERVICE_ID_CORE, HAL_ERROR_FAILED);
 }
 
 static void service_unregister(void *buf, uint16_t len)
-- 
1.8.4


^ permalink raw reply related

* Re: [PATCH] android: Check that service is started
From: Johan Hedberg @ 2013-10-23 11:03 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1382523998-30722-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Wed, Oct 23, 2013, Andrei Emeltchenko wrote:
> Add check that we are able to start Bluetooth service in
> Android. If service is not started we should not try to connect to it.
> ---
>  android/hal-ipc.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH] android: Check that service is started
From: Andrei Emeltchenko @ 2013-10-23 10:26 UTC (permalink / raw)
  To: linux-bluetooth

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

Add check that we are able to start Bluetooth service in
Android. If service is not started we should not try to connect to it.
---
 android/hal-ipc.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 2d58038..a7948a6 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -204,7 +204,11 @@ bool hal_ipc_init(void)
 	}
 
 	/* Start Android Bluetooth daemon service */
-	property_set("ctl.start", SERVICE_NAME);
+	if (property_set("ctl.start", SERVICE_NAME) < 0) {
+		error("Failed to start service %s", SERVICE_NAME);
+		close(sk);
+		return false;
+	}
 
 	cmd_sk = accept_connection(sk);
 	if (cmd_sk < 0) {
-- 
1.8.1.2


^ permalink raw reply related

* Re: [PATCH 0/2] Add support to pan and socket in haltest
From: Johan Hedberg @ 2013-10-23 10:05 UTC (permalink / raw)
  To: Jerzy Kasenberg; +Cc: linux-bluetooth
In-Reply-To: <1382517298-28093-1-git-send-email-jerzy.kasenberg@tieto.com>

Hi Jerzy,

On Wed, Oct 23, 2013, Jerzy Kasenberg wrote:
> - Add calls to methods of socket and pan
> 
> Jerzy Kasenberg (2):
>   android: Add calls to socket methods in haltest
>   android: Add calls to pan methods to haltest
> 
>  Makefile.android         |    4 +
>  android/Android.mk       |    2 +
>  android/client/haltest.c |    2 +
>  android/client/if-bt.c   |    4 +-
>  android/client/if-main.h |    4 +
>  android/client/if-pan.c  |  209 +++++++++++++++++++++++++++++
>  android/client/if-sock.c |  334 ++++++++++++++++++++++++++++++++++++++++++++++
>  7 files changed, 557 insertions(+), 2 deletions(-)
>  create mode 100644 android/client/if-pan.c
>  create mode 100644 android/client/if-sock.c

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] android: Fix build error for Android
From: Emeltchenko, Andrei @ 2013-10-23  9:18 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth, johan.hedberg, szymon.janc
In-Reply-To: <1382516789-374-1-git-send-email-lukasz.rymanowski@tieto.com>

Hi Lukasz,

On Wed, Oct 23, 2013 at 11:26 AM, Lukasz Rymanowski
<lukasz.rymanowski@tieto.com> wrote:
> Android uses functions and defines from sys/capability.h which
> requires additional include
> ---
>  android/main.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/android/main.c b/android/main.c
> index 988d08b..606baf2 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -52,6 +52,10 @@
>  #include "hal-msg.h"
>  #include "ipc.h"
>
> +#if defined(ANDROID)

check also for platform version in order to compile for 4.2.2

Regards,
Andrei

> +#include <sys/capability.h>
> +#endif
> +
>  static GMainLoop *event_loop;
>  static struct mgmt *mgmt_if = NULL;
>
> --
> 1.8.4
>
> ---------------------------------------------------------------------
> Intel Finland Oy
> Registered Address: PL 281, 00181 Helsinki
> Business Identity Code: 0357606 - 4
> Domiciled in Helsinki
>
> This e-mail and any attachments may contain confidential material for
> the sole use of the intended recipient(s). Any review or distribution
> by others is strictly prohibited. If you are not the intended
> recipient, please contact the sender and delete all copies.
>



-- 
Best regards,
Andrei Emeltchenko
Intel / OTC / Helsinki

^ permalink raw reply

* [PATCH v3 BlueZ 4/4] android: Add variable ROOT_PATH to Android.mk
From: Luiz Augusto von Dentz @ 2013-10-23  8:50 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1382518240-31896-1-git-send-email-luiz.dentz@gmail.com>

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

This makes it simpler to include files from other parts of the code.
---
 android/Android.mk | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/android/Android.mk b/android/Android.mk
index 93dcc23..2dffe71 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -1,7 +1,8 @@
 LOCAL_PATH := $(call my-dir)
+ROOT_PATH := $(LOCAL_PATH)/..
 
 # Retrieve BlueZ version from configure.ac file
-BLUEZ_VERSION := $(shell grep ^AC_INIT $(LOCAL_PATH)/../configure.ac | cpp -P -D'AC_INIT(_,v)=v')
+BLUEZ_VERSION := $(shell grep ^AC_INIT $(ROOT_PATH)/configure.ac | cpp -P -D'AC_INIT(_,v)=v')
 
 # Specify pathmap for glib
 pathmap_INCL += glib:external/bluetooth/glib
@@ -34,9 +35,9 @@ LOCAL_C_INCLUDES := \
 	$(call include-path-for, glib)/glib \
 
 LOCAL_C_INCLUDES += \
-	$(LOCAL_PATH)/../ \
-	$(LOCAL_PATH)/../src \
-	$(LOCAL_PATH)/../lib \
+	$(ROOT_PATH)/ \
+	$(ROOT_PATH)/src \
+	$(ROOT_PATH)/lib \
 
 LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
 
@@ -51,9 +52,9 @@ lib_headers := \
 	sdp_lib.h \
 	sdp.h \
 
-$(shell mkdir -p $(LOCAL_PATH)/../lib/bluetooth)
+$(shell mkdir -p $(ROOT_PATH)/lib/bluetooth)
 
-$(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bluetooth/$(file)))
+$(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(ROOT_PATH)/lib/bluetooth/$(file)))
 
 LOCAL_MODULE := bluetoothd
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH v3 BlueZ 3/4] android: Fix build dependency of haltest on target
From: Luiz Augusto von Dentz @ 2013-10-23  8:50 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1382518240-31896-1-git-send-email-luiz.dentz@gmail.com>

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

This adds missing headers necessary to build haltest.
---
 android/Android.mk | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/android/Android.mk b/android/Android.mk
index 6d707c2..93dcc23 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -92,11 +92,12 @@ include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
 	client/haltest.c \
-	client/pollhandler.c \
-	client/terminal.c \
-	client/history.c \
-	client/textconv.c \
+	client/pollhandler.c client/pollhandler.h \
+	client/terminal.c client/terminal.h \
+	client/history.c client/history.h \
+	client/textconv.c client/textconv.h \
 	client/tabcompletion.c \
+	client/if-main.h \
 	client/if-bt.c \
 	client/if-hh.c \
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH v3 BlueZ 2/4] android: Fix build dependency of bluetooth.default.so HAL on target
From: Luiz Augusto von Dentz @ 2013-10-23  8:50 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1382518240-31896-1-git-send-email-luiz.dentz@gmail.com>

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

This adds missing headers necessary to build bluetooth.default.so
---
 android/Android.mk | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/android/Android.mk b/android/Android.mk
index d67a62d..6d707c2 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -66,7 +66,8 @@ include $(BUILD_EXECUTABLE)
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
-	hal-ipc.c \
+	hal.h hal-msg.h hal-log.h \
+	hal-ipc.c hal-ipc.h \
 	hal-bluetooth.c \
 	hal-sock.c \
 	hal-hidhost.c \
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH v3 BlueZ 1/4] android: Fix build dependency of bluetoothd on target
From: Luiz Augusto von Dentz @ 2013-10-23  8:50 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds missing headers necessary to build bluetoothd.
---
 android/Android.mk | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/android/Android.mk b/android/Android.mk
index 7132279..d67a62d 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -15,9 +15,10 @@ include $(CLEAR_VARS)
 LOCAL_SRC_FILES := \
 	main.c \
 	log.c \
-	adapter.c \
-	hid.c \
+	adapter.c adapter.h \
+	hid.c hid.h \
 	ipc.c ipc.h \
+	../src/sdp.h \
 	../src/shared/mgmt.c \
 	../src/shared/util.c \
 	../src/sdpd-database.c \
-- 
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