* [PATCH 1/3] Bluetooth: btmrvl: use cal-data from device-tree instead of conf file
From: Bing Zhao @ 2013-10-31 22:08 UTC (permalink / raw)
To: linux-bluetooth
Cc: Marcel Holtmann, Gustavo Padovan, Johan Hedberg, Mike Frysinger,
Amitkumar Karwar, Bing Zhao
The cal-data is platform dependent. It's simpler and more feasible
to use device tree based cal-data instead of configuration file
based cal-data.
This patch remove configuration file based cal-data downloading
and replace it using cal-data from device tree.
Cc: Mike Frysinger <vapier@chromium.org>
Cc: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: Hyuckjoo Lee <hyuckjoo.lee@samsung.com>
---
drivers/bluetooth/btmrvl_drv.h | 4 --
drivers/bluetooth/btmrvl_main.c | 92 ++++++++---------------------------------
drivers/bluetooth/btmrvl_sdio.c | 9 +---
drivers/bluetooth/btmrvl_sdio.h | 2 -
4 files changed, 18 insertions(+), 89 deletions(-)
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h
index f9d1833..be76851 100644
--- a/drivers/bluetooth/btmrvl_drv.h
+++ b/drivers/bluetooth/btmrvl_drv.h
@@ -23,8 +23,6 @@
#include <linux/bitops.h>
#include <linux/slab.h>
#include <net/bluetooth/bluetooth.h>
-#include <linux/ctype.h>
-#include <linux/firmware.h>
#define BTM_HEADER_LEN 4
#define BTM_UPLD_SIZE 2312
@@ -43,8 +41,6 @@ struct btmrvl_thread {
struct btmrvl_device {
void *card;
struct hci_dev *hcidev;
- struct device *dev;
- const char *cal_data;
u8 dev_type;
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index 5cf31c4..a17812d 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -19,7 +19,7 @@
**/
#include <linux/module.h>
-
+#include <linux/of.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -417,52 +417,8 @@ static int btmrvl_open(struct hci_dev *hdev)
return 0;
}
-/*
- * This function parses provided calibration data input. It should contain
- * hex bytes separated by space or new line character. Here is an example.
- * 00 1C 01 37 FF FF FF FF 02 04 7F 01
- * CE BA 00 00 00 2D C6 C0 00 00 00 00
- * 00 F0 00 00
- */
-static int btmrvl_parse_cal_cfg(const u8 *src, u32 len, u8 *dst, u32 dst_size)
-{
- const u8 *s = src;
- u8 *d = dst;
- int ret;
- u8 tmp[3];
-
- tmp[2] = '\0';
- while ((s - src) <= len - 2) {
- if (isspace(*s)) {
- s++;
- continue;
- }
-
- if (isxdigit(*s)) {
- if ((d - dst) >= dst_size) {
- BT_ERR("calibration data file too big!!!");
- return -EINVAL;
- }
-
- memcpy(tmp, s, 2);
-
- ret = kstrtou8(tmp, 16, d++);
- if (ret < 0)
- return ret;
-
- s += 2;
- } else {
- return -EINVAL;
- }
- }
- if (d == dst)
- return -EINVAL;
-
- return 0;
-}
-
-static int btmrvl_load_cal_data(struct btmrvl_private *priv,
- u8 *config_data)
+static int btmrvl_download_cal_data(struct btmrvl_private *priv,
+ u8 *config_data)
{
int i, ret;
u8 data[BT_CMD_DATA_SIZE];
@@ -490,54 +446,40 @@ static int btmrvl_load_cal_data(struct btmrvl_private *priv,
return 0;
}
-static int
-btmrvl_process_cal_cfg(struct btmrvl_private *priv, u8 *data, u32 size)
+static int btmrvl_cal_data_dt(struct btmrvl_private *priv)
{
+ struct device_node *dt_node;
u8 cal_data[BT_CAL_DATA_SIZE];
+ const char name[] = "btmrvl_caldata";
+ const char property[] = "btmrvl,caldata";
int ret;
- ret = btmrvl_parse_cal_cfg(data, size, cal_data, sizeof(cal_data));
+ dt_node = of_find_node_by_name(NULL, name);
+ if (!dt_node)
+ return -ENODEV;
+
+ ret = of_property_read_u8_array(dt_node, property, cal_data,
+ sizeof(cal_data));
if (ret)
return ret;
- ret = btmrvl_load_cal_data(priv, cal_data);
+ BT_DBG("Use cal data from device tree");
+ ret = btmrvl_download_cal_data(priv, cal_data);
if (ret) {
- BT_ERR("Fail to load calibrate data");
+ BT_ERR("Fail to download calibrate data");
return ret;
}
return 0;
}
-static int btmrvl_cal_data_config(struct btmrvl_private *priv)
-{
- const struct firmware *cfg;
- int ret;
- const char *cal_data = priv->btmrvl_dev.cal_data;
-
- if (!cal_data)
- return 0;
-
- ret = request_firmware(&cfg, cal_data, priv->btmrvl_dev.dev);
- if (ret < 0) {
- BT_DBG("Failed to get %s file, skipping cal data download",
- cal_data);
- return 0;
- }
-
- ret = btmrvl_process_cal_cfg(priv, (u8 *)cfg->data, cfg->size);
- release_firmware(cfg);
- return ret;
-}
-
static int btmrvl_setup(struct hci_dev *hdev)
{
struct btmrvl_private *priv = hci_get_drvdata(hdev);
btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
- if (btmrvl_cal_data_config(priv))
- BT_ERR("Set cal data failed");
+ btmrvl_cal_data_dt(priv);
priv->btmrvl_dev.psmode = 1;
btmrvl_enable_ps(priv);
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index fabcf5b..1b52c9f 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -18,6 +18,7 @@
* this warranty disclaimer.
**/
+#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/mmc/sdio_ids.h>
@@ -101,7 +102,6 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
.helper = "mrvl/sd8688_helper.bin",
.firmware = "mrvl/sd8688.bin",
- .cal_data = NULL,
.reg = &btmrvl_reg_8688,
.sd_blksz_fw_dl = 64,
};
@@ -109,7 +109,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
.helper = NULL,
.firmware = "mrvl/sd8787_uapsta.bin",
- .cal_data = NULL,
.reg = &btmrvl_reg_87xx,
.sd_blksz_fw_dl = 256,
};
@@ -117,7 +116,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
.helper = NULL,
.firmware = "mrvl/sd8797_uapsta.bin",
- .cal_data = "mrvl/sd8797_caldata.conf",
.reg = &btmrvl_reg_87xx,
.sd_blksz_fw_dl = 256,
};
@@ -125,7 +123,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
.helper = NULL,
.firmware = "mrvl/sd8897_uapsta.bin",
- .cal_data = NULL,
.reg = &btmrvl_reg_88xx,
.sd_blksz_fw_dl = 256,
};
@@ -1007,7 +1004,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
struct btmrvl_sdio_device *data = (void *) id->driver_data;
card->helper = data->helper;
card->firmware = data->firmware;
- card->cal_data = data->cal_data;
card->reg = data->reg;
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
}
@@ -1036,8 +1032,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
}
card->priv = priv;
- priv->btmrvl_dev.dev = &card->func->dev;
- priv->btmrvl_dev.cal_data = card->cal_data;
/* Initialize the interface specific function pointers */
priv->hw_host_to_card = btmrvl_sdio_host_to_card;
@@ -1220,5 +1214,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
MODULE_FIRMWARE("mrvl/sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
-MODULE_FIRMWARE("mrvl/sd8797_caldata.conf");
MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h
index 6872d9e..43d35a6 100644
--- a/drivers/bluetooth/btmrvl_sdio.h
+++ b/drivers/bluetooth/btmrvl_sdio.h
@@ -85,7 +85,6 @@ struct btmrvl_sdio_card {
u32 ioport;
const char *helper;
const char *firmware;
- const char *cal_data;
const struct btmrvl_sdio_card_reg *reg;
u16 sd_blksz_fw_dl;
u8 rx_unit;
@@ -95,7 +94,6 @@ struct btmrvl_sdio_card {
struct btmrvl_sdio_device {
const char *helper;
const char *firmware;
- const char *cal_data;
const struct btmrvl_sdio_card_reg *reg;
u16 sd_blksz_fw_dl;
};
--
1.8.0
^ permalink raw reply related
* Re: [PATCH] android: Add support for setting adapters name
From: Johan Hedberg @ 2013-10-31 19:32 UTC (permalink / raw)
To: Grzegorz Kolodziejczyk; +Cc: linux-bluetooth
In-Reply-To: <1383233182-7188-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
Hi Grzegorz,
On Thu, Oct 31, 2013, Grzegorz Kolodziejczyk wrote:
> ---
> android/adapter.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 53 insertions(+)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 5/5] android: Pass found uuids to remote_device_properties_cb
From: Luiz Augusto von Dentz @ 2013-10-31 18:27 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth@vger.kernel.org, Marcin Kraglak
In-Reply-To: <1383233152-15040-5-git-send-email-szymon.janc@tieto.com>
Hi Marcin,
On Thu, Oct 31, 2013 at 5:25 PM, Szymon Janc <szymon.janc@tieto.com> wrote:
> From: Marcin Kraglak <marcin.kraglak@tieto.com>
>
> Change-Id: I21221033cf3510113b4014bdacb64e25b7d16ba9
Im not sure where this came from but it probably doesn't mean anything to us.
> ---
> android/adapter.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 82 insertions(+), 1 deletion(-)
>
> diff --git a/android/adapter.c b/android/adapter.c
> index 48e5e95..3d3cd72 100644
> --- a/android/adapter.c
> +++ b/android/adapter.c
> @@ -1242,9 +1242,89 @@ static void browse_req_free(struct browse_req *req)
> g_free(req);
> }
>
> +static void fill_uuids(GSList *list, void *buf)
> +{
> + int i, len = g_slist_length(list);
> +
> + for (i = 0; i < len; i++) {
> + memcpy(buf, g_slist_nth_data(list, i), sizeof(uint128_t));
Ok, this is highly inefficient since afaik g_slist_nth_data will
iterate in the list for every index, please use g_slist_foreach or
iterate with g_slist_next or ->next.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH BlueZ 2/2] android/hid: Initial implementation for uHID
From: Luiz Augusto von Dentz @ 2013-10-31 15:57 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1383235026-12247-1-git-send-email-luiz.dentz@gmail.com>
From: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
This patch reads data on interrupt channel and feeds into uHID.
Kernel will take care rest of the things and connects bt mouse
and keyboard:
[168988.557647] input: bluez-input-device as /devices/virtual/misc/uhid/input54
---
android/hid.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 125 insertions(+), 4 deletions(-)
diff --git a/android/hid.c b/android/hid.c
index 6b3b1f7..68dcec7 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -37,6 +37,7 @@
#include "src/shared/mgmt.h"
#include "src/sdp-client.h"
#include "src/glib-helper.h"
+#include "profiles/input/uhid_copy.h"
#include "log.h"
#include "hal-msg.h"
@@ -47,7 +48,7 @@
#define L2CAP_PSM_HIDP_CTRL 0x11
#define L2CAP_PSM_HIDP_INTR 0x13
-#define MAX_READ_BUFFER 4096
+#define UHID_DEVICE_FILE "/dev/uhid"
static GIOChannel *notification_io = NULL;
static GIOChannel *ctrl_io = NULL;
@@ -67,6 +68,8 @@ struct hid_device {
GIOChannel *intr_io;
guint ctrl_watch;
guint intr_watch;
+ int uhid_fd;
+ guint uhid_watch_id;
};
static int device_cmp(gconstpointer s, gconstpointer user_data)
@@ -77,6 +80,21 @@ static int device_cmp(gconstpointer s, gconstpointer user_data)
return bacmp(&hdev->dst, dst);
}
+static void uhid_destroy(int fd)
+{
+ struct uhid_event ev;
+
+ /* destroy uHID device */
+ memset(&ev, 0, sizeof(ev));
+ ev.type = UHID_DESTROY;
+
+ if (write(fd, &ev, sizeof(ev)) < 0)
+ error("Failed to destroy uHID device: %s (%d)",
+ strerror(errno), errno);
+
+ close(fd);
+}
+
static void hid_device_free(struct hid_device *hdev)
{
if (hdev->ctrl_watch > 0)
@@ -91,17 +109,63 @@ static void hid_device_free(struct hid_device *hdev)
if (hdev->ctrl_io)
g_io_channel_unref(hdev->ctrl_io);
+ if (hdev->uhid_watch_id) {
+ g_source_remove(hdev->uhid_watch_id);
+ hdev->uhid_watch_id = 0;
+ }
+
+ if (hdev->uhid_fd > 0)
+ uhid_destroy(hdev->uhid_fd);
+
g_free(hdev->rd_data);
devices = g_slist_remove(devices, hdev);
g_free(hdev);
}
+static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ struct hid_device *hdev = user_data;
+ struct uhid_event ev;
+ ssize_t bread;
+ int fd;
+
+ DBG("");
+
+ if (cond & (G_IO_ERR | G_IO_NVAL))
+ goto failed;
+
+ fd = g_io_channel_unix_get_fd(io);
+ memset(&ev, 0, sizeof(ev));
+
+ bread = read(fd, &ev, sizeof(ev));
+ if (bread < 0) {
+ DBG("read: %s (%d)", strerror(errno), errno);
+ goto failed;
+ }
+
+ DBG("uHID event type %d received", ev.type);
+ /* TODO Handle events */
+
+ return TRUE;
+
+failed:
+ hdev->uhid_watch_id = 0;
+ return FALSE;
+}
+
static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
{
- char buf[MAX_READ_BUFFER];
+ struct hid_device *hdev = data;
+ uint8_t buf[UHID_DATA_MAX];
+ struct uhid_event ev;
int fd, bread;
+ /* Wait uHID if not ready */
+ if (hdev->uhid_fd < 0)
+ return TRUE;
+
fd = g_io_channel_unix_get_fd(chan);
bread = read(fd, buf, sizeof(buf));
if (bread < 0) {
@@ -109,7 +173,18 @@ static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
return TRUE;
}
- DBG("bytes read %d", bread);
+ /* Discard non-data packets */
+ if (bread == 0 || buf[0] != 0xA1)
+ return TRUE;
+
+ /* send data to uHID device skipping HIDP header byte */
+ memset(&ev, 0, sizeof(ev));
+ ev.type = UHID_INPUT;
+ ev.u.input.size = bread - 1;
+ memcpy(ev.u.input.data, &buf[1], ev.u.input.size);
+
+ if (write(hdev->uhid_fd, &ev, sizeof(ev)) < 0)
+ DBG("write: %s (%d)", strerror(errno), errno);
return TRUE;
}
@@ -185,6 +260,44 @@ static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
return FALSE;
}
+static int uhid_create(struct hid_device *hdev)
+{
+ GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL;
+ GIOChannel *io;
+ struct uhid_event ev;
+
+ hdev->uhid_fd = open(UHID_DEVICE_FILE, O_RDWR | O_CLOEXEC);
+ if (hdev->uhid_fd < 0) {
+ error("Failed to open uHID device: %s", strerror(errno));
+ return -errno;
+ }
+
+ memset(&ev, 0, sizeof(ev));
+ ev.type = UHID_CREATE;
+ strcpy((char *) ev.u.create.name, "bluez-input-device");
+ ev.u.create.bus = BUS_BLUETOOTH;
+ ev.u.create.vendor = hdev->vendor;
+ ev.u.create.product = hdev->product;
+ ev.u.create.version = hdev->vendor;
+ ev.u.create.country = hdev->country;
+ ev.u.create.rd_size = hdev->rd_size;
+ ev.u.create.rd_data = hdev->rd_data;
+
+ if (write(hdev->uhid_fd, &ev, sizeof(ev)) < 0) {
+ error("Failed to create uHID device: %s", strerror(errno));
+ close(hdev->uhid_fd);
+ hdev->uhid_fd = -1;
+ return -errno;
+ }
+
+ io = g_io_channel_unix_new(hdev->uhid_fd);
+ g_io_channel_set_encoding(io, NULL, NULL);
+ hdev->uhid_watch_id = g_io_add_watch(io, cond, uhid_event_cb, hdev);
+ g_io_channel_unref(io);
+
+ return 0;
+}
+
static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
gpointer user_data)
{
@@ -195,6 +308,9 @@ static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
if (conn_err)
goto failed;
+ if (uhid_create(hdev) < 0)
+ goto failed;
+
hdev->intr_watch = g_io_add_watch(hdev->intr_io,
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
intr_watch_cb, hdev);
@@ -321,8 +437,11 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
}
}
- if (hdev->ctrl_io)
+ if (hdev->ctrl_io) {
+ if (uhid_create(hdev) < 0)
+ goto fail;
return;
+ }
hdev->ctrl_io = bt_io_connect(control_connect_cb, hdev, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR, src,
@@ -365,6 +484,7 @@ static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
hdev = g_new0(struct hid_device, 1);
bacpy(&hdev->dst, &dst);
+ hdev->uhid_fd = -1;
ba2str(&hdev->dst, addr);
DBG("connecting to %s", addr);
@@ -472,6 +592,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
hdev = g_new0(struct hid_device, 1);
bacpy(&hdev->dst, &dst);
hdev->ctrl_io = g_io_channel_ref(chan);
+ hdev->uhid_fd = -1;
bt_string2uuid(&uuid, HID_UUID);
if (bt_search_service(src, &hdev->dst, &uuid,
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 1/2] android/hid: Fetch record before attempting to connect
From: Luiz Augusto von Dentz @ 2013-10-31 15:57 UTC (permalink / raw)
To: linux-bluetooth
From: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
This patch fetch HID record and store the information needed by uHID.
---
android/Android.mk | 4 +-
android/Makefile.am | 4 +-
android/hid.c | 134 +++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 122 insertions(+), 20 deletions(-)
diff --git a/android/Android.mk b/android/Android.mk
index 72ea8b8..d2afa09 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -35,7 +35,9 @@ LOCAL_SRC_FILES := \
../lib/sdp.c \
../lib/bluetooth.c \
../lib/hci.c \
- ../btio/btio.c
+ ../btio/btio.c \
+ ../src/sdp-client.c \
+ ../src/glib-helper.c
LOCAL_C_INCLUDES := \
$(call include-path-for, glib) \
diff --git a/android/Makefile.am b/android/Makefile.am
index c5b70ab..ac92510 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -13,7 +13,9 @@ android_bluetoothd_SOURCES = android/main.c \
android/hid.h android/hid.c \
android/ipc.h android/ipc.c \
android/socket.h android/socket.c \
- btio/btio.h btio/btio.c
+ btio/btio.h btio/btio.c \
+ src/sdp-client.h src/sdp-client.c \
+ src/glib-helper.h src/glib-helper.c
android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
diff --git a/android/hid.c b/android/hid.c
index 5caa25b..6b3b1f7 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -31,7 +31,12 @@
#include "btio/btio.h"
#include "lib/bluetooth.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
+#include "lib/uuid.h"
#include "src/shared/mgmt.h"
+#include "src/sdp-client.h"
+#include "src/glib-helper.h"
#include "log.h"
#include "hal-msg.h"
@@ -52,6 +57,12 @@ static GSList *devices = NULL;
struct hid_device {
bdaddr_t dst;
uint8_t state;
+ uint16_t vendor;
+ uint16_t product;
+ uint16_t version;
+ uint8_t country;
+ int rd_size;
+ void *rd_data;
GIOChannel *ctrl_io;
GIOChannel *intr_io;
guint ctrl_watch;
@@ -80,6 +91,8 @@ static void hid_device_free(struct hid_device *hdev)
if (hdev->ctrl_io)
g_io_channel_unref(hdev->ctrl_io);
+ g_free(hdev->rd_data);
+
devices = g_slist_remove(devices, hdev);
g_free(hdev);
}
@@ -98,10 +111,6 @@ static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
DBG("bytes read %d", bread);
- /* TODO: At this moment only baseband is connected, i.e. mouse
- * movements keyboard events doesn't effect on UI. Have to send
- * this data to uhid fd for profile connection. */
-
return TRUE;
}
@@ -186,8 +195,6 @@ static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
if (conn_err)
goto failed;
- /*TODO: Get device details through SDP and create UHID fd and start
- * listening on uhid events */
hdev->intr_watch = g_io_add_watch(hdev->intr_io,
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
intr_watch_cb, hdev);
@@ -250,14 +257,100 @@ failed:
hid_device_free(hdev);
}
+static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
+{
+ struct hid_device *hdev = data;
+ sdp_list_t *list;
+ GError *gerr = NULL;
+ const bdaddr_t *src = bt_adapter_get_address();
+
+ DBG("");
+
+ if (err < 0) {
+ error("Unable to get SDP record: %s", strerror(-err));
+ goto fail;
+ }
+
+ if (!recs || !recs->data) {
+ error("No SDP records found");
+ goto fail;
+ }
+
+ for (list = recs; list != NULL; list = list->next) {
+ sdp_record_t *rec = list->data;
+ sdp_data_t *data;
+
+ data = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
+ if (data)
+ hdev->vendor = data->val.uint16;
+
+ data = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
+ if (data)
+ hdev->product = data->val.uint16;
+
+ data = sdp_data_get(rec, SDP_ATTR_VERSION);
+ if (data)
+ hdev->version = data->val.uint16;
+
+ data = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE);
+ if (data)
+ hdev->country = data->val.uint8;
+
+ data = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
+ if (data) {
+ if (!SDP_IS_SEQ(data->dtd))
+ goto fail;
+
+ /* First HIDDescriptor */
+ data = data->val.dataseq;
+ if (!SDP_IS_SEQ(data->dtd))
+ goto fail;
+
+ /* ClassDescriptorType */
+ data = data->val.dataseq;
+ if (data->dtd != SDP_UINT8)
+ goto fail;
+
+ /* ClassDescriptorData */
+ data = data->next;
+ if (!data || !SDP_IS_TEXT_STR(data->dtd))
+ goto fail;
+
+ hdev->rd_size = data->unitSize;
+ hdev->rd_data = g_memdup(data->val.str, data->unitSize);
+ }
+ }
+
+ if (hdev->ctrl_io)
+ return;
+
+ hdev->ctrl_io = bt_io_connect(control_connect_cb, hdev, NULL, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_DEST_BDADDR, &hdev->dst,
+ BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s", gerr->message);
+ g_error_free(gerr);
+ goto fail;
+ }
+
+ return;
+
+fail:
+ bt_hid_set_state(hdev, HAL_HID_STATE_DISCONNECTED);
+ hid_device_free(hdev);
+}
+
static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
{
struct hid_device *hdev;
char addr[18];
bdaddr_t dst;
GSList *l;
- GError *err = NULL;
const bdaddr_t *src = bt_adapter_get_address();
+ uuid_t uuid;
DBG("");
@@ -271,20 +364,15 @@ static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
return HAL_STATUS_FAILED;
hdev = g_new0(struct hid_device, 1);
- android2bdaddr(&cmd->bdaddr, &hdev->dst);
- ba2str(&hdev->dst, addr);
+ bacpy(&hdev->dst, &dst);
+ ba2str(&hdev->dst, addr);
DBG("connecting to %s", addr);
- hdev->ctrl_io = bt_io_connect(control_connect_cb, hdev, NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR, src,
- BT_IO_OPT_DEST_BDADDR, &hdev->dst,
- BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
- BT_IO_OPT_INVALID);
- if (err) {
- error("%s", err->message);
- g_error_free(err);
+ bt_string2uuid(&uuid, HID_UUID);
+ if (bt_search_service(src, &hdev->dst, &uuid, hid_sdp_search_cb, hdev,
+ NULL) < 0) {
+ error("Failed to search sdp details");
hid_device_free(hdev);
return HAL_STATUS_FAILED;
}
@@ -354,6 +442,8 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
uint16_t psm;
GError *gerr = NULL;
GSList *l;
+ const bdaddr_t *src = bt_adapter_get_address();
+ uuid_t uuid;
if (err) {
error("%s", err->message);
@@ -383,6 +473,14 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
bacpy(&hdev->dst, &dst);
hdev->ctrl_io = g_io_channel_ref(chan);
+ bt_string2uuid(&uuid, HID_UUID);
+ if (bt_search_service(src, &hdev->dst, &uuid,
+ hid_sdp_search_cb, hdev, NULL) < 0) {
+ error("failed to search sdp details");
+ hid_device_free(hdev);
+ return;
+ }
+
devices = g_slist_append(devices, hdev);
hdev->ctrl_watch = g_io_add_watch(hdev->ctrl_io,
--
1.8.3.1
^ permalink raw reply related
* [RFC] hidhost: Shutdown HID L2CAP sockets on unregister
From: Andrei Emeltchenko @ 2013-10-31 15:30 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Fixes address already in use issue if we reenable HID.
...
bluetoothd[2894]: Failed to listen on ctrl channel:
l2cap_bind: Address already in use (98)
...
---
android/hid.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/android/hid.c b/android/hid.c
index 4075ecb..2bc8c06 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -445,9 +445,15 @@ void bt_hid_unregister(void)
g_io_channel_unref(notification_io);
notification_io = NULL;
- g_io_channel_unref(ctrl_io);
- ctrl_io = NULL;
+ if (ctrl_io) {
+ g_io_channel_shutdown(ctrl_io, TRUE, NULL);
+ g_io_channel_unref(ctrl_io);
+ ctrl_io = NULL;
+ }
- g_io_channel_unref(intr_io);
- intr_io = NULL;
+ if (intr_io) {
+ g_io_channel_shutdown(intr_io, TRUE, NULL);
+ g_io_channel_unref(intr_io);
+ intr_io = NULL;
+ }
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH] android: Add support for setting adapters name
From: Grzegorz Kolodziejczyk @ 2013-10-31 15:26 UTC (permalink / raw)
To: linux-bluetooth
---
android/adapter.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/android/adapter.c b/android/adapter.c
index 15b65e5..5dadc2e 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -129,6 +129,27 @@ static void scan_mode_changed(void)
g_free(ev);
}
+static void adapter_name_changed(const uint8_t *name)
+{
+ struct hal_ev_adapter_props_changed *ev;
+ uint8_t buf[sizeof(*ev) + sizeof(struct hal_property) +
+ HAL_MAX_NAME_LENGTH];
+
+ memset(buf, 0, sizeof(buf));
+ ev = (void *) buf;
+
+ ev->num_props = 1;
+ ev->status = HAL_STATUS_SUCCESS;
+ ev->props[0].type = HAL_PROP_ADAPTER_NAME;
+ ev->props[0].len = HAL_MAX_NAME_LENGTH;
+ memcpy(ev->props->val, name, HAL_MAX_NAME_LENGTH);
+
+ DBG("Adapter name changed to: %s", ev->props->val);
+
+ ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+ HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), ev, -1);
+}
+
static void settings_changed(uint32_t settings)
{
uint32_t changed_mask;
@@ -286,6 +307,37 @@ static bool set_mode(uint16_t opcode, uint8_t mode)
return false;
}
+static void set_adapter_name_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_cp_set_local_name *rp = param;
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to set name: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ adapter_name_changed(rp->name);
+}
+
+static bool set_adapter_name(uint8_t *name, uint16_t len)
+{
+ struct mgmt_cp_set_local_name cp;
+
+ memset(&cp, 0, sizeof(cp));
+ memcpy(cp.name, name, len);
+
+ if (mgmt_send(adapter->mgmt, MGMT_OP_SET_LOCAL_NAME, adapter->index,
+ sizeof(cp), &cp, set_adapter_name_complete, NULL,
+ NULL) > 0)
+ return true;
+
+ error("Failed to set name");
+
+ return false;
+}
+
static void read_info_complete(uint8_t status, uint16_t length, const void *param,
void *user_data)
{
@@ -472,6 +524,7 @@ static uint8_t set_property(void *buf, uint16_t len)
case HAL_PROP_ADAPTER_SCAN_MODE:
return set_scan_mode(cmd->val, cmd->len);
case HAL_PROP_ADAPTER_NAME:
+ return set_adapter_name(cmd->val, cmd->len);
case HAL_PROP_ADAPTER_DISC_TIMEOUT:
default:
DBG("Unhandled property type 0x%x", cmd->type);
--
1.8.4.1
^ permalink raw reply related
* [PATCH 5/5] android: Pass found uuids to remote_device_properties_cb
From: Szymon Janc @ 2013-10-31 15:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1383233152-15040-1-git-send-email-szymon.janc@tieto.com>
From: Marcin Kraglak <marcin.kraglak@tieto.com>
Change-Id: I21221033cf3510113b4014bdacb64e25b7d16ba9
---
android/adapter.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 82 insertions(+), 1 deletion(-)
diff --git a/android/adapter.c b/android/adapter.c
index 48e5e95..3d3cd72 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -1242,9 +1242,89 @@ static void browse_req_free(struct browse_req *req)
g_free(req);
}
+static void fill_uuids(GSList *list, void *buf)
+{
+ int i, len = g_slist_length(list);
+
+ for (i = 0; i < len; i++) {
+ memcpy(buf, g_slist_nth_data(list, i), sizeof(uint128_t));
+ buf += sizeof(uint128_t);
+ }
+}
+
+static void remote_uuids_callback(struct browse_req *req)
+{
+ struct hal_ev_remote_device_props *ev;
+ int len;
+
+ len = sizeof(*ev) + sizeof(struct hal_property) + (sizeof(uint128_t) *
+ g_slist_length(req->uuids));
+ ev = g_malloc(len);
+
+ ev->status = HAL_STATUS_SUCCESS;
+ bdaddr2android(req->bdaddr, &ev->bdaddr);
+ ev->num_props = 1;
+ ev->props[0].type = HAL_PROP_DEVICE_UUIDS;
+ ev->props[0].len = sizeof(uint128_t) * g_slist_length(req->uuids);
+ fill_uuids(req->uuids, ev->props[0].val);
+
+ ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+ HAL_EV_REMOTE_DEVICE_PROPS, len, ev, -1);
+
+ g_free(ev);
+}
+
+static int uuid_128_cmp(gconstpointer a, gconstpointer b)
+{
+ return memcmp(a, b, sizeof(uint128_t));
+}
+
static void update_records(struct browse_req *req, sdp_list_t *recs)
{
- /* TODO cache found uuids */
+ for (; recs; recs = recs->next) {
+ sdp_record_t *rec = (sdp_record_t *) recs->data;
+ sdp_list_t *svcclass = NULL;
+ uuid_t uuid128;
+ uuid_t *temp;
+ uint8_t *u;
+
+ if (!rec)
+ break;
+
+ if (sdp_get_service_classes(rec, &svcclass) < 0)
+ continue;
+
+ if (svcclass == NULL)
+ continue;
+
+ temp = svcclass->data;
+
+ switch (temp->type) {
+ case SDP_UUID16:
+ sdp_uuid16_to_uuid128(&uuid128, temp);
+ break;
+ case SDP_UUID32:
+ sdp_uuid32_to_uuid128(&uuid128, temp);
+ break;
+ case SDP_UUID128:
+ memcpy(&uuid128, temp, sizeof(uuid_t));
+ break;
+ default:
+ continue;
+ }
+
+ u = g_malloc(16);/* size of 128 bit uuid */
+ memcpy(u, &uuid128.value.uuid128,
+ sizeof(uuid128.value.uuid128));
+
+ /* Check if uuid is already added */
+ if (g_slist_find_custom(req->uuids, u, uuid_128_cmp))
+ g_free(u);
+ else
+ req->uuids = g_slist_append(req->uuids, u);
+
+ sdp_list_free(svcclass, free);
+ }
}
static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
@@ -1274,6 +1354,7 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
}
done:
+ remote_uuids_callback(req);
sdp_req_list = g_list_remove(sdp_req_list, req->bdaddr);
browse_req_free(req);
}
--
1.8.4.1
^ permalink raw reply related
* [PATCH 4/5] android: Initial implementation of get_remote_services
From: Szymon Janc @ 2013-10-31 15:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1383233152-15040-1-git-send-email-szymon.janc@tieto.com>
From: Marcin Kraglak <marcin.kraglak@tieto.com>
Change-Id: I9dffb4d59be5d41c0c26d619b30289c0e52f3a2e
---
android/Android.mk | 1 +
android/Makefile.am | 1 +
android/adapter.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 94 insertions(+), 1 deletion(-)
diff --git a/android/Android.mk b/android/Android.mk
index b953554..993f6d6 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -34,6 +34,7 @@ LOCAL_SRC_FILES := \
../src/sdpd-server.c \
../src/glib-helper.c \
../src/eir.c \
+ ../src/sdp-client.c \
../lib/sdp.c \
../lib/bluetooth.c \
../lib/hci.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index 17165e2..acaece2 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -9,6 +9,7 @@ android_bluetoothd_SOURCES = android/main.c \
src/sdpd-service.c src/sdpd-request.c \
src/glib-helper.h src/glib-helper.c \
src/eir.h src/eir.c \
+ src/sdp-client.c src/sdp-client.h \
src/shared/util.h src/shared/util.c \
src/shared/mgmt.h src/shared/mgmt.c \
android/adapter.h android/adapter.c \
diff --git a/android/adapter.c b/android/adapter.c
index 6ee4a21..48e5e95 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -31,6 +31,10 @@
#include "src/shared/mgmt.h"
#include "src/glib-helper.h"
#include "src/eir.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
+#include "lib/uuid.h"
+#include "src/sdp-client.h"
#include "log.h"
#include "hal-msg.h"
#include "ipc.h"
@@ -41,6 +45,8 @@
#define DEFAULT_IO_CAPABILITY 0x01
static GIOChannel *notification_io = NULL;
+/* This list contains addresses which are asked for records */
+static GList *sdp_req_list;
struct bt_adapter {
uint16_t index;
@@ -59,6 +65,20 @@ struct bt_adapter {
bool discovering;
};
+struct browse_req {
+ bdaddr_t *bdaddr;
+ GSList *uuids;
+ int search_uuid;
+ int reconnect_attempt;
+};
+
+static const uint16_t uuid_list[] = {
+ L2CAP_UUID,
+ PNP_INFO_SVCLASS_ID,
+ PUBLIC_BROWSE_GROUP,
+ 0
+};
+
static struct bt_adapter *adapter;
static GSList *found_devices = NULL;
@@ -1215,9 +1235,80 @@ static uint8_t ssp_reply(void *buf, uint16_t len)
return status;
}
+static void browse_req_free(struct browse_req *req)
+{
+ g_free(req->bdaddr);
+ g_slist_free_full(req->uuids, g_free);
+ g_free(req);
+}
+
+static void update_records(struct browse_req *req, sdp_list_t *recs)
+{
+ /* TODO cache found uuids */
+}
+
+static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
+{
+ struct browse_req *req = user_data;
+ uuid_t uuid;
+
+ /* If we have a valid response and req->search_uuid == 2, then L2CAP
+ * UUID & PNP searching was successful -- we are done */
+ if (err < 0 || req->search_uuid == 2) {
+ if (err == -ECONNRESET && req->reconnect_attempt < 1) {
+ req->search_uuid--;
+ req->reconnect_attempt++;
+ } else {
+ goto done;
+ }
+ }
+
+ update_records(req, recs);
+
+ /* Search for mandatory uuids */
+ if (uuid_list[req->search_uuid]) {
+ sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
+ bt_search_service(&adapter->bdaddr, req->bdaddr, &uuid,
+ browse_cb, user_data, NULL);
+ return;
+ }
+
+done:
+ sdp_req_list = g_list_remove(sdp_req_list, req->bdaddr);
+ browse_req_free(req);
+}
+
static uint8_t get_remote_services(void *buf, uint16_t len)
{
- return HAL_STATUS_UNSUPPORTED;
+ struct hal_cmd_get_remote_services *cmd = buf;
+ struct browse_req *req;
+ bdaddr_t *addr;
+ uuid_t uuid;
+ int err;
+
+ addr = g_new0(bdaddr_t, 1);
+ android2bdaddr(&cmd->bdaddr, addr);
+
+ if (g_list_find_custom(sdp_req_list, addr, bdaddr_cmp)) {
+ g_free(addr);
+ return HAL_STATUS_DONE;
+ }
+
+ sdp_req_list = g_list_append(sdp_req_list, addr);
+
+ req = g_new0(struct browse_req, 1);
+ req->bdaddr = addr;
+ sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
+
+ err = bt_search_service(&adapter->bdaddr,
+ req->bdaddr, &uuid, browse_cb, req, NULL);
+ if (err) {
+ sdp_req_list = g_list_remove(sdp_req_list, req->bdaddr);
+ browse_req_free(req);
+ return HAL_STATUS_FAILED;
+ }
+
+ return HAL_STATUS_SUCCESS;
}
void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
--
1.8.4.1
^ permalink raw reply related
* [PATCH 3/5] android: Add stub for handling get_remote_services command
From: Szymon Janc @ 2013-10-31 15:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1383233152-15040-1-git-send-email-szymon.janc@tieto.com>
From: Marcin Kraglak <marcin.kraglak@tieto.com>
Change-Id: I3a88c104a496fa3c3391b11dc85b6607861158f3
---
android/adapter.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/android/adapter.c b/android/adapter.c
index 10d4a8e..6ee4a21 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -1215,6 +1215,11 @@ static uint8_t ssp_reply(void *buf, uint16_t len)
return status;
}
+static uint8_t get_remote_services(void *buf, uint16_t len)
+{
+ return HAL_STATUS_UNSUPPORTED;
+}
+
void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
uint16_t len)
{
@@ -1308,6 +1313,11 @@ void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
goto error;
break;
+ case HAL_OP_GET_REMOTE_SERVICES:
+ status = get_remote_services(buf, len);
+ if (status != HAL_STATUS_SUCCESS)
+ goto error;
+ break;
default:
DBG("Unhandled command, opcode 0x%x", opcode);
goto error;
--
1.8.4.1
^ permalink raw reply related
* [PATCH 2/5] android/hal: Add support for sending get_remote_services command
From: Szymon Janc @ 2013-10-31 15:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1383233152-15040-1-git-send-email-szymon.janc@tieto.com>
From: Marcin Kraglak <marcin.kraglak@tieto.com>
Change-Id: I99c92d8a3f3d915d1e06ecad2515fcbcbb5b660a
---
android/hal-bluetooth.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index a6228d7..4eab869 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -476,12 +476,18 @@ static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
static int get_remote_services(bt_bdaddr_t *remote_addr)
{
+ struct hal_cmd_get_remote_services cmd;
+
DBG("");
if (!interface_ready())
return BT_STATUS_NOT_READY;
- return BT_STATUS_UNSUPPORTED;
+ memcpy(cmd.bdaddr, remote_addr, sizeof(cmd.bdaddr));
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH,
+ HAL_OP_GET_REMOTE_SERVICES, sizeof(cmd),
+ &cmd, 0, NULL, NULL);
}
static int start_discovery(void)
--
1.8.4.1
^ permalink raw reply related
* [PATCH 1/5] android: Fix typo in get_remote_services command
From: Szymon Janc @ 2013-10-31 15:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcin Kraglak
From: Marcin Kraglak <marcin.kraglak@tieto.com>
Change-Id: Ia38b82b4b7fdbd6e52389b34e1cdbbcfd098958c
---
android/hal-msg.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 8a344d8..c0af083 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -148,8 +148,8 @@ struct hal_cmd_get_remote_service_rec {
uint8_t uuid[16];
} __attribute__((packed));
-#define HAL_OP_GET_REMOTE_SERVICE 0x0a
-struct hal_cmd_get_remote_service {
+#define HAL_OP_GET_REMOTE_SERVICES 0x0a
+struct hal_cmd_get_remote_services {
uint8_t bdaddr[6];
} __attribute__((packed));
--
1.8.4.1
^ permalink raw reply related
* Re: [PATCH] android: Add support for setting adapters name
From: Grzegorz Kolodziejczyk @ 2013-10-31 15:16 UTC (permalink / raw)
To: Andrei Emeltchenko, Grzegorz Kolodziejczyk, linux-bluetooth
In-Reply-To: <20131031142138.GM27517@aemeltch-MOBL1>
Hi Andrei,
On 31 October 2013 15:21, Andrei Emeltchenko
<andrei.emeltchenko.news@gmail.com> wrote:
>
> Hi Grzegorz,
>
> On Thu, Oct 31, 2013 at 03:00:38PM +0100, Grzegorz Kolodziejczyk wrote:
> > ---
> > android/adapter.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> > android/hal-msg.h | 2 ++
> > 2 files changed, 55 insertions(+)
> >
> > diff --git a/android/adapter.c b/android/adapter.c
> > index 15b65e5..5dadc2e 100644
> > --- a/android/adapter.c
> > +++ b/android/adapter.c
> > @@ -129,6 +129,27 @@ static void scan_mode_changed(void)
> > g_free(ev);
> > }
> >
> > +static void adapter_name_changed(const uint8_t *name)
> > +{
> > + struct hal_ev_adapter_props_changed *ev;
> > + uint8_t buf[sizeof(*ev) + sizeof(struct hal_property) +
> > + HAL_MAX_NAME_LENGTH];
> > +
> > + memset(buf, 0, sizeof(buf));
> > + ev = (void *) buf;
> > +
> > + ev->num_props = 1;
> > + ev->status = HAL_STATUS_SUCCESS;
> > + ev->props[0].type = HAL_PROP_ADAPTER_NAME;
> > + ev->props[0].len = HAL_MAX_NAME_LENGTH;
>
> Do we need to pass always HAL_MAX_NAME_LENGTH ?
>
Yes, HAL expect 249 byte size array. IPC should map to HAL calls,
where name is expected to have 249 bytes.
Best regards,
Grzegorz Kołodziejczyk
^ permalink raw reply
* Re: [PATCH 1/2] android/hidhost: Fix not unregistering HID
From: Johan Hedberg @ 2013-10-31 14:58 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1383230705-18110-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Thu, Oct 31, 2013, Andrei Emeltchenko wrote:
> If HID is not unregistered it cannot be registered again and we get
> following error:
> ...
> E/BluetoothHidServiceJni( 2849): Failed to initialize Bluetooth HID, status: 1
> ...
> ---
> android/hal-hidhost.c | 7 +++++++
> 1 file changed, 7 insertions(+)
Both patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 1/5] android: Add support for starting and cancelling device discovery
From: Johan Hedberg @ 2013-10-31 14:52 UTC (permalink / raw)
To: Jakub Tyszkowski; +Cc: linux-bluetooth
In-Reply-To: <1383229534-17157-1-git-send-email-jakub.tyszkowski@tieto.com>
Hi Jakub,
On Thu, Oct 31, 2013, Jakub Tyszkowski wrote:
> Android will cancel ongoing discovery after some period of time so there
> is no need for another timeout inside the daemon itself.
>
> ---
> android/adapter.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 107 insertions(+), 1 deletion(-)
All five patches have been applied. Thanks.
Johan
^ permalink raw reply
* [PATCH 2/2] android/hid: Add error message to error print
From: Andrei Emeltchenko @ 2013-10-31 14:45 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1383230705-18110-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/hid.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/android/hid.c b/android/hid.c
index 5caa25b..4075ecb 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -419,7 +419,7 @@ bool bt_hid_register(GIOChannel *io, const bdaddr_t *addr)
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
BT_IO_OPT_INVALID);
if (!ctrl_io) {
- error("Failed to listen on control channel");
+ error("Failed to listen on ctrl channel: %s", err->message);
g_error_free(err);
return false;
}
@@ -429,7 +429,7 @@ bool bt_hid_register(GIOChannel *io, const bdaddr_t *addr)
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
BT_IO_OPT_INVALID);
if (!intr_io) {
- error("Failed to listen on interrupt channel");
+ error("Failed to listen on intr channel: %s", err->message);
g_io_channel_unref(ctrl_io);
g_error_free(err);
return false;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/2] android/hidhost: Fix not unregistering HID
From: Andrei Emeltchenko @ 2013-10-31 14:45 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
If HID is not unregistered it cannot be registered again and we get
following error:
...
E/BluetoothHidServiceJni( 2849): Failed to initialize Bluetooth HID, status: 1
...
---
android/hal-hidhost.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index a72410b..e148dc2 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -301,12 +301,19 @@ static bt_status_t hh_init(bthh_callbacks_t *callbacks)
static void hh_cleanup(void)
{
+ struct hal_cmd_unregister_module cmd;
+
DBG("");
if (!interface_ready())
return;
bt_hh_cbacks = NULL;
+
+ cmd.service_id = HAL_SERVICE_ID_HIDHOST;
+
+ hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
+ sizeof(cmd), &cmd, 0, NULL, NULL);
}
static bthh_interface_t hh_if = {
--
1.7.10.4
^ permalink raw reply related
* Re: l2cap sockets not properly multiplexed on ARM
From: Marcel Holtmann @ 2013-10-31 14:41 UTC (permalink / raw)
To: Tim Tisdall; +Cc: Alexander Holler, linux-bluetooth@vger.kernel.org
In-Reply-To: <D9B9EB3A112B8F489DFFA00A6D5C0FE203241DC5@AD-BR-EX-2.adroot.flemingc.local>
Hi Tim,
>> I actually need to know if bluetooth-next tree still has this issue. That is first and foremost the one thing that needs to be checked.
>
> I really doubt it's an issue with bluetooth-next as it's only been an issue with kernel versions 3.4.X and older.
>
> I'm not familiar with how kernel development goes, so I'm not sure I completely understand what "bluetooth-next" entails. Aren't there different maintainers for the different major versions of the kernel and don't they update the in-built modules where ever possible? Is "bluetooth-next" tied to a particular kernel version or does it support a range of versions as it's a module?
bluetooth-next is what will become kernel 3.13 at some point when Linus releases it. It is code that is on its way towards official Linux trees.
If bluetooth-next works as expected, then you could just git bisect and root cause the patch that fixed it. However first you have to establish if bluetooth-next kernel works or not.
Regards
Marcel
^ permalink raw reply
* RE: l2cap sockets not properly multiplexed on ARM
From: Tim Tisdall @ 2013-10-31 14:29 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: Alexander Holler, linux-bluetooth@vger.kernel.org
In-Reply-To: <F9B30CD6-4DCB-4F58-9322-E18969867664@holtmann.org>
> I actually need to know if bluetooth-next tree still has this issue. That=
is first and foremost the one thing that needs to be checked.=0A=
=0A=
I really doubt it's an issue with bluetooth-next as it's only been an issue=
with kernel versions 3.4.X and older.=0A=
=0A=
I'm not familiar with how kernel development goes, so I'm not sure I comple=
tely understand what "bluetooth-next" entails. Aren't there different main=
tainers for the different major versions of the kernel and don't they updat=
e the in-built modules where ever possible? Is "bluetooth-next" tied to a =
particular kernel version or does it support a range of versions as it's a =
module?=
^ permalink raw reply
* [PATCH 5/5] android: Add support for remote device name confirmation
From: Jakub Tyszkowski @ 2013-10-31 14:25 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1383229534-17157-1-git-send-email-jakub.tyszkowski@tieto.com>
---
android/adapter.c | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/android/adapter.c b/android/adapter.c
index e72e45b..10d4a8e 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -390,6 +390,28 @@ static void mgmt_discovering_event(uint16_t index, uint16_t length,
sizeof(cp), &cp, -1);
}
+static void confirm_name_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ if (status != MGMT_STATUS_SUCCESS)
+ error("Failed to confirm name: %s (0x%02x)",
+ mgmt_errstr(status), status);
+}
+
+static void confirm_device_name(const bdaddr_t *addr, uint8_t addr_type)
+{
+ struct mgmt_cp_confirm_name cp;
+
+ memset(&cp, 0, sizeof(cp));
+ bacpy(&cp.addr.bdaddr, addr);
+ cp.addr.type = addr_type;
+
+ if (mgmt_reply(adapter->mgmt, MGMT_OP_CONFIRM_NAME, adapter->index,
+ sizeof(cp), &cp, confirm_name_complete,
+ NULL, NULL) == 0)
+ error("Failed to send confirm name request");
+}
+
static int bdaddr_cmp(gconstpointer a, gconstpointer b)
{
const bdaddr_t *bda = a;
@@ -519,7 +541,13 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
g_free(buf);
}
- /* TODO: name confirmation */
+ if (confirm) {
+ char addr[18];
+
+ ba2str(bdaddr, addr);
+ info("Device %s needs name confirmation.", addr);
+ confirm_device_name(bdaddr, bdaddr_type);
+ }
eir_data_free(&eir);
}
--
1.8.4.1
^ permalink raw reply related
* [PATCH 4/5] android: Add device found notifications passing
From: Jakub Tyszkowski @ 2013-10-31 14:25 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1383229534-17157-1-git-send-email-jakub.tyszkowski@tieto.com>
This patch adds remote device found and remote device properties changed
notifications passing using IPC.
---
android/adapter.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 82 insertions(+), 2 deletions(-)
diff --git a/android/adapter.c b/android/adapter.c
index 154dd06..e72e45b 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -398,11 +398,45 @@ static int bdaddr_cmp(gconstpointer a, gconstpointer b)
return bacmp(bdb, bda);
}
+static int fill_device_props(struct hal_property *prop, bdaddr_t *addr,
+ uint32_t cod, int8_t rssi, char *name)
+{
+ uint8_t num_props = 0;
+
+ /* fill cod */
+ prop->type = HAL_PROP_DEVICE_CLASS;
+ prop->len = sizeof(cod);
+ memcpy(prop->val, &cod, prop->len);
+ prop = ((void *) prop) + sizeof(*prop) + sizeof(cod);
+ num_props++;
+
+ /* fill rssi */
+ prop->type = HAL_PROP_DEVICE_RSSI;
+ prop->len = sizeof(rssi);
+ memcpy(prop->val, &rssi, prop->len);
+ prop = ((void *) prop) + sizeof(*prop) + sizeof(rssi);
+ num_props++;
+
+ /* fill name */
+ if (name) {
+ prop->type = HAL_PROP_DEVICE_NAME;
+ prop->len = HAL_MAX_NAME_LENGTH;
+ strncpy((char *) prop->val, name, HAL_MAX_NAME_LENGTH - 1);
+ prop = ((void *) prop) + sizeof(*prop) + HAL_MAX_NAME_LENGTH;
+ num_props++;
+ }
+
+ return num_props;
+}
+
static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
int8_t rssi, bool confirm,
const uint8_t *data, uint8_t data_len)
{
bool is_new_dev = false;
+ size_t props_size = 0;
+ size_t buff_size = 0;
+ void *buf;
struct eir_data eir;
GSList *l;
bdaddr_t *remote = NULL;
@@ -433,10 +467,56 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
DBG("New device found: %s", addr);
}
+ props_size += sizeof(struct hal_property) + sizeof(eir.class);
+ props_size += sizeof(struct hal_property) + sizeof(rssi);
+
+ if (eir.name)
+ props_size += sizeof(struct hal_property) + HAL_MAX_NAME_LENGTH;
+
if (is_new_dev) {
- /* TODO: notify device found */
+ struct hal_ev_device_found *ev = NULL;
+ struct hal_property *prop = NULL;
+
+ /* with new device we also send bdaddr prop */
+ props_size += sizeof(struct hal_property) + sizeof(eir.addr);
+
+ buff_size = sizeof(struct hal_ev_device_found) + props_size;
+ buf = g_new0(char, buff_size);
+ ev = buf;
+ prop = ev->props;
+
+ /* fill first prop with bdaddr */
+ prop->type = HAL_PROP_DEVICE_ADDR;
+ prop->len = sizeof(bdaddr_t);
+ bdaddr2android(bdaddr, prop->val);
+ prop = ((void *) prop) + sizeof(*prop) + sizeof(bdaddr_t);
+ ev->num_props += 1;
+
+ /* fill eir, name, and cod props */
+ ev->num_props += fill_device_props(prop, remote, eir.class,
+ rssi, eir.name);
+
+ ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+ HAL_EV_DEVICE_FOUND,
+ buff_size, ev, -1);
+ g_free(buf);
} else {
- /* TODO: notify device state changed */
+ struct hal_ev_remote_device_props *ev = NULL;
+
+ buff_size = sizeof(*ev) + props_size;
+ buf = g_new0(char, buff_size);
+ ev = buf;
+
+ ev->num_props = fill_device_props(ev->props, remote, eir.class,
+ rssi, eir.name);
+
+ ev->status = HAL_STATUS_SUCCESS;
+ bdaddr2android(bdaddr, ev->bdaddr);
+
+ ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+ HAL_EV_REMOTE_DEVICE_PROPS,
+ buff_size, ev, -1);
+ g_free(buf);
}
/* TODO: name confirmation */
--
1.8.4.1
^ permalink raw reply related
* [PATCH 3/5] android: Add name property length define
From: Jakub Tyszkowski @ 2013-10-31 14:25 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1383229534-17157-1-git-send-email-jakub.tyszkowski@tieto.com>
Add define for adapter and remote device name property.
---
android/hal-msg.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index b792411..8a344d8 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -89,6 +89,8 @@ struct hal_cmd_get_adapter_prop {
uint8_t type;
} __attribute__((packed));
+#define HAL_MAX_NAME_LENGTH 249
+
#define HAL_PROP_ADAPTER_NAME 0x01
#define HAL_PROP_ADAPTER_ADDR 0x02
#define HAL_PROP_ADAPTER_UUIDS 0x03
--
1.8.4.1
^ permalink raw reply related
* [PATCH 2/5] android: Add device discovery mgmt event handling
From: Jakub Tyszkowski @ 2013-10-31 14:25 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1383229534-17157-1-git-send-email-jakub.tyszkowski@tieto.com>
This patch provides basic handling of device found events from management
interface. Temporary device adress list is being used to determine which
devices has already been reported and device property changed event should
be sent instead of device found event.
---
android/Android.mk | 2 +
android/Makefile.am | 2 +
android/adapter.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 111 insertions(+), 2 deletions(-)
diff --git a/android/Android.mk b/android/Android.mk
index e47f4a9..ef9ebf3 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -32,6 +32,8 @@ LOCAL_SRC_FILES := \
../src/sdpd-service.c \
../src/sdpd-request.c \
../src/sdpd-server.c \
+ ../src/glib-helper.c \
+ ../src/eir.c \
../lib/sdp.c \
../lib/bluetooth.c \
../lib/hci.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index 05a124e..989b54d 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -7,6 +7,8 @@ android_bluetoothd_SOURCES = android/main.c \
android/utils.h \
src/sdpd-database.c src/sdpd-server.c \
src/sdpd-service.c src/sdpd-request.c \
+ src/glib-helper.h src/glib-helper.c \
+ src/eir.h src/eir.c \
src/shared/util.h src/shared/util.c \
src/shared/mgmt.h src/shared/mgmt.c \
android/adapter.h android/adapter.c \
diff --git a/android/adapter.c b/android/adapter.c
index a12ccb3..154dd06 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -29,6 +29,8 @@
#include "lib/sdp.h"
#include "lib/mgmt.h"
#include "src/shared/mgmt.h"
+#include "src/glib-helper.h"
+#include "src/eir.h"
#include "log.h"
#include "hal-msg.h"
#include "ipc.h"
@@ -58,6 +60,7 @@ struct bt_adapter {
};
static struct bt_adapter *adapter;
+static GSList *found_devices = NULL;
static void mgmt_local_name_changed_event(uint16_t index, uint16_t length,
const void *param, void *user_data)
@@ -373,14 +376,113 @@ static void mgmt_discovering_event(uint16_t index, uint16_t length,
DBG("new discovering state %u", ev->discovering);
- cp.state = adapter->discovering ? HAL_DISCOVERY_STATE_STARTED :
- HAL_DISCOVERY_STATE_STOPPED;
+ if (adapter->discovering) {
+ cp.state = HAL_DISCOVERY_STATE_STARTED;
+ } else {
+ g_slist_free_full(found_devices, g_free);
+ found_devices = NULL;
+
+ cp.state = HAL_DISCOVERY_STATE_STOPPED;
+ }
ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
HAL_EV_DISCOVERY_STATE_CHANGED,
sizeof(cp), &cp, -1);
}
+static int bdaddr_cmp(gconstpointer a, gconstpointer b)
+{
+ const bdaddr_t *bda = a;
+ const bdaddr_t *bdb = b;
+
+ return bacmp(bdb, bda);
+}
+
+static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
+ int8_t rssi, bool confirm,
+ const uint8_t *data, uint8_t data_len)
+{
+ bool is_new_dev = false;
+ struct eir_data eir;
+ GSList *l;
+ bdaddr_t *remote = NULL;
+ int err;
+
+ memset(&eir, 0, sizeof(eir));
+
+ err = eir_parse(&eir, data, data_len);
+ if (err < 0) {
+ error("Error parsing EIR data: %s (%d)", strerror(-err), -err);
+ return;
+ }
+
+ l = g_slist_find_custom(found_devices, bdaddr, bdaddr_cmp);
+ if (l)
+ remote = l->data;
+
+ if (!remote) {
+ char addr[18];
+
+ remote = g_new0(bdaddr_t, 1);
+ bacpy(remote, bdaddr);
+
+ found_devices = g_slist_prepend(found_devices, remote);
+ is_new_dev = true;
+
+ ba2str(remote, addr);
+ DBG("New device found: %s", addr);
+ }
+
+ if (is_new_dev) {
+ /* TODO: notify device found */
+ } else {
+ /* TODO: notify device state changed */
+ }
+
+ /* TODO: name confirmation */
+
+ eir_data_free(&eir);
+}
+
+static void mgmt_device_found_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_ev_device_found *ev = param;
+ const uint8_t *eir;
+ uint16_t eir_len;
+ uint32_t flags;
+ bool confirm_name;
+ char addr[18];
+
+ if (length < sizeof(*ev)) {
+ error("Too short device found event (%u bytes)", length);
+ return;
+ }
+
+ eir_len = btohs(ev->eir_len);
+ if (length != sizeof(*ev) + eir_len) {
+ error("Device found event size mismatch (%u != %zu)",
+ length, sizeof(*ev) + eir_len);
+ return;
+ }
+
+ if (eir_len == 0)
+ eir = NULL;
+ else
+ eir = ev->eir;
+
+ flags = btohl(ev->flags);
+
+ ba2str(&ev->addr.bdaddr, addr);
+ DBG("hci%u addr %s, rssi %d flags 0x%04x eir_len %u eir %u",
+ index, addr, ev->rssi, flags, eir_len, *eir);
+
+ confirm_name = flags & MGMT_DEV_FOUND_CONFIRM_NAME;
+
+ update_found_device(&ev->addr.bdaddr, ev->addr.type, ev->rssi,
+ confirm_name, eir, eir_len);
+}
+
static void register_mgmt_handlers(void)
{
mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->index,
@@ -415,6 +517,9 @@ static void register_mgmt_handlers(void)
mgmt_discovering_event,
NULL, NULL);
+ mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_FOUND,
+ adapter->index, mgmt_device_found_event,
+ NULL, NULL);
}
static void load_link_keys_complete(uint8_t status, uint16_t length,
--
1.8.4.1
^ permalink raw reply related
* [PATCH 1/5] android: Add support for starting and cancelling device discovery
From: Jakub Tyszkowski @ 2013-10-31 14:25 UTC (permalink / raw)
To: linux-bluetooth
Android will cancel ongoing discovery after some period of time so there
is no need for another timeout inside the daemon itself.
---
android/adapter.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 107 insertions(+), 1 deletion(-)
diff --git a/android/adapter.c b/android/adapter.c
index 02f356d..a12ccb3 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -26,8 +26,9 @@
#include <glib.h>
#include "lib/bluetooth.h"
-#include "src/shared/mgmt.h"
+#include "lib/sdp.h"
#include "lib/mgmt.h"
+#include "src/shared/mgmt.h"
#include "log.h"
#include "hal-msg.h"
#include "ipc.h"
@@ -52,6 +53,8 @@ struct bt_adapter {
uint32_t supported_settings;
uint32_t current_settings;
+
+ bool discovering;
};
static struct bt_adapter *adapter;
@@ -349,6 +352,35 @@ static void user_passkey_notify_callback(uint16_t index, uint16_t length,
ev->passkey);
}
+static void mgmt_discovering_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_ev_discovering *ev = param;
+ struct hal_ev_discovery_state_changed cp;
+
+ if (length < sizeof(*ev)) {
+ error("Too small discovering event");
+ return;
+ }
+
+ DBG("hci%u type %u discovering %u", adapter->index, ev->type,
+ ev->discovering);
+
+ if (adapter->discovering == !!ev->discovering)
+ return;
+
+ adapter->discovering = !!ev->discovering;
+
+ DBG("new discovering state %u", ev->discovering);
+
+ cp.state = adapter->discovering ? HAL_DISCOVERY_STATE_STARTED :
+ HAL_DISCOVERY_STATE_STOPPED;
+
+ ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+ HAL_EV_DISCOVERY_STATE_CHANGED,
+ sizeof(cp), &cp, -1);
+}
+
static void register_mgmt_handlers(void)
{
mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->index,
@@ -379,6 +411,10 @@ static void register_mgmt_handlers(void)
mgmt_register(adapter->mgmt, MGMT_EV_PASSKEY_NOTIFY, adapter->index,
user_passkey_notify_callback, NULL, NULL);
+ mgmt_register(adapter->mgmt, MGMT_EV_DISCOVERING, adapter->index,
+ mgmt_discovering_event,
+ NULL, NULL);
+
}
static void load_link_keys_complete(uint8_t status, uint16_t length,
@@ -551,6 +587,7 @@ void bt_adapter_init(uint16_t index, struct mgmt *mgmt, bt_adapter_ready cb)
adapter->mgmt = mgmt_ref(mgmt);
adapter->index = index;
+ adapter->discovering = false;
adapter->ready = cb;
if (mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
@@ -624,6 +661,46 @@ static bool get_property(void *buf, uint16_t len)
}
}
+static bool start_discovery(void)
+{
+ struct mgmt_cp_start_discovery cp;
+ uint8_t type = 1 << BDADDR_BREDR;
+
+ if (adapter->current_settings & type)
+ cp.type = type;
+ else
+ cp.type = 0;
+
+ DBG("type=0x%x", type);
+
+ if (mgmt_send(adapter->mgmt, MGMT_OP_START_DISCOVERY, adapter->index,
+ sizeof(cp), &cp, NULL, NULL, NULL) > 0)
+ return true;
+
+ error("Failed to start discovery");
+ return false;
+}
+
+static bool stop_discovery(void)
+{
+ struct mgmt_cp_stop_discovery cp;
+ uint8_t type = 1 << BDADDR_BREDR;
+
+ if (adapter->current_settings & type)
+ cp.type = type;
+ else
+ cp.type = 0;
+
+ DBG("type=0x%x", type);
+
+ if (mgmt_send(adapter->mgmt, MGMT_OP_STOP_DISCOVERY, adapter->index,
+ sizeof(cp), &cp, NULL, NULL, NULL) > 0)
+ return true;
+
+ error("Failed to start discovery");
+ return false;
+}
+
static uint8_t set_scan_mode(void *buf, uint16_t len)
{
uint8_t *mode = buf;
@@ -987,6 +1064,35 @@ void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
status = ssp_reply(buf, len);
if (status != HAL_STATUS_SUCCESS)
goto error;
+ break;
+ case HAL_OP_START_DISCOVERY:
+ if (adapter->discovering) {
+ status = HAL_STATUS_DONE;
+ goto error;
+ }
+
+ if (!(adapter->current_settings & MGMT_SETTING_POWERED)) {
+ status = HAL_STATUS_NOT_READY;
+ goto error;
+ }
+
+ if (!start_discovery())
+ goto error;
+
+ break;
+ case HAL_OP_CANCEL_DISCOVERY:
+ if (!adapter->discovering) {
+ status = HAL_STATUS_DONE;
+ goto error;
+ }
+
+ if (!(adapter->current_settings & MGMT_SETTING_POWERED)) {
+ status = HAL_STATUS_NOT_READY;
+ goto error;
+ }
+
+ if (!stop_discovery())
+ goto error;
break;
default:
--
1.8.4.1
^ permalink raw reply related
* Re: [PATCH] android: Add support for setting adapters name
From: Andrei Emeltchenko @ 2013-10-31 14:21 UTC (permalink / raw)
To: Grzegorz Kolodziejczyk; +Cc: linux-bluetooth
In-Reply-To: <1383228038-4306-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
Hi Grzegorz,
On Thu, Oct 31, 2013 at 03:00:38PM +0100, Grzegorz Kolodziejczyk wrote:
> ---
> android/adapter.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> android/hal-msg.h | 2 ++
> 2 files changed, 55 insertions(+)
>
> diff --git a/android/adapter.c b/android/adapter.c
> index 15b65e5..5dadc2e 100644
> --- a/android/adapter.c
> +++ b/android/adapter.c
> @@ -129,6 +129,27 @@ static void scan_mode_changed(void)
> g_free(ev);
> }
>
> +static void adapter_name_changed(const uint8_t *name)
> +{
> + struct hal_ev_adapter_props_changed *ev;
> + uint8_t buf[sizeof(*ev) + sizeof(struct hal_property) +
> + HAL_MAX_NAME_LENGTH];
> +
> + memset(buf, 0, sizeof(buf));
> + ev = (void *) buf;
> +
> + ev->num_props = 1;
> + ev->status = HAL_STATUS_SUCCESS;
> + ev->props[0].type = HAL_PROP_ADAPTER_NAME;
> + ev->props[0].len = HAL_MAX_NAME_LENGTH;
Do we need to pass always HAL_MAX_NAME_LENGTH ?
Best regards
Andrei Emeltchenko
> + memcpy(ev->props->val, name, HAL_MAX_NAME_LENGTH);
> +
> + DBG("Adapter name changed to: %s", ev->props->val);
> +
> + ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
> + HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), ev, -1);
> +}
> +
> static void settings_changed(uint32_t settings)
> {
> uint32_t changed_mask;
> @@ -286,6 +307,37 @@ static bool set_mode(uint16_t opcode, uint8_t mode)
> return false;
> }
>
> +static void set_adapter_name_complete(uint8_t status, uint16_t length,
> + const void *param, void *user_data)
> +{
> + const struct mgmt_cp_set_local_name *rp = param;
> +
> + if (status != MGMT_STATUS_SUCCESS) {
> + error("Failed to set name: %s (0x%02x)",
> + mgmt_errstr(status), status);
> + return;
> + }
> +
> + adapter_name_changed(rp->name);
> +}
> +
> +static bool set_adapter_name(uint8_t *name, uint16_t len)
> +{
> + struct mgmt_cp_set_local_name cp;
> +
> + memset(&cp, 0, sizeof(cp));
> + memcpy(cp.name, name, len);
> +
> + if (mgmt_send(adapter->mgmt, MGMT_OP_SET_LOCAL_NAME, adapter->index,
> + sizeof(cp), &cp, set_adapter_name_complete, NULL,
> + NULL) > 0)
> + return true;
> +
> + error("Failed to set name");
> +
> + return false;
> +}
> +
> static void read_info_complete(uint8_t status, uint16_t length, const void *param,
> void *user_data)
> {
> @@ -472,6 +524,7 @@ static uint8_t set_property(void *buf, uint16_t len)
> case HAL_PROP_ADAPTER_SCAN_MODE:
> return set_scan_mode(cmd->val, cmd->len);
> case HAL_PROP_ADAPTER_NAME:
> + return set_adapter_name(cmd->val, cmd->len);
> case HAL_PROP_ADAPTER_DISC_TIMEOUT:
> default:
> DBG("Unhandled property type 0x%x", cmd->type);
> diff --git a/android/hal-msg.h b/android/hal-msg.h
> index 80b47d6..506d10c 100644
> --- a/android/hal-msg.h
> +++ b/android/hal-msg.h
> @@ -89,6 +89,8 @@ struct hal_cmd_get_adapter_prop {
> uint8_t type;
> } __attribute__((packed));
>
> +#define HAL_MAX_NAME_LENGTH 249
> +
> #define HAL_PROP_ADAPTER_NAME 0x01
> #define HAL_PROP_ADAPTER_ADDR 0x02
> #define HAL_PROP_ADAPTER_UUIDS 0x03
> --
> 1.8.4.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox