* [RFC v5 03/14] Bluetooth: Introduce connection parameters list
From: Andre Guedes @ 2013-12-20 11:57 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387540675-2466-1-git-send-email-andre.guedes@openbossa.org>
This patch adds to hdev the connection parameters list (hdev->le_
conn_params). The elements from this list (struct hci_conn_params)
contains the connection parameters (for now, minimum and maximum
connection interval) that should be used during the connection
establishment.
The struct hci_conn_params also defines the 'auto_connect' field
which will be used to implement the auto connection mechanism.
Moreover, this patch adds helper functions to manipulate hdev->le_
conn_params list. Some of these functions are also declared in
hci_core.h since they will be used outside hci_core.c in upcoming
patches.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 25 +++++++++++++
net/bluetooth/hci_core.c | 80 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 105 insertions(+)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f970fc2..9a8076e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -267,6 +267,7 @@ struct hci_dev {
struct list_head link_keys;
struct list_head long_term_keys;
struct list_head remote_oob_data;
+ struct list_head le_conn_params;
struct hci_dev_stats stat;
@@ -371,6 +372,22 @@ struct hci_chan {
__u8 state;
};
+struct hci_conn_params {
+ struct list_head list;
+
+ bdaddr_t addr;
+ u8 addr_type;
+
+ enum {
+ HCI_AUTO_CONN_DISABLED,
+ HCI_AUTO_CONN_ALWAYS,
+ HCI_AUTO_CONN_LINK_LOSS,
+ } auto_connect;
+
+ u16 conn_min_interval;
+ u16 conn_max_interval;
+};
+
extern struct list_head hci_dev_list;
extern struct list_head hci_cb_list;
extern rwlock_t hci_dev_list_lock;
@@ -740,6 +757,14 @@ int hci_blacklist_clear(struct hci_dev *hdev);
int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
+struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
+ bdaddr_t *addr, u8 addr_type);
+void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
+ u8 auto_connect, u16 conn_min_interval,
+ u16 conn_max_interval);
+void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
+void hci_conn_params_clear(struct hci_dev *hdev);
+
int hci_uuids_clear(struct hci_dev *hdev);
int hci_link_keys_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b23d403..dac1d18 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2818,6 +2818,84 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
return mgmt_device_unblocked(hdev, bdaddr, type);
}
+/* This function requires the caller holds hdev->lock */
+struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
+ bdaddr_t *addr, u8 addr_type)
+{
+ struct hci_conn_params *params;
+
+ list_for_each_entry(params, &hdev->le_conn_params, list) {
+ if (bacmp(¶ms->addr, addr) == 0 &&
+ params->addr_type == addr_type) {
+ return params;
+ }
+ }
+
+ return NULL;
+}
+
+/* This function requires the caller holds hdev->lock */
+void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
+ u8 auto_connect, u16 conn_min_interval,
+ u16 conn_max_interval)
+{
+ struct hci_conn_params *params;
+
+ params = hci_conn_params_lookup(hdev, addr, addr_type);
+ if (params) {
+ params->auto_connect = auto_connect;
+ params->conn_min_interval = conn_min_interval;
+ params->conn_max_interval = conn_max_interval;
+ return;
+ }
+
+ params = kzalloc(sizeof(*params), GFP_KERNEL);
+ if (!params) {
+ BT_ERR("Out of memory");
+ return;
+ }
+
+ bacpy(¶ms->addr, addr);
+ params->addr_type = addr_type;
+ params->auto_connect = auto_connect;
+ params->conn_min_interval = conn_min_interval;
+ params->conn_max_interval = conn_max_interval;
+
+ list_add(¶ms->list, &hdev->le_conn_params);
+
+ BT_DBG("addr %pMR (type %u) auto_connect %u conn_min_interval 0x%.4x "
+ "conn_max_interval 0x%.4x", addr, addr_type, auto_connect,
+ conn_min_interval, conn_max_interval);
+}
+
+/* This function requires the caller holds hdev->lock */
+void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
+{
+ struct hci_conn_params *params;
+
+ params = hci_conn_params_lookup(hdev, addr, addr_type);
+ if (!params)
+ return;
+
+ list_del(¶ms->list);
+ kfree(params);
+
+ BT_DBG("addr %pMR (type %u)", addr, addr_type);
+}
+
+/* This function requires the caller holds hdev->lock */
+void hci_conn_params_clear(struct hci_dev *hdev)
+{
+ struct hci_conn_params *params, *tmp;
+
+ list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
+ list_del(¶ms->list);
+ kfree(params);
+ }
+
+ BT_DBG("All LE connection parameters were removed");
+}
+
static void inquiry_complete(struct hci_dev *hdev, u8 status)
{
if (status) {
@@ -2928,6 +3006,7 @@ struct hci_dev *hci_alloc_dev(void)
INIT_LIST_HEAD(&hdev->link_keys);
INIT_LIST_HEAD(&hdev->long_term_keys);
INIT_LIST_HEAD(&hdev->remote_oob_data);
+ INIT_LIST_HEAD(&hdev->le_conn_params);
INIT_LIST_HEAD(&hdev->conn_hash.list);
INIT_WORK(&hdev->rx_work, hci_rx_work);
@@ -3113,6 +3192,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
hci_link_keys_clear(hdev);
hci_smp_ltks_clear(hdev);
hci_remote_oob_data_clear(hdev);
+ hci_conn_params_clear(hdev);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
--
1.8.5.1
^ permalink raw reply related
* [RFC v5 02/14] Bluetooth: Group list_head fields from strcut hci_dev together
From: Andre Guedes @ 2013-12-20 11:57 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387540675-2466-1-git-send-email-andre.guedes@openbossa.org>
This patch groups the list_head fields from struct hci_dev together
and removes empty lines between them.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2ebe772..f970fc2 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -257,18 +257,15 @@ struct hci_dev {
__u32 req_status;
__u32 req_result;
- struct list_head mgmt_pending;
struct discovery_state discovery;
struct hci_conn_hash conn_hash;
- struct list_head blacklist;
+ struct list_head mgmt_pending;
+ struct list_head blacklist;
struct list_head uuids;
-
struct list_head link_keys;
-
struct list_head long_term_keys;
-
struct list_head remote_oob_data;
struct hci_dev_stats stat;
--
1.8.5.1
^ permalink raw reply related
* [RFC v5 01/14] Bluetooth: Save connection interval parameters in hci_conn
From: Andre Guedes @ 2013-12-20 11:57 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387540675-2466-1-git-send-email-andre.guedes@openbossa.org>
This patch creates two new fields in struct hci_conn to save the
minimum and maximum connection interval values used to establish
the connection this object represents.
This change is required in order to know what parameters the
connection is currently using.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 2 ++
net/bluetooth/hci_conn.c | 6 ++++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f2f0cf5..2ebe772 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -332,6 +332,8 @@ struct hci_conn {
__u8 passkey_entered;
__u16 disc_timeout;
__u16 setting;
+ __u16 le_conn_min_interval;
+ __u16 le_conn_max_interval;
unsigned long flags;
__u8 remote_cap;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ba5366c..15c689e 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -558,8 +558,8 @@ static int hci_create_le_conn(struct hci_conn *conn)
bacpy(&cp.peer_addr, &conn->dst);
cp.peer_addr_type = conn->dst_type;
cp.own_address_type = conn->src_type;
- cp.conn_interval_min = cpu_to_le16(hdev->le_conn_min_interval);
- cp.conn_interval_max = cpu_to_le16(hdev->le_conn_max_interval);
+ cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
+ cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
cp.min_ce_len = __constant_cpu_to_le16(0x0000);
cp.max_ce_len = __constant_cpu_to_le16(0x0000);
@@ -624,6 +624,8 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
conn->sec_level = BT_SECURITY_LOW;
conn->pending_sec_level = sec_level;
conn->auth_type = auth_type;
+ conn->le_conn_min_interval = hdev->le_conn_min_interval;
+ conn->le_conn_max_interval = hdev->le_conn_max_interval;
err = hci_create_le_conn(conn);
if (err)
--
1.8.5.1
^ permalink raw reply related
* [RFC v5 00/14] LE auto connection and connection parameters
From: Andre Guedes @ 2013-12-20 11:57 UTC (permalink / raw)
To: linux-bluetooth
Hi all,
This patch set is pretty much the same of previous one, except it implements
a different approach to handle discovery and LE connection (as discussed on
"[RFC v4 05/12] Bluetooth: Stop scanning on LE connection").
Regards,
Andre
Andre Guedes (14):
Bluetooth: Save connection interval parameters in hci_conn
Bluetooth: Group list_head fields from strcut hci_dev together
Bluetooth: Introduce connection parameters list
Bluetooth: Use connection parameters if any
Bluetooth: Introduce fail_conn_attempt() helper
Bluetooth: Stop scanning on LE connection
Bluetooth: Remove unused function
Bluetooth: Introduce hdev->pend_le_conn list
Bluetooth: Introduce LE auto connection infrastructure
Bluetooth: Re-enable background scan in case of error
Bluetooth: Temporarily stop background scanning on discovery
Bluetooth: Auto connection and power on
Bleutooth: Add support for auto connect options
Bluetooth: Add le_auto_conn file on debugfs
include/net/bluetooth/hci.h | 1 +
include/net/bluetooth/hci_core.h | 43 +++++-
net/bluetooth/hci_conn.c | 111 +++++++++++---
net/bluetooth/hci_core.c | 318 +++++++++++++++++++++++++++++++++++++++
net/bluetooth/hci_event.c | 60 ++++++++
net/bluetooth/mgmt.c | 25 ++-
6 files changed, 530 insertions(+), 28 deletions(-)
--
1.8.5.1
^ permalink raw reply
* Re: [PATCH 1/5] android/hal-bluetooth: Add support for sending LE_TEST_MODE command
From: Anderson Lizardo @ 2013-12-20 11:57 UTC (permalink / raw)
To: Szymon Janc; +Cc: BlueZ development
In-Reply-To: <1387535140-6223-2-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Fri, Dec 20, 2013 at 6:25 AM, Szymon Janc <szymon.janc@tieto.com> wrote:
> +#if PLATFORM_SDK_VERSION > 17
> +static int le_test_mode(uint16_t opcode, uint8_t *buf, uint8_t len)
> +{
> + uint8_t cmd_buf[sizeof(struct hal_cmd_dut_mode_send) + len];
> + struct hal_cmd_le_test_mode *cmd = (void *) cmd_buf;
You are using two different structs above (which happen to have the
same fields).
> +
> + DBG("opcode %u len %u", opcode, len);
> +
> + if (!interface_ready())
> + return BT_STATUS_NOT_READY;
> +
> + cmd->opcode = opcode;
> + cmd->len = len;
> + memcpy(cmd->data, buf, cmd->len);
> +
> + return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_LE_TEST_MODE,
> + sizeof(cmd_buf), cmd, 0, NULL, NULL);
Just to be consistent above, I would use "..., sizeof(cmd_buf),
cmd_buf, ...", although I noticed other similar code already upstream.
Best Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply
* [PATCH_v7 5/5] bnep: Refactored bnep server apis for bridge addition and deletion
From: Ravi kumar Veeramally @ 2013-12-20 11:40 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387539653-7271-1-git-send-email-ravikumar.veeramally@linux.intel.com>
To simplify bnep server realted bridge creation and deletion calls
provided extra apis and moved existing apis to static.
---
profiles/network/bnep.c | 50 +++++++++++++++++++++++++++++++++++++++++------
profiles/network/bnep.h | 11 ++++-------
profiles/network/server.c | 37 +++--------------------------------
3 files changed, 51 insertions(+), 47 deletions(-)
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index eace07a..2a74016 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -153,7 +153,7 @@ int bnep_cleanup(void)
return 0;
}
-int bnep_conndel(const bdaddr_t *dst)
+static int bnep_conndel(const bdaddr_t *dst)
{
struct bnep_conndel_req req;
@@ -169,7 +169,7 @@ int bnep_conndel(const bdaddr_t *dst)
return 0;
}
-int bnep_connadd(int sk, uint16_t role, char *dev)
+static int bnep_connadd(int sk, uint16_t role, char *dev)
{
struct bnep_connadd_req req;
@@ -189,7 +189,7 @@ int bnep_connadd(int sk, uint16_t role, char *dev)
return 0;
}
-int bnep_if_up(const char *devname)
+static int bnep_if_up(const char *devname)
{
struct ifreq ifr;
int sk, err;
@@ -214,7 +214,7 @@ int bnep_if_up(const char *devname)
return 0;
}
-int bnep_if_down(const char *devname)
+static int bnep_if_down(const char *devname)
{
struct ifreq ifr;
int sk, err;
@@ -485,7 +485,7 @@ void bnep_set_disconnect(struct bnep *session, bnep_disconnect_cb disconn_cb,
}
}
-int bnep_add_to_bridge(const char *devname, const char *bridge)
+static int bnep_add_to_bridge(const char *devname, const char *bridge)
{
int ifindex;
struct ifreq ifr;
@@ -516,7 +516,7 @@ int bnep_add_to_bridge(const char *devname, const char *bridge)
return 0;
}
-int bnep_del_from_bridge(const char *devname, const char *bridge)
+static int bnep_del_from_bridge(const char *devname, const char *bridge)
{
int ifindex = if_nametoindex(devname);
struct ifreq ifr;
@@ -545,6 +545,44 @@ int bnep_del_from_bridge(const char *devname, const char *bridge)
return 0;
}
+int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
+ const bdaddr_t *addr)
+{
+ if (!bridge || !bridge || !iface || !addr)
+ return -EINVAL;
+
+ if (bnep_connadd(sk, dst, iface) < 0) {
+ error("Can't add connection to the bridge %s: %s(%d)",
+ bridge, strerror(errno), errno);
+ return -errno;
+ }
+
+ if (bnep_add_to_bridge(iface, bridge) < 0) {
+ error("Can't add %s to the bridge %s: %s(%d)",
+ iface, bridge, strerror(errno), errno);
+ bnep_conndel(addr);
+ return -errno;
+ }
+
+ if (bnep_if_up(iface) < 0) {
+ error("Can't up the interface %s: %s(%d)",
+ iface, strerror(errno), errno);
+ return -errno;
+ }
+
+ return 0;
+}
+
+void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
+{
+ if (!bridge || !iface || !addr)
+ return;
+
+ bnep_del_from_bridge(iface, bridge);
+ bnep_if_down(iface);
+ bnep_conndel(addr);
+}
+
ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp)
{
struct bnep_control_rsp rsp;
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index c07cd77..87cdacf 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -33,13 +33,6 @@ const char *bnep_name(uint16_t id);
struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role);
void bnep_free(struct bnep *session);
-int bnep_connadd(int sk, uint16_t role, char *dev);
-int bnep_conndel(const bdaddr_t *dst);
-int bnep_if_up(const char *devname);
-int bnep_if_down(const char *devname);
-int bnep_add_to_bridge(const char *devname, const char *bridge);
-int bnep_del_from_bridge(const char *devname, const char *bridge);
-
typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data);
typedef void (*bnep_disconnect_cb) (void *data);
@@ -47,6 +40,10 @@ void bnep_set_disconnect(struct bnep *session, bnep_disconnect_cb disconn_cb,
void *data);
void bnep_disconnect(struct bnep *session);
+int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
+ const bdaddr_t *addr);
+void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr);
+
ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role);
uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 73741ec..7cb5a1e 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -251,35 +251,6 @@ static sdp_record_t *server_record_new(const char *name, uint16_t id)
return record;
}
-static int server_connadd(struct network_server *ns,
- struct network_session *session,
- uint16_t dst_role)
-{
- char devname[16];
- int err, nsk;
-
- nsk = g_io_channel_unix_get_fd(session->io);
- err = bnep_connadd(nsk, dst_role, devname);
- if (err < 0)
- return err;
-
- info("Added new connection: %s", devname);
-
- if (bnep_add_to_bridge(devname, ns->bridge) < 0) {
- error("Can't add %s to the bridge %s: %s(%d)",
- devname, ns->bridge, strerror(errno), errno);
- return -EPERM;
- }
-
- bnep_if_up(devname);
-
- strncpy(session->dev, devname, sizeof(devname));
-
- ns->sessions = g_slist_append(ns->sessions, session);
-
- return 0;
-}
-
static void session_free(void *data)
{
struct network_session *session = data;
@@ -377,7 +348,8 @@ static gboolean bnep_setup(GIOChannel *chan,
goto reply;
}
- if (server_connadd(ns, na->setup, dst_role) < 0)
+ if (bnep_server_add(sk, dst_role, ns->bridge, na->setup->dev,
+ &na->setup->dst) < 0)
goto reply;
na->setup = NULL;
@@ -524,10 +496,7 @@ static void server_remove_sessions(struct network_server *ns)
if (*session->dev == '\0')
continue;
- bnep_del_from_bridge(session->dev, ns->bridge);
- bnep_if_down(session->dev);
-
- bnep_conndel(&session->dst);
+ bnep_server_delete(ns->bridge, session->dev, &session->dst);
}
g_slist_free_full(ns->sessions, session_free);
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v7 4/5] bnep: Refactored bnep connect and disconnect calls
From: Ravi kumar Veeramally @ 2013-12-20 11:40 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387539653-7271-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Refactored bnep connect and disconnect calls to simplify and
keeping bnep related functionality behind curtains.
bnep_connect calls takes care of bnep_setup until interface up
then connect callback will be called. Set disconnect callback
when connect call succeeds. bnep_disconnect should be
called only when iface is up/connected.
---
android/pan.c | 54 +++++++++++++++----------------
profiles/network/bnep.c | 75 ++++++++++++++++++++++---------------------
profiles/network/bnep.h | 6 ++--
profiles/network/connection.c | 48 ++++++++++++++++-----------
4 files changed, 96 insertions(+), 87 deletions(-)
diff --git a/android/pan.c b/android/pan.c
index b83f534..689c7ef 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -54,7 +54,7 @@ struct pan_device {
uint8_t conn_state;
uint8_t role;
GIOChannel *io;
- guint watch;
+ struct bnep *session;
};
static int device_cmp(gconstpointer s, gconstpointer user_data)
@@ -67,16 +67,13 @@ static int device_cmp(gconstpointer s, gconstpointer user_data)
static void pan_device_free(struct pan_device *dev)
{
- if (dev->watch > 0) {
- g_source_remove(dev->watch);
- dev->watch = 0;
- }
-
if (dev->io) {
+ g_io_channel_shutdown(dev->io, FALSE, NULL);
g_io_channel_unref(dev->io);
dev->io = NULL;
}
+ bnep_free(dev->session);
devices = g_slist_remove(devices, dev);
g_free(dev);
@@ -124,21 +121,16 @@ static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
&ev);
}
-static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
- gpointer data)
+static void bnep_disconn_cb(void *data)
{
struct pan_device *dev = data;
DBG("%s disconnected", dev->iface);
- bnep_if_down(dev->iface);
- bnep_conndel(&dev->dst);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
-
- return FALSE;
}
-static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
+static void bnep_conn_cb(char *iface, int err, void *data)
{
struct pan_device *dev = data;
@@ -146,7 +138,6 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
if (err < 0) {
error("bnep connect req failed: %s", strerror(-err));
- bnep_conndel(&dev->dst);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
return;
}
@@ -157,17 +148,12 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
bt_pan_notify_ctrl_state(dev, HAL_PAN_CTRL_ENABLED);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTED);
-
- dev->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- bnep_watchdog_cb, dev);
- g_io_channel_unref(dev->io);
- dev->io = NULL;
}
static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
{
struct pan_device *dev = data;
- uint16_t src, dst;
+ uint16_t l_role, r_role;
int perr, sk;
DBG("");
@@ -177,16 +163,29 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
goto fail;
}
- src = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
- dst = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
+ l_role = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP :
+ BNEP_SVC_PANU;
+ r_role = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
+
sk = g_io_channel_unix_get_fd(dev->io);
- perr = bnep_connect(sk, src, dst, bnep_conn_cb, dev);
+ dev->session = bnep_new(sk, l_role, r_role);
+ if (!dev->session)
+ goto fail;
+
+ perr = bnep_connect(dev->session, bnep_conn_cb, dev);
if (perr < 0) {
error("bnep connect req failed: %s", strerror(-perr));
goto fail;
}
+ bnep_set_disconnect(dev->session, bnep_disconn_cb, dev);
+
+ if (dev->io) {
+ g_io_channel_unref(dev->io);
+ dev->io = NULL;
+ }
+
return;
fail:
@@ -284,13 +283,10 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
}
dev = l->data;
- if (dev->watch) {
- g_source_remove(dev->watch);
- dev->watch = 0;
- }
- bnep_if_down(dev->iface);
- bnep_conndel(&dst);
+ if (dev->conn_state == HAL_PAN_STATE_CONNECTED)
+ bnep_disconnect(dev->session);
+
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
status = HAL_STATUS_SUCCESS;
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 4bc08d9..eace07a 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -39,6 +39,7 @@
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/bnep.h>
+#include <btio/btio.h>
#include <glib.h>
@@ -76,25 +77,12 @@ struct bnep {
guint attempts;
guint setup_to;
guint watch;
- void *data;
bnep_connect_cb conn_cb;
+ void *conn_data;
bnep_disconnect_cb disconn_cb;
void *disconn_data;
};
-static void free_bnep_connect(struct bnep *session)
-{
- if (!session)
- return;
-
- if (session->io) {
- g_io_channel_unref(session->io);
- session->io = NULL;
- }
-
- g_free(session);
-}
-
uint16_t bnep_service_id(const char *svc)
{
int i;
@@ -251,6 +239,17 @@ int bnep_if_down(const char *devname)
return 0;
}
+static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct bnep *session = data;
+
+ if (session->disconn_cb)
+ session->disconn_cb(session->disconn_data);
+
+ return FALSE;
+}
+
static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
gpointer data)
{
@@ -258,12 +257,11 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
struct bnep_control_rsp *rsp;
struct timeval timeo;
char pkt[BNEP_MTU];
- char iface[16];
ssize_t r;
int sk;
if (cond & G_IO_NVAL)
- goto failed;
+ return FALSE;
if (session->setup_to > 0) {
g_source_remove(session->setup_to);
@@ -315,24 +313,29 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
sk = g_io_channel_unix_get_fd(session->io);
- if (bnep_connadd(sk, session->src, iface)) {
+ if (bnep_connadd(sk, session->src, session->iface)) {
error("bnep conn could not be added");
goto failed;
}
- if (bnep_if_up(iface)) {
- error("could not up %s", iface);
+ if (bnep_if_up(session->iface)) {
+ error("could not up %s", session->iface);
+ bnep_conndel(&session->dst_addr);
goto failed;
}
- session->conn_cb(chan, iface, 0, session->data);
- free_bnep_connect(session);
+ session->watch = g_io_add_watch(session->io,
+ G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ (GIOFunc) bnep_watchdog_cb, session);
+ g_io_channel_unref(session->io);
+ session->io = NULL;
+
+ session->conn_cb(session->iface, 0, session->conn_data);
return FALSE;
failed:
- session->conn_cb(NULL, NULL, -EIO, session->data);
- free_bnep_connect(session);
+ session->conn_cb(NULL, -EIO, session->conn_data);
return FALSE;
}
@@ -376,8 +379,7 @@ static gboolean bnep_conn_req_to(gpointer user_data)
return TRUE;
}
- session->conn_cb(NULL, NULL, -ETIMEDOUT, session->data);
- free_bnep_connect(session);
+ session->conn_cb(NULL, -ETIMEDOUT, session->conn_data);
return FALSE;
}
@@ -423,22 +425,25 @@ void bnep_free(struct bnep *session)
g_free(session);
}
-int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
- void *data)
+int bnep_connect(struct bnep *session, bnep_connect_cb conn_cb, void *data)
{
- struct bnep *session;
+ GError *gerr = NULL;
int err;
- if (!conn_cb)
+ if (!session || !conn_cb)
return -EINVAL;
- session = g_new0(struct bnep, 1);
- session->io = g_io_channel_unix_new(sk);
session->attempts = 0;
- session->src = src;
- session->dst = dst;
session->conn_cb = conn_cb;
- session->data = data;
+ session->conn_data = data;
+
+ bt_io_get(session->io, &gerr, BT_IO_OPT_DEST_BDADDR, &session->dst_addr,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s", gerr->message);
+ g_error_free(gerr);
+ return -EINVAL;
+ }
err = bnep_setup_conn_req(session);
if (err < 0)
@@ -446,8 +451,6 @@ int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
session->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
bnep_conn_req_to, session);
- g_io_add_watch(session->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- bnep_setup_cb, session);
return 0;
}
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index d3c5c1b..c07cd77 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -40,10 +40,8 @@ int bnep_if_down(const char *devname);
int bnep_add_to_bridge(const char *devname, const char *bridge);
int bnep_del_from_bridge(const char *devname, const char *bridge);
-typedef void (*bnep_connect_cb) (GIOChannel *chan, char *iface, int err,
- void *data);
-int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
- void *data);
+typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
+int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data);
typedef void (*bnep_disconnect_cb) (void *data);
void bnep_set_disconnect(struct bnep *session, bnep_disconnect_cb disconn_cb,
void *data);
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index fb3e1ce..c66987d 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -72,6 +72,7 @@ struct network_conn {
guint dc_id;
struct network_peer *peer;
DBusMessage *connect;
+ struct bnep *session;
};
static GSList *peers = NULL;
@@ -106,8 +107,7 @@ static struct network_conn *find_connection_by_state(GSList *list,
return NULL;
}
-static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
- gpointer data)
+static void bnep_disconn_cb(gpointer data)
{
struct network_conn *nc = data;
DBusConnection *conn = btd_get_dbus_connection();
@@ -126,12 +126,12 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
info("%s disconnected", nc->dev);
- bnep_if_down(nc->dev);
nc->state = DISCONNECTED;
memset(nc->dev, 0, sizeof(nc->dev));
strcpy(nc->dev, "bnep%d");
- return FALSE;
+ bnep_free(nc->session);
+ nc->session = NULL;
}
static void local_connect_cb(struct network_conn *nc, int err)
@@ -155,12 +155,21 @@ static void local_connect_cb(struct network_conn *nc, int err)
static void cancel_connection(struct network_conn *nc, int err)
{
btd_service_connecting_complete(nc->service, err);
+
if (nc->connect)
local_connect_cb(nc, err);
- g_io_channel_shutdown(nc->io, TRUE, NULL);
- g_io_channel_unref(nc->io);
- nc->io = NULL;
+ if (nc->io) {
+ g_io_channel_shutdown(nc->io, FALSE, NULL);
+ g_io_channel_unref(nc->io);
+ nc->io = NULL;
+ }
+
+ if (nc->state == CONNECTED)
+ bnep_disconnect(nc->session);
+
+ bnep_free(nc->session);
+ nc->session = NULL;
nc->state = DISCONNECTED;
}
@@ -169,11 +178,7 @@ static void connection_destroy(DBusConnection *conn, void *user_data)
{
struct network_conn *nc = user_data;
- if (nc->state == CONNECTED) {
- bnep_if_down(nc->dev);
- bnep_conndel(device_get_address(nc->peer->device));
- } else if (nc->io)
- cancel_connection(nc, -EIO);
+ cancel_connection(nc, -EIO);
}
static void disconnect_cb(struct btd_device *device, gboolean removal,
@@ -186,7 +191,7 @@ static void disconnect_cb(struct btd_device *device, gboolean removal,
connection_destroy(NULL, user_data);
}
-static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
+static void bnep_conn_cb(char *iface, int err, void *data)
{
struct network_conn *nc = data;
const char *path;
@@ -220,10 +225,6 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
nc->state = CONNECTED;
nc->dc_id = device_add_disconnect_watch(nc->peer->device, disconnect_cb,
nc, NULL);
- g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- bnep_watchdog_cb, nc);
- g_io_channel_unref(nc->io);
- nc->io = NULL;
return;
@@ -242,12 +243,23 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
}
sk = g_io_channel_unix_get_fd(nc->io);
- perr = bnep_connect(sk, BNEP_SVC_PANU, nc->id, bnep_conn_cb, nc);
+ nc->session = bnep_new(sk, BNEP_SVC_PANU, nc->id);
+ if (!nc->session)
+ goto failed;
+
+ perr = bnep_connect(nc->session, bnep_conn_cb, nc);
if (perr < 0) {
error("bnep connect(): %s (%d)", strerror(-perr), -perr);
goto failed;
}
+ bnep_set_disconnect(nc->session, bnep_disconn_cb, nc);
+
+ if (nc->io) {
+ g_io_channel_unref(nc->io);
+ nc->io = NULL;
+ }
+
return;
failed:
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v7 3/5] bnep: Add bnep_disconnect and bnep_set_disconnect apis
From: Ravi kumar Veeramally @ 2013-12-20 11:40 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387539653-7271-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Set disconnect call and callback will be triggered by I/O event on
bnep channel. Call bnep_disconnect, it will delete bnep connection
and down the interface, if interface is not up and running do not
use this api, simply call bnep_free.
---
profiles/network/bnep.c | 35 +++++++++++++++++++++++++++++++++++
profiles/network/bnep.h | 4 ++++
2 files changed, 39 insertions(+)
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 304b9da..4bc08d9 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -71,11 +71,15 @@ struct bnep {
GIOChannel *io;
uint16_t src;
uint16_t dst;
+ bdaddr_t dst_addr;
+ char iface[16];
guint attempts;
guint setup_to;
guint watch;
void *data;
bnep_connect_cb conn_cb;
+ bnep_disconnect_cb disconn_cb;
+ void *disconn_data;
};
static void free_bnep_connect(struct bnep *session)
@@ -447,6 +451,37 @@ int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
return 0;
}
+void bnep_disconnect(struct bnep *session)
+{
+ if (!session)
+ return;
+
+ if (session->watch > 0) {
+ g_source_remove(session->watch);
+ session->watch = 0;
+ }
+
+ if (session->io) {
+ g_io_channel_unref(session->io);
+ session->io = NULL;
+ }
+
+ bnep_if_down(session->iface);
+ bnep_conndel(&session->dst_addr);
+}
+
+void bnep_set_disconnect(struct bnep *session, bnep_disconnect_cb disconn_cb,
+ void *data)
+{
+ if (!session || !disconn_cb)
+ return;
+
+ if (!session->disconn_cb && !session->disconn_data) {
+ session->disconn_cb = disconn_cb;
+ session->disconn_data = data;
+ }
+}
+
int bnep_add_to_bridge(const char *devname, const char *bridge)
{
int ifindex;
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 91ca622..d3c5c1b 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -44,6 +44,10 @@ typedef void (*bnep_connect_cb) (GIOChannel *chan, char *iface, int err,
void *data);
int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
void *data);
+typedef void (*bnep_disconnect_cb) (void *data);
+void bnep_set_disconnect(struct bnep *session, bnep_disconnect_cb disconn_cb,
+ void *data);
+void bnep_disconnect(struct bnep *session);
ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role);
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v7 2/5] bnep: Add bnep_new and bnep_free api's
From: Ravi kumar Veeramally @ 2013-12-20 11:40 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387539653-7271-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Refactoring connect and disconnect mechanisms. It would be more
convinient for caller to maintain just bnep connection reference
and delete whenever it is not required.
---
profiles/network/bnep.c | 42 ++++++++++++++++++++++++++++++++++++++++++
profiles/network/bnep.h | 5 +++++
2 files changed, 47 insertions(+)
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index edf258b..304b9da 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -73,6 +73,7 @@ struct bnep {
uint16_t dst;
guint attempts;
guint setup_to;
+ guint watch;
void *data;
bnep_connect_cb conn_cb;
};
@@ -377,6 +378,47 @@ static gboolean bnep_conn_req_to(gpointer user_data)
return FALSE;
}
+struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role)
+{
+ struct bnep *session;
+ int dup_fd;
+
+ dup_fd = dup(sk);
+ if (dup_fd < 0)
+ return NULL;
+
+ session = g_new0(struct bnep, 1);
+ session->io = g_io_channel_unix_new(dup_fd);
+ session->src = local_role;
+ session->dst = remote_role;
+
+ g_io_channel_set_close_on_unref(session->io, TRUE);
+ session->watch = g_io_add_watch(session->io,
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ (GIOFunc) bnep_setup_cb, session);
+
+ return session;
+}
+
+void bnep_free(struct bnep *session)
+{
+ if (!session)
+ return;
+
+ if (session->io) {
+ g_io_channel_shutdown(session->io, FALSE, NULL);
+ g_io_channel_unref(session->io);
+ session->io = NULL;
+ }
+
+ if (session->watch > 0) {
+ g_source_remove(session->watch);
+ session->watch = 0;
+ }
+
+ g_free(session);
+}
+
int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
void *data)
{
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index dd22c40..91ca622 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -21,6 +21,8 @@
*
*/
+struct bnep;
+
int bnep_init(void);
int bnep_cleanup(void);
@@ -28,6 +30,9 @@ uint16_t bnep_service_id(const char *svc);
const char *bnep_uuid(uint16_t id);
const char *bnep_name(uint16_t id);
+struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role);
+void bnep_free(struct bnep *session);
+
int bnep_connadd(int sk, uint16_t role, char *dev);
int bnep_conndel(const bdaddr_t *dst);
int bnep_if_up(const char *devname);
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v7 1/5] bnep: Rename struct bnep_conn to bnep and vars for better readability
From: Ravi kumar Veeramally @ 2013-12-20 11:40 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
---
profiles/network/bnep.c | 80 ++++++++++++++++++++++++-------------------------
1 file changed, 40 insertions(+), 40 deletions(-)
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 08037e6..edf258b 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -67,7 +67,7 @@ struct __service_16 {
uint16_t src;
} __attribute__ ((packed));
-struct bnep_conn {
+struct bnep {
GIOChannel *io;
uint16_t src;
uint16_t dst;
@@ -77,17 +77,17 @@ struct bnep_conn {
bnep_connect_cb conn_cb;
};
-static void free_bnep_connect(struct bnep_conn *bc)
+static void free_bnep_connect(struct bnep *session)
{
- if (!bc)
+ if (!session)
return;
- if (bc->io) {
- g_io_channel_unref(bc->io);
- bc->io = NULL;
+ if (session->io) {
+ g_io_channel_unref(session->io);
+ session->io = NULL;
}
- g_free(bc);
+ g_free(session);
}
uint16_t bnep_service_id(const char *svc)
@@ -249,7 +249,7 @@ int bnep_if_down(const char *devname)
static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
gpointer data)
{
- struct bnep_conn *bc = data;
+ struct bnep *session = data;
struct bnep_control_rsp *rsp;
struct timeval timeo;
char pkt[BNEP_MTU];
@@ -260,9 +260,9 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
if (cond & G_IO_NVAL)
goto failed;
- if (bc->setup_to > 0) {
- g_source_remove(bc->setup_to);
- bc->setup_to = 0;
+ if (session->setup_to > 0) {
+ g_source_remove(session->setup_to);
+ session->setup_to = 0;
}
if (cond & (G_IO_HUP | G_IO_ERR)) {
@@ -309,8 +309,8 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
timeo.tv_sec = 0;
setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
- sk = g_io_channel_unix_get_fd(bc->io);
- if (bnep_connadd(sk, bc->src, iface)) {
+ sk = g_io_channel_unix_get_fd(session->io);
+ if (bnep_connadd(sk, session->src, iface)) {
error("bnep conn could not be added");
goto failed;
}
@@ -320,19 +320,19 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
goto failed;
}
- bc->conn_cb(chan, iface, 0, bc->data);
- free_bnep_connect(bc);
+ session->conn_cb(chan, iface, 0, session->data);
+ free_bnep_connect(session);
return FALSE;
failed:
- bc->conn_cb(NULL, NULL, -EIO, bc->data);
- free_bnep_connect(bc);
+ session->conn_cb(NULL, NULL, -EIO, session->data);
+ free_bnep_connect(session);
return FALSE;
}
-static int bnep_setup_conn_req(struct bnep_conn *bc)
+static int bnep_setup_conn_req(struct bnep *session)
{
struct bnep_setup_conn_req *req;
struct __service_16 *s;
@@ -345,34 +345,34 @@ static int bnep_setup_conn_req(struct bnep_conn *bc)
req->ctrl = BNEP_SETUP_CONN_REQ;
req->uuid_size = 2; /* 16bit UUID */
s = (void *) req->service;
- s->src = htons(bc->src);
- s->dst = htons(bc->dst);
+ s->src = htons(session->src);
+ s->dst = htons(session->dst);
- fd = g_io_channel_unix_get_fd(bc->io);
+ fd = g_io_channel_unix_get_fd(session->io);
if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
error("bnep connection req send failed: %s", strerror(errno));
return -errno;
}
- bc->attempts++;
+ session->attempts++;
return 0;
}
static gboolean bnep_conn_req_to(gpointer user_data)
{
- struct bnep_conn *bc = user_data;
+ struct bnep *session = user_data;
- if (bc->attempts == CON_SETUP_RETRIES) {
+ if (session->attempts == CON_SETUP_RETRIES) {
error("Too many bnep connection attempts");
} else {
error("bnep connection setup TO, retrying...");
- if (bnep_setup_conn_req(bc) == 0)
+ if (bnep_setup_conn_req(session) == 0)
return TRUE;
}
- bc->conn_cb(NULL, NULL, -ETIMEDOUT, bc->data);
- free_bnep_connect(bc);
+ session->conn_cb(NULL, NULL, -ETIMEDOUT, session->data);
+ free_bnep_connect(session);
return FALSE;
}
@@ -380,28 +380,28 @@ static gboolean bnep_conn_req_to(gpointer user_data)
int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
void *data)
{
- struct bnep_conn *bc;
+ struct bnep *session;
int err;
if (!conn_cb)
return -EINVAL;
- bc = g_new0(struct bnep_conn, 1);
- bc->io = g_io_channel_unix_new(sk);
- bc->attempts = 0;
- bc->src = src;
- bc->dst = dst;
- bc->conn_cb = conn_cb;
- bc->data = data;
+ session = g_new0(struct bnep, 1);
+ session->io = g_io_channel_unix_new(sk);
+ session->attempts = 0;
+ session->src = src;
+ session->dst = dst;
+ session->conn_cb = conn_cb;
+ session->data = data;
- err = bnep_setup_conn_req(bc);
+ err = bnep_setup_conn_req(session);
if (err < 0)
return err;
- bc->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
- bnep_conn_req_to, bc);
- g_io_add_watch(bc->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- bnep_setup_cb, bc);
+ session->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
+ bnep_conn_req_to, session);
+ g_io_add_watch(session->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ bnep_setup_cb, session);
return 0;
}
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH v2 BlueZ] android/AVDTP: Duplicate fd passed to avdtp_new
From: Johan Hedberg @ 2013-12-20 11:08 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1387537166-7703-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Fri, Dec 20, 2013, Luiz Augusto von Dentz wrote:
> This use dup to create a new fd to be used by AVDTP session leaving the
> caller free to close the original fd. Note that even if the caller
> decides to keep the original fd it will still be notified when
> avdtp_shutdown is called since it uses shutdown.
> ---
> android/a2dp.c | 6 +++++-
> android/avdtp.c | 9 ++++++++-
> 2 files changed, 13 insertions(+), 2 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCHv3 1/3] tools/l2cap-tester: Remove not necessary bthost_set_server_psm
From: Johan Hedberg @ 2013-12-20 11:03 UTC (permalink / raw)
To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1387536827-1590-1-git-send-email-marcin.kraglak@tieto.com>
Hi Marcin,
On Fri, Dec 20, 2013, Marcin Kraglak wrote:
> This function can be replaced with bthost_add_l2cap_server().
> ---
> tools/l2cap-tester.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
All three patches have been applied. Thanks.
Johan
^ permalink raw reply
* [PATCH v2 BlueZ] android/AVDTP: Duplicate fd passed to avdtp_new
From: Luiz Augusto von Dentz @ 2013-12-20 10:59 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This use dup to create a new fd to be used by AVDTP session leaving the
caller free to close the original fd. Note that even if the caller
decides to keep the original fd it will still be notified when
avdtp_shutdown is called since it uses shutdown.
---
android/a2dp.c | 6 +++++-
android/avdtp.c | 9 ++++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/android/a2dp.c b/android/a2dp.c
index 9087c62..581d094 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -150,11 +150,15 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
return;
}
- g_io_channel_set_close_on_unref(chan, FALSE);
fd = g_io_channel_unix_get_fd(chan);
/* FIXME: Add proper version */
dev->session = avdtp_new(fd, imtu, omtu, 0x0100);
+ if (!dev->session) {
+ bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+ return;
+ }
+
avdtp_add_disconnect_cb(dev->session, disconnect_cb, dev);
if (dev->io) {
diff --git a/android/avdtp.c b/android/avdtp.c
index 353316c..02ee920 100644
--- a/android/avdtp.c
+++ b/android/avdtp.c
@@ -2055,9 +2055,16 @@ struct avdtp *avdtp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
{
struct avdtp *session;
GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+ int new_fd;
+
+ new_fd = dup(fd);
+ if (new_fd < 0) {
+ error("dup(): %s (%d)", strerror(errno), errno);
+ return NULL;
+ }
session = g_new0(struct avdtp, 1);
- session->io = g_io_channel_unix_new(fd);
+ session->io = g_io_channel_unix_new(new_fd);
session->version = version;
session->imtu = imtu;
session->omtu = omtu;
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH 0/5] android: Update HAL to Android 4.4 API
From: Johan Hedberg @ 2013-12-20 10:58 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1387535140-6223-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Fri, Dec 20, 2013, Szymon Janc wrote:
> It is important to fully implement bt_interface_t (at least with stubs/NULLs)
> since Android is not checking size field from HAL and just assume memory
> layout of BT HAL. This was causing crashes on 4.4 due to Android trying
> to call not existing methods.
>
> BT snoop logs enabling function is a bit special since it will be implemented
> only in HAL so no need to extend IPC with that (plan is to have dedicated
> service that will dump HCI traffic).
>
> For now 4.2+ API is if-deffed in HAL library - this will be removed when
> minimal Android version required will be dropped.
>
> --
> BR
> Szymon Janc
>
> Szymon Janc (5):
> android/hal-bluetooth: Add support for sending LE_TEST_MODE command
> android/hal-bluetooth: Add support for enabling HCI snoop dump
> android/hal-bluetooth: Add support for remote version info property
> android/hal-bluetooth: Add support for device service record property
> android/bluetooth: Add stubs for missing commands
>
> android/bluetooth.c | 56 ++++++++++++++++++++++++
> android/cutils/properties.h | 1 +
> android/hal-bluetooth.c | 104 +++++++++++++++++++++++++++++++++++++++++++-
> android/hal-msg.h | 13 ++++++
> 4 files changed, 172 insertions(+), 2 deletions(-)
All patches in this set have been applied. Thanks.
Johan
^ permalink raw reply
* [PATCHv3 3/3] emulator/bthost: Remove not used bthost_set_server_psm
From: Marcin Kraglak @ 2013-12-20 10:53 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387536827-1590-1-git-send-email-marcin.kraglak@tieto.com>
This function is not needed and has been replaced with bthost_add_l2cap_server.
---
emulator/bthost.c | 5 -----
emulator/bthost.h | 2 --
2 files changed, 7 deletions(-)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 8e62d26..c627f8a 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -1304,11 +1304,6 @@ void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm,
bthost->new_l2cap_conn_data = data;
}
-void bthost_set_server_psm(struct bthost *bthost, uint16_t psm)
-{
- bthost_add_l2cap_server(bthost, psm, NULL, NULL);
-}
-
void bthost_start(struct bthost *bthost)
{
if (!bthost)
diff --git a/emulator/bthost.h b/emulator/bthost.h
index 2b8f212..97f011b 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -77,8 +77,6 @@ void bthost_le_start_encrypt(struct bthost *bthost, uint16_t handle,
typedef void (*bthost_l2cap_connect_cb) (uint16_t handle, uint16_t cid,
void *user_data);
-void bthost_set_server_psm(struct bthost *bthost, uint16_t psm);
-
void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm,
bthost_l2cap_connect_cb func, void *user_data);
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 2/3] android/android-tester: Remove not necessary bthost_set_server_psm
From: Marcin Kraglak @ 2013-12-20 10:53 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387536827-1590-1-git-send-email-marcin.kraglak@tieto.com>
Replace this function with bthost_add_l2cap_server().
---
android/android-tester.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/android/android-tester.c b/android/android-tester.c
index aa0c155..5e60397 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1404,7 +1404,7 @@ static void test_socket_real_connect(const void *test_data)
bdaddr2android((bdaddr_t *) client_bdaddr, &emu_bdaddr);
- bthost_set_server_psm(bthost, 0x0003);
+ bthost_add_l2cap_server(bthost, 0x0003, NULL, NULL);
status = data->if_sock->connect(&emu_bdaddr, test->sock_type,
test->service_uuid, test->channel,
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 1/3] tools/l2cap-tester: Remove not necessary bthost_set_server_psm
From: Marcin Kraglak @ 2013-12-20 10:53 UTC (permalink / raw)
To: linux-bluetooth
This function can be replaced with bthost_add_l2cap_server().
---
tools/l2cap-tester.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index a5028a3..d4a5041 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -731,7 +731,8 @@ static void test_connect(const void *test_data)
struct bthost *bthost = hciemu_client_get_host(data->hciemu);
if (!l2data->data_len)
- bthost_set_server_psm(bthost, l2data->server_psm);
+ bthost_add_l2cap_server(bthost, l2data->server_psm,
+ NULL, NULL);
else
bthost_add_l2cap_server(bthost, l2data->server_psm,
client_l2cap_connect_cb, data);
--
1.8.3.1
^ permalink raw reply related
* [PATCH 5/5] android/bluetooth: Add stubs for missing commands
From: Szymon Janc @ 2013-12-20 10:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1387535140-6223-1-git-send-email-szymon.janc@tieto.com>
This adds stubs for commands that were introduced by BT HAL changes
in Android 4.3+.
---
android/bluetooth.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index efaa424..6bfe786 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -2567,6 +2567,54 @@ failed:
ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_DISCOVERY, status);
}
+static void handle_dut_mode_conf_cmd(const void *buf, uint16_t len)
+{
+ const struct hal_cmd_dut_mode_conf *cmd = buf;
+
+ DBG("enable %u", cmd->enable);
+
+ /* TODO */
+
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_CONF,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_dut_mode_send_cmd(const void *buf, uint16_t len)
+{
+ const struct hal_cmd_dut_mode_send *cmd = buf;
+
+ if (len != sizeof(*cmd) + cmd->len) {
+ error("Invalid dut mode send cmd, terminating");
+ raise(SIGTERM);
+ return;
+ }
+
+ DBG("opcode %u", cmd->opcode);
+
+ /* TODO */
+
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_SEND,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_le_test_mode_cmd(const void *buf, uint16_t len)
+{
+ const struct hal_cmd_le_test_mode *cmd = buf;
+
+ if (len != sizeof(*cmd) + cmd->len) {
+ error("Invalid le test mode cmd, terminating");
+ raise(SIGTERM);
+ return;
+ }
+
+ DBG("opcode %u", cmd->opcode);
+
+ /* TODO */
+
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_LE_TEST_MODE,
+ HAL_STATUS_FAILED);
+}
+
static const struct ipc_handler cmd_handlers[] = {
/* HAL_OP_ENABLE */
{ handle_enable_cmd, false, 0 },
@@ -2609,6 +2657,14 @@ static const struct ipc_handler cmd_handlers[] = {
{ handle_pin_reply_cmd, false, sizeof(struct hal_cmd_pin_reply) },
/* HAL_OP_SSP_REPLY */
{ handle_ssp_reply_cmd, false, sizeof(struct hal_cmd_ssp_reply) },
+ /* HAL_OP_DUT_MODE_CONF */
+ { handle_dut_mode_conf_cmd, false,
+ sizeof(struct hal_cmd_dut_mode_conf) },
+ /* HAL_OP_DUT_MODE_SEND */
+ { handle_dut_mode_send_cmd, true,
+ sizeof(struct hal_cmd_dut_mode_send) },
+ /* HAL_OP_LE_TEST_MODE */
+ { handle_le_test_mode_cmd, true, sizeof(struct hal_cmd_le_test_mode) },
};
void bt_bluetooth_register(void)
--
1.8.3.2
^ permalink raw reply related
* [PATCH 4/5] android/hal-bluetooth: Add support for device service record property
From: Szymon Janc @ 2013-12-20 10:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1387535140-6223-1-git-send-email-szymon.janc@tieto.com>
This allows to correctly handle device service record property.
---
android/hal-bluetooth.c | 15 +++++++++++++++
android/hal-msg.h | 7 +++++++
2 files changed, 22 insertions(+)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index d0c1c01..4ef2ebe 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -166,6 +166,21 @@ static void device_props_to_hal(bt_property_t *send_props,
break;
#endif
case HAL_PROP_DEVICE_SERVICE_REC:
+ {
+ static bt_service_record_t e;
+ const struct hal_prop_device_service_rec *p;
+
+ send_props[i].val = &e;
+ send_props[i].len = sizeof(e);
+
+ p = (struct hal_prop_device_service_rec *) prop->val;
+
+ memset(&e, 0, sizeof(e));
+ memcpy(&e.channel, &p->channel, sizeof(e.channel));
+ memcpy(e.uuid.uu, p->uuid, sizeof(e.uuid.uu));
+ memcpy(e.name, p->name, p->name_len);
+ }
+ break;
default:
send_props[i].len = prop->len;
send_props[i].val = prop->val;
diff --git a/android/hal-msg.h b/android/hal-msg.h
index bb196d8..c351501 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -107,6 +107,13 @@ struct hal_cmd_get_adapter_prop {
#define HAL_PROP_DEVICE_CLASS 0x04
#define HAL_PROP_DEVICE_TYPE 0x05
#define HAL_PROP_DEVICE_SERVICE_REC 0x06
+struct hal_prop_device_service_rec {
+ uint8_t uuid[16];
+ uint16_t channel;
+ uint8_t name_len;
+ uint8_t name[];
+} __attribute__((packed));
+
#define HAL_PROP_DEVICE_FRIENDLY_NAME 0x0a
#define HAL_PROP_DEVICE_RSSI 0x0b
#define HAL_PROP_DEVICE_VERSION_INFO 0x0c
--
1.8.3.2
^ permalink raw reply related
* [PATCH 3/5] android/hal-bluetooth: Add support for remote version info property
From: Szymon Janc @ 2013-12-20 10:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1387535140-6223-1-git-send-email-szymon.janc@tieto.com>
This allows to correctly handle remote version info property. Although
this property is marked as get/set in HAL only get is implemented as
I fail to see how this property could be settable.
---
android/hal-bluetooth.c | 21 ++++++++++++++++++++-
android/hal-msg.h | 6 ++++++
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 905b293..d0c1c01 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -145,8 +145,27 @@ static void device_props_to_hal(bt_property_t *send_props,
enum_prop_to_hal(send_props[i], prop,
bt_device_type_t);
break;
- case HAL_PROP_DEVICE_SERVICE_REC:
+#if PLATFORM_SDK_VERSION > 17
case HAL_PROP_DEVICE_VERSION_INFO:
+ {
+ static bt_remote_version_t e;
+ const struct hal_prop_device_info *p;
+ uint16_t tmp;
+
+ send_props[i].val = &e;
+ send_props[i].len = sizeof(e);
+
+ p = (struct hal_prop_device_info *) prop->val;
+
+ memcpy(&tmp, &p->manufacturer, sizeof(tmp));
+ e.manufacturer = tmp;
+ memcpy(&tmp, &p->sub_version, sizeof(tmp));
+ e.sub_ver = tmp;
+ e.version = p->version;
+ }
+ break;
+#endif
+ case HAL_PROP_DEVICE_SERVICE_REC:
default:
send_props[i].len = prop->len;
send_props[i].val = prop->val;
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 3be91aa..bb196d8 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -110,6 +110,12 @@ struct hal_cmd_get_adapter_prop {
#define HAL_PROP_DEVICE_FRIENDLY_NAME 0x0a
#define HAL_PROP_DEVICE_RSSI 0x0b
#define HAL_PROP_DEVICE_VERSION_INFO 0x0c
+struct hal_prop_device_info {
+ uint8_t version;
+ uint16_t sub_version;
+ uint16_t manufacturer;
+} __attribute__((packed));
+
#define HAL_PROP_DEVICE_TIMESTAMP 0xFF
#define HAL_ADAPTER_SCAN_MODE_NONE 0x00
--
1.8.3.2
^ permalink raw reply related
* [PATCH 2/5] android/hal-bluetooth: Add support for enabling HCI snoop dump
From: Szymon Janc @ 2013-12-20 10:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1387535140-6223-1-git-send-email-szymon.janc@tieto.com>
This allows to enable HCI SNOOP dump from HAL. This requires that
service named 'bluetoothd_snoop' be available in Android system.
---
android/cutils/properties.h | 1 +
android/hal-bluetooth.c | 24 ++++++++++++++++++++++++
2 files changed, 25 insertions(+)
diff --git a/android/cutils/properties.h b/android/cutils/properties.h
index 7951585..256bf13 100644
--- a/android/cutils/properties.h
+++ b/android/cutils/properties.h
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 11f2a9f..905b293 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -20,12 +20,16 @@
#include <stdbool.h>
#include <string.h>
+#include <cutils/properties.h>
+
#include "hal-log.h"
#include "hal.h"
#include "hal-msg.h"
#include "hal-ipc.h"
#include "hal-utils.h"
+#define SNOOP_SERVICE_NAME "bluetoothd_snoop"
+
static const bt_callbacks_t *bt_hal_cbacks = NULL;
#define enum_prop_to_hal(prop, hal_prop, type) do { \
@@ -791,6 +795,23 @@ static int le_test_mode(uint16_t opcode, uint8_t *buf, uint8_t len)
}
#endif
+#if PLATFORM_SDK_VERSION > 18
+static int config_hci_snoop_log(uint8_t enable)
+{
+ if (enable && property_set("ctl.start", SNOOP_SERVICE_NAME) < 0) {
+ error("Failed to start service %s", SNOOP_SERVICE_NAME);
+ return BT_STATUS_FAIL;
+ }
+
+ if (!enable && property_set("ctl.stop", SNOOP_SERVICE_NAME) < 0) {
+ error("Failed to stop service %s", SNOOP_SERVICE_NAME);
+ return BT_STATUS_FAIL;
+ }
+
+ return BT_STATUS_SUCCESS;
+}
+#endif
+
static const bt_interface_t bluetooth_if = {
.size = sizeof(bt_interface_t),
.init = init,
@@ -818,6 +839,9 @@ static const bt_interface_t bluetooth_if = {
#if PLATFORM_SDK_VERSION > 17
.le_test_mode = le_test_mode,
#endif
+#if PLATFORM_SDK_VERSION > 18
+ .config_hci_snoop_log = config_hci_snoop_log,
+#endif
};
static const bt_interface_t *get_bluetooth_interface(void)
--
1.8.3.2
^ permalink raw reply related
* [PATCH 1/5] android/hal-bluetooth: Add support for sending LE_TEST_MODE command
From: Szymon Janc @ 2013-12-20 10:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1387535140-6223-1-git-send-email-szymon.janc@tieto.com>
This allows to send LE_TEST_MODE command introduced in Android 4.3.
---
android/hal-bluetooth.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 7cac15c..11f2a9f 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -307,6 +307,18 @@ static void handle_dut_mode_receive(void *buf, uint16_t len)
bt_hal_cbacks->dut_mode_recv_cb(ev->opcode, ev->data, ev->len);
}
+#if PLATFORM_SDK_VERSION > 17
+static void handle_le_test_mode(void *buf, uint16_t len)
+{
+ struct hal_ev_le_test_mode *ev = buf;
+
+ DBG("");
+
+ if (bt_hal_cbacks->le_test_mode_cb)
+ bt_hal_cbacks->le_test_mode_cb(ev->status, ev->num_packets);
+}
+#endif
+
/* handlers will be called from notification thread context,
* index in table equals to 'opcode - HAL_MINIMUM_EVENT' */
static const struct hal_ipc_handler ev_handlers[] = {
@@ -363,6 +375,13 @@ static const struct hal_ipc_handler ev_handlers[] = {
.var_len = true,
.data_len = sizeof(struct hal_ev_dut_mode_receive),
},
+#if PLATFORM_SDK_VERSION > 17
+ { /* HAL_EV_LE_TEST_MODE */
+ .handler = handle_le_test_mode,
+ .var_len = false,
+ .data_len = sizeof(struct hal_ev_le_test_mode),
+ }
+#endif
};
static int init(bt_callbacks_t *callbacks)
@@ -752,6 +771,26 @@ static int dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t len)
sizeof(cmd_buf), cmd, 0, NULL, NULL);
}
+#if PLATFORM_SDK_VERSION > 17
+static int le_test_mode(uint16_t opcode, uint8_t *buf, uint8_t len)
+{
+ uint8_t cmd_buf[sizeof(struct hal_cmd_dut_mode_send) + len];
+ struct hal_cmd_le_test_mode *cmd = (void *) cmd_buf;
+
+ DBG("opcode %u len %u", opcode, len);
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ cmd->opcode = opcode;
+ cmd->len = len;
+ memcpy(cmd->data, buf, cmd->len);
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_LE_TEST_MODE,
+ sizeof(cmd_buf), cmd, 0, NULL, NULL);
+}
+#endif
+
static const bt_interface_t bluetooth_if = {
.size = sizeof(bt_interface_t),
.init = init,
@@ -775,7 +814,10 @@ static const bt_interface_t bluetooth_if = {
.ssp_reply = ssp_reply,
.get_profile_interface = get_profile_interface,
.dut_mode_configure = dut_mode_configure,
- .dut_mode_send = dut_mode_send
+ .dut_mode_send = dut_mode_send,
+#if PLATFORM_SDK_VERSION > 17
+ .le_test_mode = le_test_mode,
+#endif
};
static const bt_interface_t *get_bluetooth_interface(void)
--
1.8.3.2
^ permalink raw reply related
* [PATCH 0/5] android: Update HAL to Android 4.4 API
From: Szymon Janc @ 2013-12-20 10:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Hi,
It is important to fully implement bt_interface_t (at least with stubs/NULLs)
since Android is not checking size field from HAL and just assume memory
layout of BT HAL. This was causing crashes on 4.4 due to Android trying
to call not existing methods.
BT snoop logs enabling function is a bit special since it will be implemented
only in HAL so no need to extend IPC with that (plan is to have dedicated
service that will dump HCI traffic).
For now 4.2+ API is if-deffed in HAL library - this will be removed when
minimal Android version required will be dropped.
--
BR
Szymon Janc
Szymon Janc (5):
android/hal-bluetooth: Add support for sending LE_TEST_MODE command
android/hal-bluetooth: Add support for enabling HCI snoop dump
android/hal-bluetooth: Add support for remote version info property
android/hal-bluetooth: Add support for device service record property
android/bluetooth: Add stubs for missing commands
android/bluetooth.c | 56 ++++++++++++++++++++++++
android/cutils/properties.h | 1 +
android/hal-bluetooth.c | 104 +++++++++++++++++++++++++++++++++++++++++++-
android/hal-msg.h | 13 ++++++
4 files changed, 172 insertions(+), 2 deletions(-)
--
1.8.3.2
^ permalink raw reply
* Re: [PATCHv2] tools/l2cap-tester: Fix memory leak
From: Johan Hedberg @ 2013-12-20 10:20 UTC (permalink / raw)
To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1387531829-31079-1-git-send-email-marcin.kraglak@tieto.com>
Hi Marcin,
On Fri, Dec 20, 2013, Marcin Kraglak wrote:
> Set close_on_unref on new created GIOChannel and don't close
> its file descriptor.
>
> 126 (120 direct, 6 indirect) bytes in 1 blocks aredefinitely
> lost in loss record 24 of 28
> at 0x4A06409: malloc (in/usr/lib64/valgrind/vgpreload_memcheck
> -amd64-linux.so)
> by 0x3C9564D88E: g_malloc (in /usr/lib64/libglib-2.0.so.0.3600.3)
> by 0x3C956881F4: g_io_channel_unix_new (in/usr/lib64/libglib-
> 2.0.so.0.3600.3)
> by 0x402A5A: l2cap_listen_cb (l2cap-tester.c:774)
> by 0x3C95647DF5: g_main_context_dispatch (in/usr/lib64/
> libglib-2.0.so.0.3600.3)
> by 0x3C95648147: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
> by 0x3C95648549: g_main_loop_run
> (in/usr/lib64/libglib-2.0.so.0.3600.3)
> by 0x40A67C: tester_run (tester.c:784)
> by 0x4026A9: main (l2cap-tester.c:991)
> ---
> tools/l2cap-tester.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH BlueZ] android/AVDTP: Duplicate fd passed to avdtp_new
From: Ravi kumar Veeramally @ 2013-12-20 10:08 UTC (permalink / raw)
To: Luiz Augusto von Dentz, linux-bluetooth
In-Reply-To: <1387533387-6724-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On 20.12.2013 11:56, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This use dup to create a new fd to be used by AVDTP session leaving the
> caller free to close the original fd. Note that even if the caller
> decides to keep the original fd it will still be notified when
> avdtp_shutdown is called since it uses shutdown.
> ---
> android/a2dp.c | 1 -
> android/avdtp.c | 7 ++++++-
> 2 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/android/a2dp.c b/android/a2dp.c
> index 9087c62..b7bb8d2 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -150,7 +150,6 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
> return;
> }
>
> - g_io_channel_set_close_on_unref(chan, FALSE);
> fd = g_io_channel_unix_get_fd(chan);
>
> /* FIXME: Add proper version */
> diff --git a/android/avdtp.c b/android/avdtp.c
> index 353316c..ec78cc6 100644
> --- a/android/avdtp.c
> +++ b/android/avdtp.c
> @@ -2055,9 +2055,14 @@ struct avdtp *avdtp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
> {
> struct avdtp *session;
> GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
> + int new_fd;
> +
> + new_fd = dup(fd);
> + if (new_fd < 0)
> + return NULL;
You are returning NULL here, but not checking at
static void signaling_connect_cb(...)
dev->session = avdtp_new(fd, imtu, omtu, 0x0100);
>
> session = g_new0(struct avdtp, 1);
> - session->io = g_io_channel_unix_new(fd);
> + session->io = g_io_channel_unix_new(new_fd);
> session->version = version;
> session->imtu = imtu;
> session->omtu = omtu;
Regards,
Ravi.
^ 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