* [PATCH v2 04/10] emulator: Add handling inquiry number of responses
From: Lukasz Rymanowski @ 2014-03-09 23:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lukasz Rymanowski
In-Reply-To: <1394406363-6751-1-git-send-email-lukasz.rymanowski@tieto.com>
---
emulator/btdev.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/emulator/btdev.c b/emulator/btdev.c
index 3c0b0ad..c932a18 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -129,6 +129,8 @@ struct btdev {
struct inquiry_data {
struct btdev *btdev;
+ int num_resp;
+
int sent_count;
int iter;
};
@@ -705,6 +707,7 @@ static bool inquiry_callback(void *user_data)
{
struct inquiry_data *data = user_data;
struct btdev *btdev = data->btdev;
+ struct bt_hci_evt_inquiry_complete ic;
int sent = data->sent_count;
int i;
@@ -769,17 +772,22 @@ static bool inquiry_callback(void *user_data)
}
}
- if (i == MAX_BTDEV_ENTRIES) {
- struct bt_hci_evt_inquiry_complete ic;
-
- ic.status = BT_HCI_ERR_SUCCESS;
- send_event(btdev, BT_HCI_EVT_INQUIRY_COMPLETE, &ic, sizeof(ic));
+ /* Check if we sent already required amount of responses*/
+ if (data->num_resp && data->sent_count == data->num_resp)
+ goto finish;
- btdev->inquiry_id = 0;
- return false;
- }
+ if (i == MAX_BTDEV_ENTRIES)
+ goto finish;
return true;
+
+finish:
+ /* Note that destroy will be called */
+ ic.status = BT_HCI_ERR_SUCCESS;
+ send_event(btdev, BT_HCI_EVT_INQUIRY_COMPLETE, &ic, sizeof(ic));
+
+ btdev->inquiry_id = 0;
+ return false;
}
static void inquiry_destroy(void *user_data)
@@ -804,6 +812,7 @@ finish:
static void inquiry_cmd(struct btdev *btdev, const void *cmd)
{
+ const struct bt_hci_cmd_inquiry *inq_cmd = cmd;
struct inquiry_data *data;
struct bt_hci_evt_inquiry_complete ic;
int status = BT_HCI_ERR_HARDWARE_FAILURE;
@@ -819,6 +828,7 @@ static void inquiry_cmd(struct btdev *btdev, const void *cmd)
memset(data, 0, sizeof(*data));
data->btdev = btdev;
+ data->num_resp = inq_cmd->num_resp;
btdev->inquiry_id = timeout_add(DEFAULT_INQUIRY_INTERVAL,
inquiry_callback, data, inquiry_destroy);
--
1.8.4
^ permalink raw reply related
* [PATCH v2 03/10] emulator: Add inquiry cancel
From: Lukasz Rymanowski @ 2014-03-09 23:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lukasz Rymanowski
In-Reply-To: <1394406363-6751-1-git-send-email-lukasz.rymanowski@tieto.com>
With this patch, scheduled inquiry session in btdev can be canceled
Conflicts:
emulator/btdev.c
---
emulator/btdev.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/emulator/btdev.c b/emulator/btdev.c
index 8b3a2d8..3c0b0ad 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -70,6 +70,7 @@ struct btdev {
void *send_data;
int inquiry_id;
+ bool inquiry_cancel;
struct hook *hook_list[MAX_HOOK_ENTRIES];
@@ -784,10 +785,20 @@ static bool inquiry_callback(void *user_data)
static void inquiry_destroy(void *user_data)
{
struct inquiry_data *data = user_data;
+ struct btdev *btdev = data->btdev;
+ uint8_t status = BT_HCI_ERR_SUCCESS;
+
+ if (!btdev)
+ goto finish;
- if (data->btdev)
- data->btdev->inquiry_id = 0;
+ if (btdev->inquiry_cancel)
+ cmd_complete(btdev, BT_HCI_CMD_INQUIRY_CANCEL, &status,
+ sizeof(status));
+ btdev->inquiry_cancel = false;
+ btdev->inquiry_id = 0;
+
+finish:
free(data);
}
@@ -820,6 +831,20 @@ error:
send_event(btdev, BT_HCI_EVT_INQUIRY_COMPLETE, &ic, sizeof(ic));
}
+static void inquiry_cancel(struct btdev *btdev)
+{
+ uint8_t status = BT_HCI_ERR_COMMAND_DISALLOWED;
+
+ if (!btdev->inquiry_id) {
+ cmd_complete(btdev, BT_HCI_CMD_INQUIRY_CANCEL, &status,
+ sizeof(status));
+ return;
+ }
+
+ btdev->inquiry_cancel = true;
+ timeout_remove(btdev->inquiry_id);
+ btdev->inquiry_id = 0;
+}
static void conn_complete(struct btdev *btdev,
const uint8_t *bdaddr, uint8_t status)
{
@@ -1637,8 +1662,7 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
case BT_HCI_CMD_INQUIRY_CANCEL:
if (btdev->type == BTDEV_TYPE_LE)
goto unsupported;
- status = BT_HCI_ERR_SUCCESS;
- cmd_complete(btdev, opcode, &status, sizeof(status));
+ inquiry_cancel(btdev);
break;
case BT_HCI_CMD_CREATE_CONN:
--
1.8.4
^ permalink raw reply related
* [PATCH v2 02/10] emulator: Use timeout for sending inquiry results
From: Lukasz Rymanowski @ 2014-03-09 23:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lukasz Rymanowski
In-Reply-To: <1394406363-6751-1-git-send-email-lukasz.rymanowski@tieto.com>
With this patch btdev uses timeout to schedule inquiry results
It also allows btdev to receive hci commands during inquiry.
Previously btdev was blocked since all the inquiry result were sent in
single loop
---
Makefile.tools | 19 ++++++++----
android/Makefile.am | 2 ++
emulator/btdev.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++----
3 files changed, 93 insertions(+), 12 deletions(-)
diff --git a/Makefile.tools b/Makefile.tools
index 7ffdbc6..88a15ee 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -48,6 +48,7 @@ emulator_btvirt_SOURCES = emulator/main.c monitor/bt.h \
monitor/mainloop.h monitor/mainloop.c \
src/shared/util.h src/shared/util.c \
src/shared/crypto.h src/shared/crypto.c \
+ src/sharead/timeout.h src/shared/timeout-mainloop.c \
emulator/server.h emulator/server.c \
emulator/vhci.h emulator/vhci.c \
emulator/btdev.h emulator/btdev.c \
@@ -84,7 +85,8 @@ tools_mgmt_tester_SOURCES = tools/mgmt-tester.c monitor/bt.h \
src/shared/util.h src/shared/util.c \
src/shared/mgmt.h src/shared/mgmt.c \
src/shared/hciemu.h src/shared/hciemu.c \
- src/shared/tester.h src/shared/tester.c
+ src/shared/tester.h src/shared/tester.c \
+ src/shared/timeout.h src/shared/timeout-glib.c
tools_mgmt_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
tools_l2cap_tester_SOURCES = tools/l2cap-tester.c monitor/bt.h \
@@ -97,7 +99,8 @@ tools_l2cap_tester_SOURCES = tools/l2cap-tester.c monitor/bt.h \
src/shared/util.h src/shared/util.c \
src/shared/mgmt.h src/shared/mgmt.c \
src/shared/hciemu.h src/shared/hciemu.c \
- src/shared/tester.h src/shared/tester.c
+ src/shared/tester.h src/shared/tester.c \
+ src/shared/timeout.h src/shared/timeout-glib.c
tools_l2cap_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
tools_rfcomm_tester_SOURCES = tools/rfcomm-tester.c monitor/bt.h \
@@ -110,7 +113,8 @@ tools_rfcomm_tester_SOURCES = tools/rfcomm-tester.c monitor/bt.h \
src/shared/util.h src/shared/util.c \
src/shared/mgmt.h src/shared/mgmt.c \
src/shared/hciemu.h src/shared/hciemu.c \
- src/shared/tester.h src/shared/tester.c
+ src/shared/tester.h src/shared/tester.c \
+ src/shared/timeout.h src/shared/timeout-glib.c
tools_rfcomm_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
tools_smp_tester_SOURCES = tools/smp-tester.c monitor/bt.h \
@@ -123,7 +127,8 @@ tools_smp_tester_SOURCES = tools/smp-tester.c monitor/bt.h \
src/shared/util.h src/shared/util.c \
src/shared/mgmt.h src/shared/mgmt.c \
src/shared/hciemu.h src/shared/hciemu.c \
- src/shared/tester.h src/shared/tester.c
+ src/shared/tester.h src/shared/tester.c \
+ src/shared/timeout.h src/shared/timeout-glib.c
tools_smp_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
tools_gap_tester_SOURCES = tools/gap-tester.c monitor/bt.h \
@@ -134,7 +139,8 @@ tools_gap_tester_SOURCES = tools/gap-tester.c monitor/bt.h \
src/shared/util.h src/shared/util.c \
src/shared/queue.h src/shared/queue.c \
src/shared/hciemu.h src/shared/hciemu.c \
- src/shared/tester.h src/shared/tester.c
+ src/shared/tester.h src/shared/tester.c \
+ src/shared/timeout.h src/shared/timeout-glib.c
tools_gap_tester_LDADD = lib/libbluetooth-internal.la \
gdbus/libgdbus-internal.la \
@GLIB_LIBS@ @DBUS_LIBS@
@@ -149,7 +155,8 @@ tools_sco_tester_SOURCES = tools/sco-tester.c monitor/bt.h \
src/shared/util.h src/shared/util.c \
src/shared/mgmt.h src/shared/mgmt.c \
src/shared/hciemu.h src/shared/hciemu.c \
- src/shared/tester.h src/shared/tester.c
+ src/shared/tester.h src/shared/tester.c \
+ src/shared/timeout.h src/shared/timeout-glib.c
tools_sco_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
tools_hci_tester_SOURCES = tools/hci-tester.c monitor/bt.h \
diff --git a/android/Makefile.am b/android/Makefile.am
index bbd3d2f..b3a8cc8 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -119,6 +119,7 @@ android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
src/shared/mgmt.h src/shared/mgmt.c \
src/shared/hciemu.h src/shared/hciemu.c \
src/shared/tester.h src/shared/tester.c \
+ src/shared/timeout.h src/shared/timeout-glib.c \
monitor/rfcomm.h \
android/hardware/hardware.c \
android/android-tester.c
@@ -142,6 +143,7 @@ android_ipc_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
src/shared/mgmt.h src/shared/mgmt.c \
src/shared/hciemu.h src/shared/hciemu.c \
src/shared/tester.h src/shared/tester.c \
+ src/shared/timeout.h src/shared/timeout-glib.c \
android/hal-utils.h android/hal-utils.c \
android/ipc-tester.c
diff --git a/emulator/btdev.c b/emulator/btdev.c
index 2cf8f89..8b3a2d8 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -33,6 +33,7 @@
#include <alloca.h>
#include "src/shared/util.h"
+#include "src/shared/timeout.h"
#include "monitor/bt.h"
#include "btdev.h"
@@ -68,6 +69,8 @@ struct btdev {
btdev_send_func send_handler;
void *send_data;
+ int inquiry_id;
+
struct hook *hook_list[MAX_HOOK_ENTRIES];
uint16_t manufacturer;
@@ -123,8 +126,17 @@ struct btdev {
uint8_t sync_train_service_data;
};
+struct inquiry_data {
+ struct btdev *btdev;
+ int sent_count;
+ int iter;
+};
+
+#define DEFAULT_INQUIRY_INTERVAL 100 /* 100 miliseconds */
+
#define MAX_BTDEV_ENTRIES 16
+
static const uint8_t LINK_KEY_NONE[16] = { 0 };
static const uint8_t LINK_KEY_DUMMY[16] = { 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 0, 1, 2, 3, 4, 5 };
@@ -528,9 +540,13 @@ void btdev_destroy(struct btdev *btdev)
if (!btdev)
return;
+ if (btdev->inquiry_id)
+ timeout_remove(btdev->inquiry_id);
+
del_btdev(btdev);
free(btdev);
+ btdev = NULL;
}
const uint8_t *btdev_get_bdaddr(struct btdev *btdev)
@@ -684,12 +700,18 @@ static void num_completed_packets(struct btdev *btdev)
}
}
-static void inquiry_complete(struct btdev *btdev, uint8_t status)
+static bool inquiry_callback(void *user_data)
{
- struct bt_hci_evt_inquiry_complete ic;
+ struct inquiry_data *data = user_data;
+ struct btdev *btdev = data->btdev;
+ int sent = data->sent_count;
int i;
- for (i = 0; i < MAX_BTDEV_ENTRIES; i++) {
+ for (i = data->iter; i < MAX_BTDEV_ENTRIES; i++, data->iter++) {
+ /*Lets sent 10 inquiry results at once */
+ if (sent + 10 == data->sent_count)
+ break;
+
if (!btdev_list[i] || btdev_list[i] == btdev)
continue;
@@ -711,6 +733,7 @@ static void inquiry_complete(struct btdev *btdev, uint8_t status)
send_event(btdev, BT_HCI_EVT_EXT_INQUIRY_RESULT, &ir,
sizeof(ir));
+ data->sent_count++;
continue;
}
@@ -727,6 +750,7 @@ static void inquiry_complete(struct btdev *btdev, uint8_t status)
send_event(btdev, BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI,
&ir, sizeof(ir));
+ data->sent_count++;
} else {
struct bt_hci_evt_inquiry_result ir;
@@ -740,11 +764,59 @@ static void inquiry_complete(struct btdev *btdev, uint8_t status)
send_event(btdev, BT_HCI_EVT_INQUIRY_RESULT, &ir,
sizeof(ir));
+ data->sent_count++;
}
- }
+ }
- ic.status = status;
+ if (i == MAX_BTDEV_ENTRIES) {
+ struct bt_hci_evt_inquiry_complete ic;
+
+ ic.status = BT_HCI_ERR_SUCCESS;
+ send_event(btdev, BT_HCI_EVT_INQUIRY_COMPLETE, &ic, sizeof(ic));
+
+ btdev->inquiry_id = 0;
+ return false;
+ }
+ return true;
+}
+
+static void inquiry_destroy(void *user_data)
+{
+ struct inquiry_data *data = user_data;
+
+ if (data->btdev)
+ data->btdev->inquiry_id = 0;
+
+ free(data);
+}
+
+static void inquiry_cmd(struct btdev *btdev, const void *cmd)
+{
+ struct inquiry_data *data;
+ struct bt_hci_evt_inquiry_complete ic;
+ int status = BT_HCI_ERR_HARDWARE_FAILURE;
+
+ if (btdev->inquiry_id) {
+ status = BT_HCI_ERR_COMMAND_DISALLOWED;
+ goto error;
+ }
+
+ data = malloc(sizeof(*data));
+ if (!data)
+ goto error;
+
+ memset(data, 0, sizeof(*data));
+ data->btdev = btdev;
+
+ btdev->inquiry_id = timeout_add(DEFAULT_INQUIRY_INTERVAL,
+ inquiry_callback, data, inquiry_destroy);
+ /* Return if success */
+ if (btdev->inquiry_id)
+ return;
+
+error:
+ ic.status = status;
send_event(btdev, BT_HCI_EVT_INQUIRY_COMPLETE, &ic, sizeof(ic));
}
@@ -2491,7 +2563,7 @@ static void default_cmd_completion(struct btdev *btdev, uint16_t opcode,
case BT_HCI_CMD_INQUIRY:
if (btdev->type == BTDEV_TYPE_LE)
return;
- inquiry_complete(btdev, BT_HCI_ERR_SUCCESS);
+ inquiry_cmd(btdev, data);
break;
case BT_HCI_CMD_CREATE_CONN:
--
1.8.4
^ permalink raw reply related
* [PATCH v2 01/10] emulator: Minor style fix
From: Lukasz Rymanowski @ 2014-03-09 23:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lukasz Rymanowski
In-Reply-To: <1394406363-6751-1-git-send-email-lukasz.rymanowski@tieto.com>
---
emulator/btdev.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/emulator/btdev.c b/emulator/btdev.c
index b54f91e..2cf8f89 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -709,8 +709,8 @@ static void inquiry_complete(struct btdev *btdev, uint8_t status)
ir.rssi = -60;
memcpy(ir.data, btdev_list[i]->ext_inquiry_rsp, 240);
- send_event(btdev, BT_HCI_EVT_EXT_INQUIRY_RESULT,
- &ir, sizeof(ir));
+ send_event(btdev, BT_HCI_EVT_EXT_INQUIRY_RESULT, &ir,
+ sizeof(ir));
continue;
}
@@ -738,8 +738,8 @@ static void inquiry_complete(struct btdev *btdev, uint8_t status)
memcpy(ir.dev_class, btdev_list[i]->dev_class, 3);
ir.clock_offset = 0x0000;
- send_event(btdev, BT_HCI_EVT_INQUIRY_RESULT,
- &ir, sizeof(ir));
+ send_event(btdev, BT_HCI_EVT_INQUIRY_RESULT, &ir,
+ sizeof(ir));
}
}
--
1.8.4
^ permalink raw reply related
* [PATCH v2 00/10] Change inquiry handling in btdev
From: Lukasz Rymanowski @ 2014-03-09 23:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lukasz Rymanowski
This patch set introduce new way of handling inquiry in btdev.
v2:
* Changes in handling inquiry lenght
* Changes in handling inquiry cancel
* Updates in mgmt-tester
Lukasz Rymanowski (10):
emulator: Minor style fix
emulator: Use timeout for sending inquiry results
emulator: Add inquiry cancel
emulator: Add handling inquiry number of responses
emulator: Add handling inquiry_lenght from inquiry command
android/tester: Fix handling inquiry by android tester
tools/mgmt-tester: Fix for Stop discovery test
tools/mgmt-tester: Update Stop Discovery-BR/EDR (Inquiry) Success 1
tools/mgmt-tester: Remove not used condition
tools/mgmt-tester: Refactor setup_start_discovery function
Makefile.tools | 19 ++++--
android/Makefile.am | 2 +
android/android-tester.c | 24 ++-----
emulator/btdev.c | 166 +++++++++++++++++++++++++++++++++++++++++++----
tools/mgmt-tester.c | 70 +++++---------------
5 files changed, 194 insertions(+), 87 deletions(-)
--
1.8.4
^ permalink raw reply
* [PATCH] Bluetooth: Make LTK and CSRK only persisent when bonding
From: Marcel Holtmann @ 2014-03-09 22:00 UTC (permalink / raw)
To: linux-bluetooth
In case the pairable option has been disabled, the pairing procedure
does not create keys for bonding. This means that these generated keys
should not be stored persistently.
For LTK and CSRK this is important to tell userspace to not store these
new keys. They will be available for the lifetime of the device, but
after the next power cycle they should not be used anymore.
Make sure that the SMP pairing procedures rememberes the authentication
request information for bonding and if both sides request bonding, then
inform userspace to actually store the keys persistently.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 5 +++--
net/bluetooth/mgmt.c | 9 +++++----
net/bluetooth/smp.c | 15 +++++++++++----
net/bluetooth/smp.h | 1 +
4 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e869884fbfa9..b8cc39a4a9a5 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1270,9 +1270,10 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
-void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key);
+void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent);
void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
-void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk);
+void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
+ bool persistent);
void mgmt_reenable_advertising(struct hci_dev *hdev);
void mgmt_smp_complete(struct hci_conn *conn, bool complete);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 9c7788914b4e..fbcf9d4f130b 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -5005,7 +5005,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
}
-void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key)
+void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent)
{
struct mgmt_ev_new_long_term_key ev;
@@ -5026,7 +5026,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key)
(key->bdaddr.b[5] & 0xc0) != 0xc0)
ev.store_hint = 0x00;
else
- ev.store_hint = 0x01;
+ ev.store_hint = persistent;
bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type);
@@ -5073,7 +5073,8 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk)
mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
}
-void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk)
+void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
+ bool persistent)
{
struct mgmt_ev_new_csrk ev;
@@ -5092,7 +5093,7 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk)
(csrk->bdaddr.b[5] & 0xc0) != 0xc0)
ev.store_hint = 0x00;
else
- ev.store_hint = 0x01;
+ ev.store_hint = persistent;
bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr);
ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type);
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index fc652592daf6..1a6a24fc1bb3 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -716,6 +716,8 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
if (ret)
return SMP_UNSPECIFIED;
+ smp->auth_req = auth;
+
return 0;
}
@@ -758,6 +760,8 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
if (ret)
return SMP_UNSPECIFIED;
+ smp->auth_req = auth;
+
set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
/* Can't compose response until we have been confirmed */
@@ -1209,32 +1213,35 @@ static void smp_notify_keys(struct l2cap_conn *conn)
struct smp_chan *smp = conn->smp_chan;
struct hci_conn *hcon = conn->hcon;
struct hci_dev *hdev = hcon->hdev;
+ bool persistent;
if (smp->remote_irk)
mgmt_new_irk(hdev, smp->remote_irk);
+ persistent = !!(smp->auth_req & SMP_AUTH_BONDING);
+
if (smp->csrk) {
smp->csrk->bdaddr_type = hcon->dst_type;
bacpy(&smp->csrk->bdaddr, &hcon->dst);
- mgmt_new_csrk(hdev, smp->csrk);
+ mgmt_new_csrk(hdev, smp->csrk, persistent);
}
if (smp->slave_csrk) {
smp->slave_csrk->bdaddr_type = hcon->dst_type;
bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
- mgmt_new_csrk(hdev, smp->slave_csrk);
+ mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
}
if (smp->ltk) {
smp->ltk->bdaddr_type = hcon->dst_type;
bacpy(&smp->ltk->bdaddr, &hcon->dst);
- mgmt_new_ltk(hdev, smp->ltk);
+ mgmt_new_ltk(hdev, smp->ltk, persistent);
}
if (smp->slave_ltk) {
smp->slave_ltk->bdaddr_type = hcon->dst_type;
bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
- mgmt_new_ltk(hdev, smp->slave_ltk);
+ mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
}
}
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index f223b9d38b61..b7c6f903e895 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -131,6 +131,7 @@ struct smp_chan {
u8 rrnd[16]; /* SMP Pairing Random (remote) */
u8 pcnf[16]; /* SMP Pairing Confirm */
u8 tk[16]; /* SMP Temporary Key */
+ u8 auth_req;
u8 enc_key_size;
u8 remote_key_dist;
bdaddr_t id_addr;
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCH] Bluetooth: Add support for handling signature resolving keys
From: Johan Hedberg @ 2014-03-09 19:42 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1394392757-49734-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Sun, Mar 09, 2014, Marcel Holtmann wrote:
> The connection signature resolving key (CSRK) is used for attribute
> protocol signed write procedures. This change generates a new local
> key during pairing and requests the peer key as well.
>
> Newly generated key and received key will be provided to userspace
> using the New Signature Resolving Key management event.
>
> The Master CSRK can be used for verification of remote signed write
> PDUs and the Slave CSRK can be used for sending signed write PDUs
> to the remote device.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> include/net/bluetooth/hci_core.h | 8 +++++
> include/net/bluetooth/mgmt.h | 12 +++++++
> net/bluetooth/mgmt.c | 30 ++++++++++++++++++
> net/bluetooth/smp.c | 67 +++++++++++++++++++++++++++++++++++++---
> net/bluetooth/smp.h | 2 ++
> 5 files changed, 114 insertions(+), 5 deletions(-)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* [PATCH] Bluetooth: Add support for handling signature resolving keys
From: Marcel Holtmann @ 2014-03-09 19:19 UTC (permalink / raw)
To: linux-bluetooth
The connection signature resolving key (CSRK) is used for attribute
protocol signed write procedures. This change generates a new local
key during pairing and requests the peer key as well.
Newly generated key and received key will be provided to userspace
using the New Signature Resolving Key management event.
The Master CSRK can be used for verification of remote signed write
PDUs and the Slave CSRK can be used for sending signed write PDUs
to the remote device.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 8 +++++
include/net/bluetooth/mgmt.h | 12 +++++++
net/bluetooth/mgmt.c | 30 ++++++++++++++++++
net/bluetooth/smp.c | 67 +++++++++++++++++++++++++++++++++++++---
net/bluetooth/smp.h | 2 ++
5 files changed, 114 insertions(+), 5 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index dbb788e4f265..e869884fbfa9 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -91,6 +91,13 @@ struct bt_uuid {
u8 svc_hint;
};
+struct smp_csrk {
+ bdaddr_t bdaddr;
+ u8 bdaddr_type;
+ u8 master;
+ u8 val[16];
+};
+
struct smp_ltk {
struct list_head list;
bdaddr_t bdaddr;
@@ -1265,6 +1272,7 @@ int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key);
void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
+void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk);
void mgmt_reenable_advertising(struct hci_dev *hdev);
void mgmt_smp_complete(struct hci_conn *conn, bool complete);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 0326648fd799..d4b571c2f9fd 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -551,3 +551,15 @@ struct mgmt_ev_new_irk {
bdaddr_t rpa;
struct mgmt_irk_info irk;
} __packed;
+
+struct mgmt_csrk_info {
+ struct mgmt_addr_info addr;
+ __u8 master;
+ __u8 val[16];
+} __packed;
+
+#define MGMT_EV_NEW_CSRK 0x0019
+struct mgmt_ev_new_csrk {
+ __u8 store_hint;
+ struct mgmt_csrk_info key;
+} __packed;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f2397e7ad385..9c7788914b4e 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -108,6 +108,7 @@ static const u16 mgmt_events[] = {
MGMT_EV_DEVICE_UNPAIRED,
MGMT_EV_PASSKEY_NOTIFY,
MGMT_EV_NEW_IRK,
+ MGMT_EV_NEW_CSRK,
};
#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000)
@@ -5072,6 +5073,35 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk)
mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
}
+void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk)
+{
+ struct mgmt_ev_new_csrk ev;
+
+ memset(&ev, 0, sizeof(ev));
+
+ /* Devices using resolvable or non-resolvable random addresses
+ * without providing an indentity resolving key don't require
+ * to store signature resolving keys. Their addresses will change
+ * the next time around.
+ *
+ * Only when a remote device provides an identity address
+ * make sure the signature resolving key is stored. So allow
+ * static random and public addresses here.
+ */
+ if (csrk->bdaddr_type == ADDR_LE_DEV_RANDOM &&
+ (csrk->bdaddr.b[5] & 0xc0) != 0xc0)
+ ev.store_hint = 0x00;
+ else
+ ev.store_hint = 0x01;
+
+ bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr);
+ ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type);
+ ev.key.master = csrk->master;
+ memcpy(ev.key.val, csrk->val, sizeof(csrk->val));
+
+ mgmt_event(MGMT_EV_NEW_CSRK, hdev, &ev, sizeof(ev), NULL);
+}
+
static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
u8 data_len)
{
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index f886bcae1b7e..fc652592daf6 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -273,8 +273,8 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
u8 local_dist = 0, remote_dist = 0;
if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
- local_dist = SMP_DIST_ENC_KEY;
- remote_dist = SMP_DIST_ENC_KEY;
+ local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
+ remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
authreq |= SMP_AUTH_BONDING;
} else {
authreq &= ~SMP_AUTH_BONDING;
@@ -596,6 +596,9 @@ void smp_chan_destroy(struct l2cap_conn *conn)
complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
mgmt_smp_complete(conn->hcon, complete);
+ kfree(smp->csrk);
+ kfree(smp->slave_csrk);
+
/* If pairing failed clean up any keys we might have */
if (!complete) {
if (smp->ltk) {
@@ -1065,6 +1068,41 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
return 0;
}
+static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+ struct smp_cmd_sign_info *rp = (void *) skb->data;
+ struct smp_chan *smp = conn->smp_chan;
+ struct hci_dev *hdev = conn->hcon->hdev;
+ struct smp_csrk *csrk;
+
+ BT_DBG("conn %p", conn);
+
+ if (skb->len < sizeof(*rp))
+ return SMP_UNSPECIFIED;
+
+ /* Ignore this PDU if it wasn't requested */
+ if (!(smp->remote_key_dist & SMP_DIST_SIGN))
+ return 0;
+
+ /* Mark the information as received */
+ smp->remote_key_dist &= ~SMP_DIST_SIGN;
+
+ skb_pull(skb, sizeof(*rp));
+
+ hci_dev_lock(hdev);
+ csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
+ if (csrk) {
+ csrk->master = 0x01;
+ memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
+ }
+ smp->csrk = csrk;
+ if (!(smp->remote_key_dist & SMP_DIST_SIGN))
+ smp_distribute_keys(conn);
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct hci_conn *hcon = conn->hcon;
@@ -1147,8 +1185,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
break;
case SMP_CMD_SIGN_INFO:
- /* Just ignored */
- reason = 0;
+ reason = smp_cmd_sign_info(conn, skb);
break;
default:
@@ -1176,6 +1213,18 @@ static void smp_notify_keys(struct l2cap_conn *conn)
if (smp->remote_irk)
mgmt_new_irk(hdev, smp->remote_irk);
+ if (smp->csrk) {
+ smp->csrk->bdaddr_type = hcon->dst_type;
+ bacpy(&smp->csrk->bdaddr, &hcon->dst);
+ mgmt_new_csrk(hdev, smp->csrk);
+ }
+
+ if (smp->slave_csrk) {
+ smp->slave_csrk->bdaddr_type = hcon->dst_type;
+ bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
+ mgmt_new_csrk(hdev, smp->slave_csrk);
+ }
+
if (smp->ltk) {
smp->ltk->bdaddr_type = hcon->dst_type;
bacpy(&smp->ltk->bdaddr, &hcon->dst);
@@ -1274,10 +1323,18 @@ int smp_distribute_keys(struct l2cap_conn *conn)
if (*keydist & SMP_DIST_SIGN) {
struct smp_cmd_sign_info sign;
+ struct smp_csrk *csrk;
- /* Send a dummy key */
+ /* Generate a new random key */
get_random_bytes(sign.csrk, sizeof(sign.csrk));
+ csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
+ if (csrk) {
+ csrk->master = 0x00;
+ memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
+ }
+ smp->slave_csrk = csrk;
+
smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
*keydist &= ~SMP_DIST_SIGN;
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index f55d83617218..f223b9d38b61 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -136,6 +136,8 @@ struct smp_chan {
bdaddr_t id_addr;
u8 id_addr_type;
u8 irk[16];
+ struct smp_csrk *csrk;
+ struct smp_csrk *slave_csrk;
struct smp_ltk *ltk;
struct smp_ltk *slave_ltk;
struct smp_irk *remote_irk;
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCH 1/2] android: Fix type of discovery on start/stop discovery
From: Szymon Janc @ 2014-03-09 14:09 UTC (permalink / raw)
To: Lukasz Rymanowski; +Cc: linux-bluetooth
In-Reply-To: <1394188110-16336-1-git-send-email-lukasz.rymanowski@tieto.com>
Hi Łukasz,
On Friday 07 of March 2014 11:28:29 Lukasz Rymanowski wrote:
> Discovering type was confused with adapter settings. With this patch it
> is fixed
> ---
> android/bluetooth.c | 14 ++++++--------
> 1 file changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/android/bluetooth.c b/android/bluetooth.c
> index 1101b64..6d08a50 100644
> --- a/android/bluetooth.c
> +++ b/android/bluetooth.c
> @@ -2408,14 +2408,13 @@ static void get_adapter_properties(void)
> 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;
> + if (adapter.current_settings & MGMT_SETTING_BREDR)
> + cp.type = 1 << BDADDR_BREDR;
> else
> cp.type = 0;
>
> - DBG("type=0x%x", type);
> + DBG("type=0x%x", cp.type);
>
> if (mgmt_send(mgmt_if, MGMT_OP_START_DISCOVERY, adapter.index,
> sizeof(cp), &cp, NULL, NULL, NULL) > 0)
> @@ -2428,14 +2427,13 @@ static bool start_discovery(void)
> 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;
> + if (adapter.current_settings & MGMT_SETTING_BREDR)
> + cp.type = 1 << BDADDR_BREDR;
> else
> cp.type = 0;
>
> - DBG("type=0x%x", type);
> + DBG("type=0x%x", cp.type);
>
> if (mgmt_send(mgmt_if, MGMT_OP_STOP_DISCOVERY, adapter.index,
> sizeof(cp), &cp, NULL, NULL, NULL) > 0)
Both patches applied. Thanks.
--
BR
Szymon Janc
^ permalink raw reply
* [PATCH BlueZ 2/2] android/avrcp: Fix not handling SetAbsoluteVolume response
From: Luiz Augusto von Dentz @ 2014-03-09 11:24 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1394364285-684-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This follow what is stated in AVRCP specification 1.5 page 83:
" When the volume is changed on the TG by this command the Volume Change
notification shall not be completed."
Therefore the only option is to treat the response and self generate
changed notification.
---
android/avrcp.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/android/avrcp.c b/android/avrcp.c
index e26ddf2..7dfb661 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -330,6 +330,31 @@ done:
HAL_OP_AVRCP_REGISTER_NOTIFICATION, status);
}
+static gboolean set_volume_rsp(struct avctp *conn,
+ uint8_t code, uint8_t subunit,
+ uint8_t *operands, size_t operand_count,
+ void *user_data)
+{
+ struct hal_ev_avrcp_volume_changed ev;
+ uint8_t *params;
+
+ if (code != AVC_CTYPE_INTERIM && code != AVC_CTYPE_CHANGED)
+ return FALSE;
+
+ if (operands == NULL || operand_count < 7)
+ return FALSE;
+
+ params = &operands[7];
+
+ ev.volume = params[0] & 0x7F;
+
+ ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP,
+ HAL_EV_AVRCP_VOLUME_CHANGED,
+ sizeof(ev), &ev);
+
+ return FALSE;
+}
+
static void handle_set_volume(const void *buf, uint16_t len)
{
struct hal_cmd_avrcp_set_volume *cmd = (void *) buf;
@@ -350,7 +375,8 @@ static void handle_set_volume(const void *buf, uint16_t len)
*/
dev = devices->data;
- ret = avrcp_set_volume(dev->session, cmd->value & 0x7f, NULL, NULL);
+ ret = avrcp_set_volume(dev->session, cmd->value & 0x7f, set_volume_rsp,
+ dev);
if (ret < 0) {
status = HAL_STATUS_FAILED;
goto done;
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ 1/2] android/hal-avrcp: Fill attributes in case of empty for GetElementAttributes
From: Luiz Augusto von Dentz @ 2014-03-09 11:24 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This has to be done since the upper layer to not interpret empty list as
get all attributes.
---
android/hal-avrcp.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index 5f98f5b..0a5f500 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -134,11 +134,19 @@ static void handle_get_element_attrs(void *buf, uint16_t len)
if (!cbs->get_element_attr_cb)
return;
+ /* Set everything in case of empty list */
+ if (ev->number == 0) {
+ for (i = 0; i < BTRC_MAX_APP_SETTINGS; i++)
+ attrs[i] = i;
+ goto done;
+ }
+
/* Convert uint8_t array to btrc_media_attr_t array */
for (i = 0; i < ev->number; i++)
attrs[i] = ev->attrs[i];
- cbs->get_element_attr_cb(ev->number, attrs);
+done:
+ cbs->get_element_attr_cb(i, attrs);
}
static void handle_register_notification(void *buf, uint16_t len)
--
1.8.5.3
^ permalink raw reply related
* [PATCH] Bluetooth: Export signature resolving key in debugfs
From: Marcel Holtmann @ 2014-03-09 7:32 UTC (permalink / raw)
To: linux-bluetooth
Include the current connection signature resolving key (CSRK) as part
of the identity debugfs information.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8bbfdea9cbec..1b2935c61b49 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -589,8 +589,8 @@ static int identity_show(struct seq_file *f, void *p)
hci_copy_identity_address(hdev, &addr, &addr_type);
- seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type,
- 16, hdev->irk, &hdev->rpa);
+ seq_printf(f, "%pMR (type %u) %*phN %pMR %*phN\n", &addr, addr_type,
+ 16, hdev->irk, &hdev->rpa, 16, hdev->csrk);
hci_dev_unlock(hdev);
--
1.8.5.3
^ permalink raw reply related
* [PATCH] doc: Add management command for setting signature resolving key
From: Marcel Holtmann @ 2014-03-09 7:12 UTC (permalink / raw)
To: linux-bluetooth
---
doc/mgmt-api.txt | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index d008704198df..88f79eb87bef 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -1659,6 +1659,31 @@ Load Identity Resolving Keys Command
Invalid Index
+Set Signature Resolving Key Command
+===================================
+
+ Command Code: 0x0031
+ Controller Index: <controller id>
+ Command Parameters: Signature_Resolving_Key (16 Octets)
+ Return Parameters:
+
+ This command allows for setting the signature resolving key and
+ is only supported on controllers with LE support.
+
+ The key can only be changed when the controller is powered off.
+
+ The special empty key (all zeros) can be used to disable the
+ signature resolving key.
+
+ This command generates a Command Complete event on success or a
+ Command Status event on failure.
+
+ Possible errors: Rejected
+ Not Supported
+ Invalid Parameters
+ Invalid Index
+
+
Command Complete Event
======================
--
1.8.5.3
^ permalink raw reply related
* [PATCH 2/2] Bluetooth: Distribute configured signature resolving key over SMP
From: Marcel Holtmann @ 2014-03-09 7:06 UTC (permalink / raw)
To: linux-bluetooth
When the connection signature resolving key (CSRK) is requested over
SMP and it has been configured from userspace, then distribute it.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/smp.c | 6 ++++--
net/bluetooth/smp.h | 2 ++
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index f886bcae1b7e..a98a902eadf1 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -298,6 +298,9 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
return;
}
+ if (memcmp(hdev->csrk, SMP_KEY_NONE, 16))
+ local_dist |= SMP_DIST_SIGN;
+
rsp->io_capability = conn->hcon->io_capability;
rsp->oob_flag = SMP_OOB_NOT_PRESENT;
rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
@@ -1275,8 +1278,7 @@ int smp_distribute_keys(struct l2cap_conn *conn)
if (*keydist & SMP_DIST_SIGN) {
struct smp_cmd_sign_info sign;
- /* Send a dummy key */
- get_random_bytes(sign.csrk, sizeof(sign.csrk));
+ memcpy(sign.csrk, hdev->csrk, sizeof(sign.csrk));
smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index f55d83617218..522e11aa73e8 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -123,6 +123,8 @@ struct smp_cmd_security_req {
#define SMP_REENCRYPT_TIMEOUT msecs_to_jiffies(250)
+#define SMP_KEY_NONE (&(u8[16]) {0, })
+
struct smp_chan {
struct l2cap_conn *conn;
u8 preq[7]; /* SMP Pairing Request */
--
1.8.5.3
^ permalink raw reply related
* [PATCH 1/2] Bluetooth: Add management command for setting signature resolving key
From: Marcel Holtmann @ 2014-03-09 7:06 UTC (permalink / raw)
To: linux-bluetooth
The connection signature resolving key (CSRK) can be used to allow
signed write requests over the attribute protocol. This command
provides userspace with the ability to configure such a key that
can be distributed over SMP if requested.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 1 +
include/net/bluetooth/mgmt.h | 6 ++++++
net/bluetooth/mgmt.c | 28 ++++++++++++++++++++++++++++
3 files changed, 35 insertions(+)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index dbb788e4f265..dd6e58062e34 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -187,6 +187,7 @@ struct hci_dev {
__u16 le_conn_min_interval;
__u16 le_conn_max_interval;
__u8 ssp_debug_mode;
+ __u8 csrk[16];
__u16 devid_source;
__u16 devid_vendor;
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 0326648fd799..d79f81c04cb3 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -409,6 +409,12 @@ struct mgmt_cp_load_irks {
} __packed;
#define MGMT_LOAD_IRKS_SIZE 2
+#define MGMT_OP_SET_CSRK 0x0031
+struct mgmt_cp_set_csrk {
+ __u8 val[16];
+} __packed;
+#define MGMT_SET_CSRK_SIZE 16
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f2397e7ad385..4ccb3baaa4a2 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -83,6 +83,7 @@ static const u16 mgmt_commands[] = {
MGMT_OP_SET_DEBUG_KEYS,
MGMT_OP_SET_PRIVACY,
MGMT_OP_LOAD_IRKS,
+ MGMT_OP_SET_CSRK,
};
static const u16 mgmt_events[] = {
@@ -4554,6 +4555,32 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
return err;
}
+static int set_csrk(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
+{
+ struct mgmt_cp_set_csrk *cp = data;
+ int err;
+
+ BT_DBG("%s", hdev->name);
+
+ if (!lmp_le_capable(hdev))
+ return cmd_status(sk, hdev->id, MGMT_OP_SET_CSRK,
+ MGMT_STATUS_NOT_SUPPORTED);
+
+ if (hdev_is_powered(hdev))
+ return cmd_status(sk, hdev->id, MGMT_OP_SET_CSRK,
+ MGMT_STATUS_REJECTED);
+
+ hci_dev_lock(hdev);
+
+ memcpy(hdev->csrk, cp->val, 16);
+
+ err = cmd_complete(sk, hdev->id, MGMT_OP_SET_CSRK, 0, NULL, 0);
+
+ hci_dev_unlock(hdev);
+
+ return err;
+}
+
static const struct mgmt_handler {
int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
u16 data_len);
@@ -4609,6 +4636,7 @@ static const struct mgmt_handler {
{ set_debug_keys, false, MGMT_SETTING_SIZE },
{ set_privacy, false, MGMT_SET_PRIVACY_SIZE },
{ load_irks, true, MGMT_LOAD_IRKS_SIZE },
+ { set_csrk, false, MGMT_SET_CSRK_SIZE },
};
--
1.8.5.3
^ permalink raw reply related
* Re: Passive scanning of iBeacons results in a "Data Buffer Overflow"
From: Terry Hardie @ 2014-03-09 6:25 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <alpine.DEB.2.02.1403072307490.21384@orcas.net>
On Fri, 7 Mar 2014, Terry Hardie wrote:
> I'm having something similar to what Adam is reporting. I'm running on a
> BeagleBone Black, which uses a TI MUSB controller (I think it's different to
> the Raspberry Pi USB controller?).
I have just found switching the USB 2 hub for a USB 1.1 hub makes the
problem go away... Not sure what that proves though...
^ permalink raw reply
* Re: [PATCH 2/2] android/gatt: Handle Unregister gatt client command
From: Szymon Janc @ 2014-03-08 20:14 UTC (permalink / raw)
To: Grzegorz Kolodziejczyk; +Cc: linux-bluetooth
In-Reply-To: <1394197499-2207-2-git-send-email-grzegorz.kolodziejczyk@tieto.com>
Hi Grzegorz,
On Friday 07 of March 2014 14:04:59 Grzegorz Kolodziejczyk wrote:
> This adds unregister gatt client app command handling.
> ---
> android/gatt.c | 25 ++++++++++++++++++++++++-
> 1 file changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/android/gatt.c b/android/gatt.c
> index f8f7208..1261c1f 100644
> --- a/android/gatt.c
> +++ b/android/gatt.c
> @@ -60,6 +60,13 @@ static int find_client_uuid(gconstpointer data,
> gconstpointer user_data) return 0;
> }
>
> +static int find_client_if(gconstpointer data, gconstpointer user_data)
> +{
> + const int32_t exp_cif = *((int32_t *)user_data);
You can use int to pointer macro to pass int here.
> + const int32_t cur_cif = ((struct gatt_client *)data)->client_if;
const struct gatt_client *client = data;
> +
> + return cur_cif != exp_cif;
> +}
>
> static void handle_client_register(const void *buf, uint16_t len)
> {
> @@ -110,10 +117,26 @@ failed:
>
> static void handle_client_unregister(const void *buf, uint16_t len)
> {
> + const struct hal_cmd_gatt_client_unregister *cmd = buf;
> + int32_t client_if = cmd->client_if;
Why is this copy needed?
> + GList *found_client_if;
> +
> DBG("");
>
> - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> + found_client_if = g_list_find_custom(gatt_client_list, &client_if,
> + find_client_if);
> + if (!found_client_if) {
> + error("client_if: %d not found", client_if);
> + ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> HAL_OP_GATT_CLIENT_UNREGISTER, HAL_STATUS_FAILED);
Lets follow this convention for error handling:
status = HAL_STATUS_FAILED;
goto failed;
> + return;
> + }
> +
> + gatt_client_list = g_list_remove(gatt_client_list,
> + found_client_if->data);
> +
> + ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> + HAL_OP_GATT_CLIENT_UNREGISTER, HAL_STATUS_SUCCESS);
> }
>
> static void handle_client_scan(const void *buf, uint16_t len)
--
BR
Szymon Janc
^ permalink raw reply
* Re: [PATCH 1/2] android/gatt: Handle Register gatt client command
From: Szymon Janc @ 2014-03-08 20:03 UTC (permalink / raw)
To: Grzegorz Kolodziejczyk; +Cc: linux-bluetooth
In-Reply-To: <1394197499-2207-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
Hi Grzegorz,
On Friday 07 of March 2014 14:04:58 Grzegorz Kolodziejczyk wrote:
> This adds register gatt client app command handling.
> ---
> android/gatt.c | 63
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed,
> 62 insertions(+), 1 deletion(-)
>
> diff --git a/android/gatt.c b/android/gatt.c
> index ce85af4..f8f7208 100644
> --- a/android/gatt.c
> +++ b/android/gatt.c
> @@ -31,6 +31,7 @@
> #include <glib.h>
>
> #include "ipc.h"
> +#include "ipc-common.h"
> #include "lib/bluetooth.h"
> #include "gatt.h"
> #include "src/log.h"
> @@ -38,13 +39,73 @@
>
> static struct ipc *hal_ipc = NULL;
> static bdaddr_t adapter_addr;
> +static int32_t client_if_counter;
Just use local static variable in function that use this counter.
> +
> +struct gatt_client {
> + int32_t client_if;
> + uint8_t uuid[16];
> +};
> +
> +GList *gatt_client_list = NULL;
This should be static. Also don't mix statics and type definitions.
And name it gatt_clients or just clients.
> +
> +static int find_client_uuid(gconstpointer data, gconstpointer user_data)
> +{
> + const uint8_t *exp_uuid = user_data;
> + const uint8_t *cur_uuid = ((struct gatt_client *)data)->uuid;
> + struct gatt_client *client;
> +
> + if (memcmp(exp_uuid, cur_uuid, sizeof(client->uuid)))
> + return 1;
> +
> + return 0;
> +}
Just return memcmp(); should be enough.
> +
This extra empty line is not needed.
>
> static void handle_client_register(const void *buf, uint16_t len)
> {
> + const struct hal_cmd_gatt_client_register *cmd = buf;
> + struct hal_ev_gatt_client_register_client ev;
> + struct gatt_client *client;
> + GList *found_client_uuid;
> +
> DBG("");
>
> + if (!cmd->uuid) {
> + error("no uuid received");
Lets prefix all info and error messages with "gatt: "
> + goto failed;
> + }
> +
> + found_client_uuid = g_list_find_custom(gatt_client_list,
> + &cmd->uuid, find_client_uuid);
> +
> + if (found_client_uuid) {
if (g_list_find_custom(..)) {
}
> + error("client uuid is already on list");
> + goto failed;
> + }
> +
> + client = g_new0(struct gatt_client, 1);
> + g_memmove(client->uuid, cmd->uuid, sizeof(client->uuid));
Why g_memmove? Just use memcpy() here.
> +
> + client->client_if = ++client_if_counter;
> +
> + gatt_client_list = g_list_append(gatt_client_list, client);
> +
> ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_REGISTER,
> - HAL_STATUS_FAILED);
> + HAL_STATUS_SUCCESS);
I would add status variable and pass it to ipc_send_rsp() at the end of
function.
> +
> + ev.status = HAL_STATUS_SUCCESS;
> + ev.client_if = client->client_if;
> + g_memmove(ev.app_uuid, client->uuid, sizeof(client->uuid));
memcpy();
> +
> + ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT,
> + HAL_EV_GATT_CLIENT_REGISTER_CLIENT, sizeof(ev), &ev);
> +
> + return;
> +
> +failed:
> + ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
> + HAL_OP_GATT_CLIENT_REGISTER, HAL_STATUS_FAILED);
> +
> }
>
> static void handle_client_unregister(const void *buf, uint16_t len)
--
BR
Szymon Janc
^ permalink raw reply
* Re: [PATCH 5/5] android/handsfree: Remove empty line
From: Szymon Janc @ 2014-03-08 19:01 UTC (permalink / raw)
To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1394223800-11961-5-git-send-email-marcin.kraglak@tieto.com>
Hi Marcin,
On Friday 07 of March 2014 21:23:20 Marcin Kraglak wrote:
> ---
> android/handsfree.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/android/handsfree.c b/android/handsfree.c
> index 69de670..1b42142 100644
> --- a/android/handsfree.c
> +++ b/android/handsfree.c
> @@ -475,7 +475,6 @@ static void connect_cb(GIOChannel *chan, GError *err,
> gpointer user_data) hfp_gw_set_command_handler(device.gw,
> at_command_handler, NULL, NULL); hfp_gw_set_disconnect_handler(device.gw,
> disconnect_watch, NULL, NULL);
>
> -
> if (device.hsp) {
> register_post_slc_at();
> device_set_state(HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
This patch is now applied, thanks.
--
BR
Szymon Janc
^ permalink raw reply
* Re: [PATCH 1/5] android/handsfree: Fix possible g_io_channel_shutdown() on NULL channel
From: Szymon Janc @ 2014-03-08 19:00 UTC (permalink / raw)
To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1394223800-11961-1-git-send-email-marcin.kraglak@tieto.com>
Hi Marcin,
On Friday 07 of March 2014 21:23:16 Marcin Kraglak wrote:
> Return false if listen failed.
> ---
> android/handsfree.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/android/handsfree.c b/android/handsfree.c
> index dc5c73d..fa27f10 100644
> --- a/android/handsfree.c
> +++ b/android/handsfree.c
> @@ -1192,7 +1192,7 @@ static bool enable_hfp_ag(void)
> if (!hfp_server) {
> error("Failed to listen on Handsfree rfcomm: %s", err->message);
> g_error_free(err);
> - goto failed;
> + return false;
> }
>
> rec = hfp_ag_record();
This patch is now pushed, thanks.
--
BR
Szymon Janc
^ permalink raw reply
* Re: [PATCH 1/2] android/pics: Correct PICS for AbsoluteVolume
From: Szymon Janc @ 2014-03-08 19:00 UTC (permalink / raw)
To: Sebastian Chlad; +Cc: linux-bluetooth
In-Reply-To: <1394217767-12242-1-git-send-email-sebastian.chlad@tieto.com>
Hi Sebastian,
On Friday 07 of March 2014 19:42:46 Sebastian Chlad wrote:
> As Specification for AVRCP 1.4+ requires, in case of Absolute
> Volume, roles are reveresed and IUT plays CT while PTS plays TG
> role (PTS acts as sink. See section 6.13.2 AVRCP 1.5 Spec)
> ---
> android/pics-avrcp.txt | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/android/pics-avrcp.txt b/android/pics-avrcp.txt
> index 845ba33..bee22c8 100644
> --- a/android/pics-avrcp.txt
> +++ b/android/pics-avrcp.txt
> @@ -12,7 +12,7 @@ O - optional
> ---------------------------------------------------------------------------
> ---- Parameter Name Selected Description
> ---------------------------------------------------------------------------
> ---- -SPC_AVRCP_1_1 False (*) Role: Controller (CT) (C.1)
> +SPC_AVRCP_1_1 True Role: Controller (CT) (C.1)
> TSPC_AVRCP_1_2 True Role: Target (TG) (C.1)
> ---------------------------------------------------------------------------
> ---- C.1: Mandatory to support at least one of the defined roles.
> @@ -82,9 +82,9 @@ TSPC_AVRCP_2_45 False CT: PlayItem(NowPlayingList)
> (C.8) TSPC_AVRCP_2_46 False CT: AddToNowPlaying (O)
> TSPC_AVRCP_2_47 False CT: EVENT_NOW_PLAYING_CONTENT_CHANGED (O)
> TSPC_AVRCP_2_48 False CT: Playable Folders (O)
> -TSPC_AVRCP_2_49 False CT: Absolute Volume (C.3)
> -TSPC_AVRCP_2_50 False CT: SetAbsoluteVolume (C.3)
> -TSPC_AVRCP_2_51 False CT: NotifyVolumeChange (C.3)
> +TSPC_AVRCP_2_49 True (*) CT: Absolute Volume (C.3)
> +TSPC_AVRCP_2_50 True (*) CT: SetAbsoluteVolume (C.3)
> +TSPC_AVRCP_2_51 True (*) CT: NotifyVolumeChange (C.3)
> TSPC_AVRCP_2_52 False (*) CT: Discoverable Mode (M)
> TSPC_AVRCP_2_53 False CT: PASSTHROUGH operation supporting press
> and hold (O)
> @@ -405,9 +405,9 @@ TSPC_AVRCP_7_56 False TG:
PlayItem(NowPlayingList)
> (C.11) TSPC_AVRCP_7_57 False TG: AddToNowPlaying (O)
> TSPC_AVRCP_7_58 False TG: EVENT_NOW_PLAYING_CONTENT_CHANGED (C.11)
> TSPC_AVRCP_7_59 False TG: Playable Folders (O)
> -TSPC_AVRCP_7_60 True (*) TG: Absolute Volume (C.5)
> -TSPC_AVRCP_7_61 True (*) TG: SetAbsoluteVolume (C.5)
> -TSPC_AVRCP_7_62 True (*) TG: NotifyVolumeChange (C.5)
> +TSPC_AVRCP_7_60 False TG: Absolute Volume (C.5)
> +TSPC_AVRCP_7_61 False TG: SetAbsoluteVolume (C.5)
> +TSPC_AVRCP_7_62 False TG: NotifyVolumeChange (C.5)
> TSPC_AVRCP_7_63 False TG: Error Response (O)
> TSPC_AVRCP_7_64 False TG: General Reject (C.13)
> TSPC_AVRCP_7_65 True TG: Discoverable Mode (M)
Both patches applied, thanks.
--
BR
Szymon Janc
^ permalink raw reply
* [PATCH 2/2] android/handsfree: Use string type in IPC messages
From: Szymon Janc @ 2014-03-08 16:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1394296531-22469-1-git-send-email-szymon.janc@tieto.com>
This type is used to carry NULL terminated string. If last byte is not
NULL this is an IPC error. It doesn't change memory structure of
messages but emphasize that buffer should be NULL terminated.
---
android/hal-handsfree.c | 38 ++++++++++++++++++++------------------
android/hal-msg.h | 23 +++++++++++------------
android/handsfree.c | 9 +++------
3 files changed, 34 insertions(+), 36 deletions(-)
diff --git a/android/hal-handsfree.c b/android/hal-handsfree.c
index 4117ed0..7471ec8 100644
--- a/android/hal-handsfree.c
+++ b/android/hal-handsfree.c
@@ -84,13 +84,14 @@ static void handle_dial(void *buf, uint16_t len)
{
struct hal_ev_handsfree_dial *ev = buf;
- if (len != sizeof(*ev) + ev->number_len) {
+ if (len != sizeof(*ev) + ev->number.len ||
+ ev->number.data[ev->number.len - 1] != '\0') {
error("invalid dial event, aborting");
exit(EXIT_FAILURE);
}
if (cbs->dial_call_cmd_cb)
- cbs->dial_call_cmd_cb((char *) ev->number);
+ cbs->dial_call_cmd_cb((char *) ev->number.data);
}
static void handle_dtmf(void *buf, uint16_t len)
@@ -145,13 +146,14 @@ static void handle_unknown_at(void *buf, uint16_t len)
{
struct hal_ev_handsfree_unknown_at *ev = buf;
- if (len != sizeof(*ev) + ev->len) {
+ if (len != sizeof(*ev) + ev->at.len ||
+ ev->at.data[ev->at.len - 1] != '\0') {
error("invalid unknown command event, aborting");
exit(EXIT_FAILURE);
}
if (cbs->unknown_at_cmd_cb)
- cbs->unknown_at_cmd_cb((char *) ev->buf);
+ cbs->unknown_at_cmd_cb((char *) ev->at.data);
}
static void handle_hsp_key_press(void *buf, uint16_t len)
@@ -387,10 +389,10 @@ static bt_status_t cops_response(const char *cops)
if (!cops)
return BT_STATUS_PARM_INVALID;
- cmd->len = strlen(cops);
- memcpy(cmd->buf, cops, cmd->len);
+ cmd->cops.len = strlen(cops) + 1;
+ memcpy(cmd->cops.data, cops, cmd->cops.len);
- len = sizeof(*cmd) + cmd->len;
+ len = sizeof(*cmd) + cmd->cops.len;
return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
HAL_OP_HANDSFREE_COPS_RESPONSE,
@@ -435,10 +437,10 @@ static bt_status_t formatted_at_response(const char *rsp)
if (!rsp)
return BT_STATUS_PARM_INVALID;
- cmd->len = strlen(rsp);
- memcpy(cmd->buf, rsp, cmd->len);
+ cmd->resp.len = strlen(rsp) + 1;
+ memcpy(cmd->resp.data, rsp, cmd->resp.len);
- len = sizeof(*cmd) + cmd->len;
+ len = sizeof(*cmd) + cmd->resp.len;
return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE,
@@ -486,13 +488,13 @@ static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
cmd->type = type;
if (number) {
- cmd->number_len = strlen(number);
- memcpy(cmd->number, number, cmd->number_len);
+ cmd->number.len = strlen(number) + 1;
+ memcpy(cmd->number.data, number, cmd->number.len);
} else {
- cmd->number_len = 0;
+ cmd->number.len = 0;
}
- len = sizeof(*cmd) + cmd->number_len;
+ len = sizeof(*cmd) + cmd->number.len;
return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
HAL_OP_HANDSFREE_CLCC_RESPONSE,
@@ -519,13 +521,13 @@ static bt_status_t phone_state_change(int num_active, int num_held,
cmd->type = type;
if (number) {
- cmd->number_len = strlen(number);
- memcpy(cmd->number, number, cmd->number_len);
+ cmd->number.len = strlen(number) + 1;
+ memcpy(cmd->number.data, number, cmd->number.len);
} else {
- cmd->number_len = 0;
+ cmd->number.len = 0;
}
- len = sizeof(*cmd) + cmd->number_len;
+ len = sizeof(*cmd) + cmd->number.len;
return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
HAL_OP_HANDSFREE_PHONE_STATE_CHANGE,
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 1b2b31a..ec8c342 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -23,6 +23,11 @@
static const char BLUEZ_HAL_SK_PATH[] = "\0bluez_hal_socket";
+struct hal_string {
+ uint16_t len;
+ uint8_t data[0];
+} __attribute__((packed));
+
#define HAL_MINIMUM_EVENT 0x81
#define HAL_SERVICE_ID_CORE 0
@@ -436,8 +441,7 @@ struct hal_cmd_handsfree_device_status_notif {
#define HAL_OP_HANDSFREE_COPS_RESPONSE 0x09
struct hal_cmd_handsfree_cops_response {
- uint16_t len;
- uint8_t buf[0];
+ struct hal_string cops;
} __attribute__((packed));
#define HAL_HANDSFREE_CALL_STATE_ACTIVE 0x00
@@ -461,8 +465,7 @@ struct hal_cmd_handsfree_cind_response {
#define HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE 0x0B
struct hal_cmd_handsfree_formatted_at_response {
- uint16_t len;
- uint8_t buf[0];
+ struct hal_string resp;
} __attribute__((packed));
#define HAL_HANDSFREE_AT_RESPONSE_ERROR 0x00
@@ -495,8 +498,7 @@ struct hal_cmd_handsfree_clcc_response {
uint8_t mode;
uint8_t mpty;
uint8_t type;
- uint16_t number_len;
- uint8_t number[0];
+ struct hal_string number;
} __attribute__((packed));
#define HAL_OP_HANDSFREE_PHONE_STATE_CHANGE 0x0E
@@ -505,8 +507,7 @@ struct hal_cmd_handsfree_phone_state_change {
uint8_t num_held;
uint8_t state;
uint8_t type;
- uint16_t number_len;
- uint8_t number[0];
+ struct hal_string number;
} __attribute__((packed));
/* GATT HAL API */
@@ -1016,8 +1017,7 @@ struct hal_ev_handsfree_volume {
#define HAL_EV_HANDSFREE_DIAL 0x87
struct hal_ev_handsfree_dial {
- uint16_t number_len;
- uint8_t number[0];
+ struct hal_string number;
} __attribute__((packed));
#define HAL_EV_HANDSFREE_DTMF 0x88
@@ -1054,8 +1054,7 @@ struct hal_ev_handsfree_chld {
#define HAL_EV_HANDSFREE_UNKNOWN_AT 0x8F
struct hal_ev_handsfree_unknown_at {
- uint16_t len;
- uint8_t buf[0];
+ struct hal_string at;
} __attribute__((packed));
#define HAL_EV_HANDSFREE_HSP_KEY_PRESS 0x90
diff --git a/android/handsfree.c b/android/handsfree.c
index dc5c73d..275a0cf 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -838,9 +838,9 @@ static void handle_device_status_notif(const void *buf, uint16_t len)
static void handle_cops(const void *buf, uint16_t len)
{
const struct hal_cmd_handsfree_cops_response *cmd = buf;
- char operator[17];
- if (len != sizeof(*cmd) + cmd->len) {
+ if (len != sizeof(*cmd) + cmd->cops.len ||
+ cmd->cops.data[cmd->cops.len - 1] != '\0') {
error("Invalid cops response command, terminating");
raise(SIGTERM);
return;
@@ -848,10 +848,7 @@ static void handle_cops(const void *buf, uint16_t len)
DBG("");
- memset(operator, 0, sizeof(operator));
- memcpy(operator, cmd->buf, MIN(cmd->len, 16));
-
- hfp_gw_send_info(device.gw, "+COPS: 0,0,\"%s\" ", operator);
+ hfp_gw_send_info(device.gw, "+COPS: 0,0,\"%.16s\" ", cmd->cops.data);
hfp_gw_send_result(device.gw, HFP_RESULT_OK);
--
1.8.5.3
^ permalink raw reply related
* [PATCH 1/2] android/hal-ipc-api: Fix not describing call numbers as strings
From: Szymon Janc @ 2014-03-08 16:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
---
android/hal-ipc-api.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index 1ecf75f..e4a4e9c 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -898,7 +898,7 @@ Commands and responses:
Call mode (1 octet)
Call multiparty type (1 octet)
Call number type (1 octet)
- Call number (variable)
+ Call number (string)
Response parameters: <none>
Valid call directions: 0x00 = Outgoing
@@ -930,7 +930,7 @@ Commands and responses:
Number of held calls (1 octet)
Call setup state (1 octet)
Call number type (1 octet)
- Call number (variable)
+ Call number (string)
Response parameters: <none>
Valid call setup states: 0x00 = Active
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCH 03/20] android/handsfree: Add support for unknown AT commands
From: Szymon Janc @ 2014-03-08 12:29 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <E54E58F0-0743-4000-883C-981E0B692728@holtmann.org>
Hi Marcel,
On Friday 07 of March 2014 19:37:00 Marcel Holtmann wrote:
> Hi Szymon,
>=20
> > Those commands are passed to Framework without parsing.
> > ---
> > android/handsfree.c | 64
> > ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file change=
d, 54
> > insertions(+), 10 deletions(-)
> >=20
> > diff --git a/android/handsfree.c b/android/handsfree.c
> > index c49a35b..e104c4a 100644
> > --- a/android/handsfree.c
> > +++ b/android/handsfree.c
> > @@ -161,19 +161,35 @@ static void device_cleanup(void)
> >=20
> > =09memset(&device, 0, sizeof(device));
> >=20
> > }
> >=20
> > -static void at_command_handler(const char *command, void *user_dat=
a)
> > +static void disconnect_watch(void *user_data)
> > {
> > -=09hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
> > +=09DBG("");
> >=20
> > -=09if (device.state !=3D HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED=
)
> > -=09=09hfp_gw_disconnect(device.gw);
> > +=09device_cleanup();
> > }
> >=20
> > -static void disconnect_watch(void *user_data)
> > +static void at_cmd_unknown(const char *command, void *user_data)
> > {
> > -=09DBG("");
> > +=09uint8_t buf[IPC_MTU];
> > +=09struct hal_ev_handsfree_unknown_at *ev =3D (void *) buf;
> >=20
> > -=09device_cleanup();
> > +=09if (device.state !=3D HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED=
) {
> > +=09=09hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
> > +=09=09hfp_gw_disconnect(device.gw);
> > +=09=09return;
> > +=09}
> > +
> > +=09/* copy while string including terminating NULL */
> > +=09ev->len =3D strlen(command) + 1;
> > +=09memcpy(ev->buf, command, ev->len);
> > +
> > +=09if (ev->len > IPC_MTU - sizeof(*ev)) {
> > +=09=09hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
> > +=09=09return;
> > +=09}
> > +
> > +=09ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> > +=09=09=09HAL_EV_HANDSFREE_UNKNOWN_AT, sizeof(*ev) + ev->len, ev);
> > }
> >=20
> > static void at_cmd_vgs_vgm(struct hfp_gw_result *result,
> > @@ -674,7 +690,7 @@ static void connect_cb(GIOChannel *chan, GError=
*err,
> > gpointer user_data)>=20
> > =09g_io_channel_set_close_on_unref(chan, FALSE);
> > =09
> > =09hfp_gw_set_close_on_unref(device.gw, true);
> >=20
> > -=09hfp_gw_set_command_handler(device.gw, at_command_handler, NULL,=
NULL);
> > +=09hfp_gw_set_command_handler(device.gw, at_cmd_unknown, NULL, NUL=
L);
> >=20
> > =09hfp_gw_set_disconnect_handler(device.gw, disconnect_watch, NULL,=
=20
NULL);
> >=20
> > @@ -1147,19 +1163,47 @@ static void handle_cind(const void *buf, ui=
nt16_t
> > len)
> >=20
> > static void handle_formatted_at_resp(const void *buf, uint16_t len)=
> > {
> > +=09const struct hal_cmd_handsfree_formatted_at_response *cmd =3D b=
uf;
> > +=09char *at;
> > +
> >=20
> > =09DBG("");
> >=20
> > +=09if (len !=3D sizeof(*cmd) + cmd->len) {
> > +=09=09error("Invalid formatted AT response command, terminating");=
> > +=09=09raise(SIGTERM);
> > +=09=09return;
> > +=09}
> > +
> > +=09DBG("");
> > +
> > +=09at =3D g_malloc0(cmd->len + 1);
> > +
> > +=09memcpy(at, cmd->buf, cmd->len);
> > +
> > +=09hfp_gw_send_info(device.gw, "%s", at);
> > +
> > +=09g_free(at);
> > +
>=20
> is Android really passing AT commands around without \0 terminating t=
hem.
> That OS is really just plain silly.
This is due to how we currently send strings overs IPC. There is string=
type=20
in our IPC doc, but not in hal-msg.h. I'll fix that.
>=20
> Anyway, using strndupa seems more appropriate here.
>=20
> I also wonder why not just using (.., =E2=80=9C%.*s=E2=80=9D, cmd->le=
n, cmd->buf) here.
I'll use that.
> Regards
>=20
> Marcel
--=20
BR
Szymon Janc
^ permalink raw reply
* Re: Passive scanning of iBeacons results in a "Data Buffer Overflow"
From: Terry Hardie @ 2014-03-08 7:19 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <6E6C1573-4744-486B-B2E6-2D3DC45D024B@warski.org>
Hi guys,
I'm having something similar to what Adam is reporting. I'm running on a
BeagleBone Black, which uses a TI MUSB controller (I think it's different
to the Raspberry Pi USB controller?).
I have 2 vendor's USB bluetooth receivers.
One is a Cambridge Silicon Radio (0a12:0001) and the other is a Broadcom
BCM20702A1 (0a5c:21e8). The Broadcom needs a RAM patch to behave slightly
better, but it outside the scope of this problem. BOTH exhibit the same
problem (so I seriously doubt it's a problem with the Bluetooth receivers)
Both devices are operating in HCI mode. I'm running Ubuntu on my
BeagleBone Black.
I've also built the latest version of Bluez (5.15)
The problem is when running a lescan (hcitool lescan) with a LE device in
paring mode, which is transmitting a lot of LE Advertising report packets,
the HCI drivers eventually loses sync. I've traced it down to a duplicate
USB fragment.
I've tested these USB receivers under Ubuntu on an Intel machine with the
same Bluez 5.15, and the problem is not present.
hcidump shows when things go crazy:
2014-03-08 06:32:12.111970 > HCI Event: LE Meta Event (0x3e) plen 33
LE Advertising Report
ADV_IND - Connectable undirected advertising (0)
bdaddr E1:F9:7C:05:30:3C (Random)
Flags: 0x05
Complete local name: 'Scosche PROX'
Unknown type 0x19 with 2 bytes data
RSSI: -62
2014-03-08 06:32:12.163087 > HCI Event: Unknown (0x00) plen 2
C7 3E
2014-03-08 06:32:12.163136 > HCI Event: Flow Specification Complete (0x21)
plen 2
status 0x01 handle 0x0000 flags 1 incoming
Error: Unknown HCI Command
2014-03-08 06:32:12.192009 > HCI Event: Inquiry Complete (0x01) plen 60
status 0x30
Error: Parameter out of Mandatory Range
05 7C F9 E1 15 02 01 05 0D 09 53 63 6F 73 63 68 65 20 50 52
4F 58 03 19 00 02 C5 3E 21 02 01 00 01 3C 30 05 7C F9 E1 15
02 01 05 0D 09 53 63 6F 73 63 68 65 20 50 52 4F 58 03 19
2014-03-08 06:32:12.218055 > HCI Event: Unknown (0x00) plen 2
C5 3E
I added some code to btusb_intr_complete to print each urb as it comes up
from the USB stack. Here's the output for the above problem. Note the
extra "00 02 c7" -- Should not be there...
Mar 8 06:32:12 arm kernel: [ 122.915094] hci1 urb df4a8540 status 0 count 16 flags 768
Mar 8 06:32:12 arm kernel: [ 122.915176] hci1 urb contents: 3e 21 02 01 00 01 3c 30 05 7c f9 e1 15 02 01 05
Mar 8 06:32:12 arm kernel: [ 122.916004] hci1 urb df4a8540 status 0 count 16 flags 768
Mar 8 06:32:12 arm kernel: [ 122.916085] hci1 urb contents: 0d 09 53 63 6f 73 63 68 65 20 50 52 4f 58 03 19
Mar 8 06:32:12 arm kernel: [ 122.916985] hci1 urb df4a8540 status 0 count 3 flags 768
Mar 8 06:32:12 arm kernel: [ 122.917018] hci1 urb contents: 00 02 c2
Mar 8 06:32:12 arm kernel: [ 122.942995] hci1 urb df4a8540 status 0 count 3 flags 768
Mar 8 06:32:12 arm kernel: [ 122.943028] hci1 urb contents: 00 02 c7
I used usbmon to do a "sniff" of the USB traffic. Here's a snippet of a
correct HCI LE Advertising report event, followed by one where the middle
fragment is repeated (frame 1300 is a repeat) This is a different capture
from the above example. I can provide the pcap somewhere if needed
No. Time Source Destination Protocol Length Info
1291 2014-03-07 02:40:16.942573 host 3.1 USB 64 URB_INTERRUPT in
1292 2014-03-07 02:40:16.959480 3.1 host HCI_USB 80 Rcvd Fragment
3e21020100013c30057cf9e115020105
1293 2014-03-07 02:40:16.959624 host 3.1 USB 64 URB_INTERRUPT in
1294 2014-03-07 02:40:16.960449 3.1 host HCI_USB 80 Rcvd Fragment
0d0953636f736368652050524f580319
1295 2014-03-07 02:40:16.960546 host 3.1 USB 64 URB_INTERRUPT in
1296 2014-03-07 02:40:16.961455 3.1 host HCI_EVT 67 Rcvd LE Meta (LE Advertising Report)
0002ae
1297 2014-03-07 02:40:16.961560 host 3.1 USB 64 URB_INTERRUPT in
1298 2014-03-07 02:40:16.981627 3.1 host HCI_USB 80 Rcvd Fragment
3e21020100013c30057cf9e115020105
1299 2014-03-07 02:40:16.981696 host 3.1 USB 64 URB_INTERRUPT in
1300 2014-03-07 02:40:17.002651 3.1 host HCI_USB 80 Rcvd Fragment
3e21020100013c30057cf9e115020105
1301 2014-03-07 02:40:17.002720 host 3.1 USB 64 URB_INTERRUPT in
1302 2014-03-07 02:40:17.003560 3.1 host HCI_USB 80 Rcvd Fragment
0d0953636f736368652050524f580319
1303 2014-03-07 02:40:17.003649 host 3.1 USB 64 URB_INTERRUPT in
1304 2014-03-07 02:40:17.004567 3.1 host HCI_USB 67 Rcvd Fragment
0002b5
^ 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