* [PATCH v2 13/13] Bluetooth: Provide remote OOB data for Secure Connections
From: Marcel Holtmann @ 2014-01-10 6:40 UTC (permalink / raw)
To: linux-bluetooth
When Secure Connections has been enabled it is possible to provide P-192
and/or P-256 data during the pairing process. The internal out-of-band
credentials storage has been extended to also hold P-256 data.
Initially the P-256 data will be empty and with Secure Connections enabled
no P-256 data will be provided. This is according to the specification
since it might be possible that the remote side did not provide either
of the out-of-band credentials.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 6 ++++--
net/bluetooth/hci_core.c | 6 +++---
net/bluetooth/hci_event.c | 32 ++++++++++++++++++++++++--------
3 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index bd15eaa4c06e..5948930f92e6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -114,8 +114,10 @@ struct link_key {
struct oob_data {
struct list_head list;
bdaddr_t bdaddr;
- u8 hash[16];
- u8 randomizer[16];
+ u8 hash192[16];
+ u8 randomizer192[16];
+ u8 hash256[16];
+ u8 randomizer256[16];
};
#define HCI_MAX_SHORT_NAME_LENGTH 10
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 946631ffe802..f13c0550f368 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2802,7 +2802,7 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
data = hci_find_remote_oob_data(hdev, bdaddr);
if (!data) {
- data = kmalloc(sizeof(*data), GFP_ATOMIC);
+ data = kzalloc(sizeof(*data), GFP_ATOMIC);
if (!data)
return -ENOMEM;
@@ -2810,8 +2810,8 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
list_add(&data->list, &hdev->remote_oob_data);
}
- memcpy(data->hash, hash, sizeof(data->hash));
- memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
+ memcpy(data->hash192, hash, sizeof(data->hash192));
+ memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
BT_DBG("%s for %pMR", hdev->name, bdaddr);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6923241d2b3e..47b953e24864 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3391,20 +3391,36 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
if (data) {
- struct hci_cp_remote_oob_data_reply cp;
+ if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
+ struct hci_cp_remote_oob_ext_data_reply cp;
- bacpy(&cp.bdaddr, &ev->bdaddr);
- memcpy(cp.hash, data->hash, sizeof(cp.hash));
- memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
+ bacpy(&cp.bdaddr, &ev->bdaddr);
+ memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
+ memcpy(cp.randomizer192, data->randomizer192,
+ sizeof(cp.randomizer192));
+ memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
+ memcpy(cp.randomizer256, data->randomizer256,
+ sizeof(cp.randomizer256));
+
+ hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
+ sizeof(cp), &cp);
+ } else {
+ struct hci_cp_remote_oob_data_reply cp;
- hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
- &cp);
+ bacpy(&cp.bdaddr, &ev->bdaddr);
+ memcpy(cp.hash, data->hash192, sizeof(cp.hash));
+ memcpy(cp.randomizer, data->randomizer192,
+ sizeof(cp.randomizer));
+
+ hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
+ sizeof(cp), &cp);
+ }
} else {
struct hci_cp_remote_oob_data_neg_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
- hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
- &cp);
+ hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
+ sizeof(cp), &cp);
}
unlock:
--
1.8.4.2
^ permalink raw reply related
* Re: Last depmod fails with 3.13-rc6
From: Paul Bolle @ 2014-01-10 8:11 UTC (permalink / raw)
To: Marcel Holtmann, Gustavo Padovan, Johan Hedberg
Cc: Sébastien Luttringer, linux-bluetooth, linux-kernel
In-Reply-To: <la50g5$n4j$1@ger.gmane.org>
Adding maintainers and linux-bluetooth.
On Fri, 2014-01-03 at 01:33 +0100, Sébastien Luttringer wrote:
> On 03/01/2014 01:11, Sébastien Luttringer wrote:
> > Hello,
> >
> > Trying to run depmod (from kmod 16) on the 3.13-rc6, I got this error
> > message:
> >
> > # depmod 3.13.0-rc6-seblu
> > depmod: ERROR: Module 'hci_vhci' has devname (vhci) but lacks major and
> > minor information. Ignoring.
> >
> > The message and error code seem to be on purpose[2] but they break tools
> > which rely on depmod return 0 (like kernel-install).
> >
> >
> > [1] http://git.kernel.org/cgit/utils/kernel/kmod/kmod.git/commit/?id=6506ddf
> >
> Forget about the return code and their consequences. I made a mistake.
>
> The missing informations in hci_vhci is still relevant.
>
> # depmod 3.13.0-rc6-seblu
> depmod: ERROR: Module 'hci_vhci' has devname (vhci) but lacks major and
> minor information. Ignoring.
>
> Regards,
>
Paul Bolle
^ permalink raw reply
* Re: [PATCH_v4 0/4] Add support for NAP role
From: Ravi kumar Veeramally @ 2014-01-10 8:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389181593-9683-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Ping.
On 01/08/2014 01:46 PM, Ravi kumar Veeramally wrote:
> v4: Fixed Szymon's and Luiz's comments.
>
> v3: Fixed Johan's comments (removed fopen, fprintf and used open and write).
>
> v2: Fixed Johan's comments.
>
> v1: This patch set add support for NAP role. It register NAP server and create
> bnep bridge and listen for incoming connections from client devices.
> On incoming connection request it accepts connection, creates bnep interface
> and notifies control state and connection state infromation. Removes device
> on disconnect request. Android related changes are required to enable this
> role. Patches sent to respective ML.
>
> Ravi kumar Veeramally (4):
> android/pan: Register Network Access Point
> android/pan: Listen for incoming connections and accept in NAP role
> android/pan: Implement PAN enable HAL api at daemon side
> android/pan: Remove connected PAN devices on profile unregister call
>
> android/pan.c | 346 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 334 insertions(+), 12 deletions(-)
>
^ permalink raw reply
* [PATCHv3 00/19] Initial RFCOMM support in bthost
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
This adds initial support from rfcomm connection in bthost.
With these patches bthost can accept incoming RFCOMM connections
and create outgoing RFCOMM connections. Also rfcomm-tester is
introduced with few basic test cases. monitor/rfcomm.h is created
for proper handling rfcomm signaling.
Comments are welcome
Marcin Kraglak (19):
tools/rfcomm-tester: Initial version of rfcomm-tester
tools/rfcomm-tester: Add basic rfcomm test case
monitor: Add rfcomm.h to tree
emulator/bthost: Add initial rfcomm handling
emulator/bthost: Add method to create rfcomm server
emulator/bthost: Add recv_sabm imnplementation
monitor: Add mcc structs and types to rfcomm.h
emulator/bthost: Add rfcomm_mcc_recv stub
emulator/bthost: Add recv_pn implementation
emulator/bthost: Service msc frames
emulator/bthost: Implement recv_disc rfcomm frame in bthost
tools/rfcomm-tester: Implement client test case
tools/rfcomm-tester: Add Connection refused client test case
emulator/bthost: Implement bthost_connect_rfcomm
emulator/bthost: Ad implementation of rfcomm_ua_recv
emulator/bthost: Add implementation to PN RSP
emulator/bthost: Call rfcomm_connect_cb when connected
tools/rfcomm-tester: Add RFCOMM server test case
tools/rfcomm-tester: Add RFCOMM server negative test case
.gitignore | 1 +
Makefile.tools | 13 +-
emulator/bthost.c | 436 +++++++++++++++++++++++++++++++++++++-
emulator/bthost.h | 11 +
monitor/rfcomm.h | 79 +++++++
tools/rfcomm-tester.c | 564 ++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 1102 insertions(+), 2 deletions(-)
create mode 100644 monitor/rfcomm.h
create mode 100644 tools/rfcomm-tester.c
--
1.8.3.1
^ permalink raw reply
* [PATCHv3 01/19] tools/rfcomm-tester: Initial version of rfcomm-tester
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
Add rfcomm-tester to tree.
---
.gitignore | 1 +
Makefile.tools | 6 +++++-
tools/rfcomm-tester.c | 36 ++++++++++++++++++++++++++++++++++++
3 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 tools/rfcomm-tester.c
diff --git a/.gitignore b/.gitignore
index 3e0641d..4ac216d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,6 +81,7 @@ unit/test-mgmt
tools/mgmt-tester
tools/smp-tester
tools/gap-tester
+tools/rfcomm-tester
tools/btattach
tools/btmgmt
tools/btsnoop
diff --git a/Makefile.tools b/Makefile.tools
index ec1499a..07fbd80 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -39,7 +39,7 @@ if EXPERIMENTAL
noinst_PROGRAMS += emulator/btvirt emulator/b1ee tools/3dsp \
tools/mgmt-tester tools/gap-tester \
tools/l2cap-tester tools/sco-tester \
- tools/smp-tester
+ tools/smp-tester tools/rfcomm-tester
emulator_btvirt_SOURCES = emulator/main.c monitor/bt.h \
monitor/mainloop.h monitor/mainloop.c \
@@ -80,6 +80,10 @@ tools_l2cap_tester_SOURCES = tools/l2cap-tester.c monitor/bt.h \
src/shared/tester.h src/shared/tester.c
tools_l2cap_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+tools_rfcomm_tester_SOURCES = tools/rfcomm-tester.c src/shared/tester.h \
+ src/shared/tester.c
+tools_rfcomm_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+
tools_smp_tester_SOURCES = tools/smp-tester.c monitor/bt.h \
emulator/btdev.h emulator/btdev.c \
emulator/bthost.h emulator/bthost.c \
diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
new file mode 100644
index 0000000..200d953
--- /dev/null
+++ b/tools/rfcomm-tester.c
@@ -0,0 +1,36 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Intel Corporation. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include "src/shared/tester.h"
+
+int main(int argc, char *argv[])
+{
+ tester_init(&argc, &argv);
+
+ return tester_run();
+}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 02/19] tools/rfcomm-tester: Add basic rfcomm test case
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
This test case verifies creating rfcomm socket.
---
Makefile.tools | 11 ++-
tools/rfcomm-tester.c | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 258 insertions(+), 2 deletions(-)
diff --git a/Makefile.tools b/Makefile.tools
index 07fbd80..93ff354 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -80,8 +80,15 @@ tools_l2cap_tester_SOURCES = tools/l2cap-tester.c monitor/bt.h \
src/shared/tester.h src/shared/tester.c
tools_l2cap_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
-tools_rfcomm_tester_SOURCES = tools/rfcomm-tester.c src/shared/tester.h \
- src/shared/tester.c
+tools_rfcomm_tester_SOURCES = tools/rfcomm-tester.c monitor/bt.h \
+ emulator/btdev.h emulator/btdev.c \
+ emulator/bthost.h emulator/bthost.c \
+ src/shared/io.h src/shared/io-glib.c \
+ src/shared/queue.h src/shared/queue.c \
+ 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
tools_rfcomm_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
tools_smp_tester_SOURCES = tools/smp-tester.c monitor/bt.h \
diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index 200d953..a4f1c8e 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -25,12 +25,261 @@
#include <config.h>
#endif
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdbool.h>
+
#include <glib.h>
+
+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+
+#include "monitor/bt.h"
+#include "emulator/bthost.h"
+
#include "src/shared/tester.h"
+#include "src/shared/mgmt.h"
+#include "src/shared/hciemu.h"
+
+struct test_data {
+ struct mgmt *mgmt;
+ uint16_t mgmt_index;
+ struct hciemu *hciemu;
+ enum hciemu_type hciemu_type;
+ const void *test_data;
+};
+
+static void mgmt_debug(const char *str, void *user_data)
+{
+ const char *prefix = user_data;
+
+ tester_print("%s%s", prefix, str);
+}
+
+static void read_info_callback(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct mgmt_rp_read_info *rp = param;
+ char addr[18];
+ uint16_t manufacturer;
+ uint32_t supported_settings, current_settings;
+
+ tester_print("Read Info callback");
+ tester_print(" Status: 0x%02x", status);
+
+ if (status || !param) {
+ tester_pre_setup_failed();
+ return;
+ }
+
+ ba2str(&rp->bdaddr, addr);
+ manufacturer = btohs(rp->manufacturer);
+ supported_settings = btohl(rp->supported_settings);
+ current_settings = btohl(rp->current_settings);
+
+ tester_print(" Address: %s", addr);
+ tester_print(" Version: 0x%02x", rp->version);
+ tester_print(" Manufacturer: 0x%04x", manufacturer);
+ tester_print(" Supported settings: 0x%08x", supported_settings);
+ tester_print(" Current settings: 0x%08x", current_settings);
+ tester_print(" Class: 0x%02x%02x%02x",
+ rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
+ tester_print(" Name: %s", rp->name);
+ tester_print(" Short name: %s", rp->short_name);
+
+ if (strcmp(hciemu_get_address(data->hciemu), addr)) {
+ tester_pre_setup_failed();
+ return;
+ }
+
+ tester_pre_setup_complete();
+}
+
+static void index_added_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+
+ tester_print("Index Added callback");
+ tester_print(" Index: 0x%04x", index);
+
+ data->mgmt_index = index;
+
+ mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
+ read_info_callback, NULL, NULL);
+}
+
+static void index_removed_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+
+ tester_print("Index Removed callback");
+ tester_print(" Index: 0x%04x", index);
+
+ if (index != data->mgmt_index)
+ return;
+
+ mgmt_unregister_index(data->mgmt, data->mgmt_index);
+
+ mgmt_unref(data->mgmt);
+ data->mgmt = NULL;
+
+ tester_post_teardown_complete();
+}
+
+static void read_index_list_callback(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+
+ tester_print("Read Index List callback");
+ tester_print(" Status: 0x%02x", status);
+
+ if (status || !param) {
+ tester_pre_setup_failed();
+ return;
+ }
+
+ mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+ index_added_callback, NULL, NULL);
+
+ mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+ index_removed_callback, NULL, NULL);
+
+ data->hciemu = hciemu_new(data->hciemu_type);
+ if (!data->hciemu) {
+ tester_warn("Failed to setup HCI emulation");
+ tester_pre_setup_failed();
+ }
+
+ tester_print("New hciemu instance created");
+}
+
+static void test_pre_setup(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ data->mgmt = mgmt_new_default();
+ if (!data->mgmt) {
+ tester_warn("Failed to setup management interface");
+ tester_pre_setup_failed();
+ return;
+ }
+
+ if (tester_use_debug())
+ mgmt_set_debug(data->mgmt, mgmt_debug, "mgmt: ", NULL);
+
+ mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL,
+ read_index_list_callback, NULL, NULL);
+}
+
+static void test_post_teardown(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ hciemu_unref(data->hciemu);
+ data->hciemu = NULL;
+}
+
+static void test_data_free(void *test_data)
+{
+ struct test_data *data = test_data;
+
+ free(data);
+}
+
+static void client_connectable_complete(uint16_t opcode, uint8_t status,
+ const void *param, uint8_t len,
+ void *user_data)
+{
+ switch (opcode) {
+ case BT_HCI_CMD_WRITE_SCAN_ENABLE:
+ break;
+ default:
+ return;
+ }
+
+ tester_print("Client set connectable status 0x%02x", status);
+
+ if (status)
+ tester_setup_failed();
+ else
+ tester_setup_complete();
+}
+
+static void setup_powered_client_callback(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost;
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ tester_setup_failed();
+ return;
+ }
+
+ tester_print("Controller powered on");
+
+ bthost = hciemu_client_get_host(data->hciemu);
+ bthost_set_cmd_complete_cb(bthost, client_connectable_complete, data);
+ bthost_write_scan_enable(bthost, 0x03);
+}
+
+static void setup_powered_client(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ unsigned char param[] = { 0x01 };
+
+ tester_print("Powering on controller");
+
+ mgmt_send(data->mgmt, MGMT_OP_SET_SSP, data->mgmt_index,
+ sizeof(param), param, NULL, NULL, NULL);
+
+ mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
+ sizeof(param), param, setup_powered_client_callback,
+ NULL, NULL);
+}
+
+static void test_basic(const void *test_data)
+{
+ int sk;
+
+ sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+ if (sk < 0) {
+ tester_warn("Can't create socket: %s (%d)", strerror(errno),
+ errno);
+ tester_test_failed();
+ return;
+ }
+
+ close(sk);
+
+ tester_test_passed();
+}
+
+#define test_rfcomm(name, data, setup, func) \
+ do { \
+ struct test_data *user; \
+ user = malloc(sizeof(struct test_data)); \
+ if (!user) \
+ break; \
+ user->hciemu_type = HCIEMU_TYPE_BREDR; \
+ user->test_data = data; \
+ tester_add_full(name, data, \
+ test_pre_setup, setup, func, NULL, \
+ test_post_teardown, 2, user, test_data_free); \
+ } while (0)
int main(int argc, char *argv[])
{
tester_init(&argc, &argv);
+ test_rfcomm("Basic RFCOMM Socket - Success", NULL,
+ setup_powered_client, test_basic);
+
return tester_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 03/19] monitor: Add rfcomm.h to tree
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
Add initial rfcomm structs and defines to rfcomm.h.
---
monitor/rfcomm.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 monitor/rfcomm.h
diff --git a/monitor/rfcomm.h b/monitor/rfcomm.h
new file mode 100644
index 0000000..8dcb9c1
--- /dev/null
+++ b/monitor/rfcomm.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Intel Corporation
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define RFCOMM_SABM 0x2f
+#define RFCOMM_DISC 0x43
+#define RFCOMM_UA 0x63
+#define RFCOMM_DM 0x0f
+#define RFCOMM_UIH 0xef
+
+#define RFCOMM_GET_TYPE(control) ((control) & 0xef)
+#define RFCOMM_GET_DLCI(address) ((address & 0xfc) >> 2)
+#define RFCOMM_GET_CHANNEL(address) ((address & 0xf8) >> 3)
+#define RFCOMM_GET_DIR(address) ((address & 0x04) >> 2)
+#define RFCOMM_TEST_EA(length) ((length & 0x01))
+
+struct rfcomm_hdr {
+ uint8_t address;
+ uint8_t control;
+ uint8_t length;
+} __attribute__((packed));
+
+struct rfcomm_cmd {
+ uint8_t address;
+ uint8_t control;
+ uint8_t length;
+ uint8_t fcs;
+} __attribute__((packed));
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 04/19] emulator/bthost: Add initial rfcomm handling
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
This is initial rfcomm handling in bthost.
---
emulator/bthost.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 66 insertions(+), 1 deletion(-)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 4ce720e..f896616 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -36,6 +36,7 @@
#include "bluetooth/bluetooth.h"
#include "monitor/bt.h"
+#include "monitor/rfcomm.h"
#include "bthost.h"
/* ACL handle and flags pack/unpack */
@@ -1236,6 +1237,64 @@ static struct cid_hook *find_cid_hook(struct btconn *conn, uint16_t cid)
return NULL;
}
+static void rfcomm_sabm_recv(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, const void *data,
+ uint16_t len)
+{
+}
+
+static void rfcomm_disc_recv(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, const void *data,
+ uint16_t len)
+{
+}
+
+static void rfcomm_ua_recv(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, const void *data,
+ uint16_t len)
+{
+}
+
+static void rfcomm_dm_recv(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, const void *data,
+ uint16_t len)
+{
+}
+
+static void rfcomm_uih_recv(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, const void *data,
+ uint16_t len)
+{
+}
+
+static void process_rfcomm(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, const void *data,
+ uint16_t len)
+{
+ const struct rfcomm_hdr *hdr = data;
+
+ switch (RFCOMM_GET_TYPE(hdr->control)) {
+ case RFCOMM_SABM:
+ rfcomm_sabm_recv(bthost, conn, l2conn, data, len);
+ break;
+ case RFCOMM_DISC:
+ rfcomm_disc_recv(bthost, conn, l2conn, data, len);
+ break;
+ case RFCOMM_UA:
+ rfcomm_ua_recv(bthost, conn, l2conn, data, len);
+ break;
+ case RFCOMM_DM:
+ rfcomm_dm_recv(bthost, conn, l2conn, data, len);
+ break;
+ case RFCOMM_UIH:
+ rfcomm_uih_recv(bthost, conn, l2conn, data, len);
+ break;
+ default:
+ printf("Unknown frame type\n");
+ break;
+ }
+}
+
static void process_acl(struct bthost *bthost, const void *data, uint16_t len)
{
const struct bt_hci_acl_hdr *acl_hdr = data;
@@ -1243,6 +1302,7 @@ static void process_acl(struct bthost *bthost, const void *data, uint16_t len)
uint16_t handle, cid, acl_len, l2_len;
struct cid_hook *hook;
struct btconn *conn;
+ struct l2conn *l2conn;
const void *l2_data;
if (len < sizeof(*acl_hdr) + sizeof(*l2_hdr))
@@ -1281,7 +1341,12 @@ static void process_acl(struct bthost *bthost, const void *data, uint16_t len)
l2cap_le_sig(bthost, conn, l2_data, l2_len);
break;
default:
- printf("Packet for unknown CID 0x%04x (%u)\n", cid, cid);
+ l2conn = btconn_find_l2cap_conn_by_scid(conn, cid);
+ if (l2conn && l2conn->psm == 0x0003)
+ process_rfcomm(bthost, conn, l2conn, l2_data, l2_len);
+ else
+ printf("Packet for unknown CID 0x%04x (%u)\n", cid,
+ cid);
break;
}
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 05/19] emulator/bthost: Add method to create rfcomm server
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
It allows user to create rfcomm server on bthost.
---
emulator/bthost.c | 32 ++++++++++++++++++++++++++++++++
emulator/bthost.h | 7 +++++++
2 files changed, 39 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index f896616..bf63b2f 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -99,6 +99,13 @@ struct l2cap_conn_cb_data {
struct l2cap_conn_cb_data *next;
};
+struct rfcomm_conn_cb_data {
+ uint8_t channel;
+ bthost_rfcomm_connect_cb func;
+ void *user_data;
+ struct rfcomm_conn_cb_data *next;
+};
+
struct bthost {
uint8_t bdaddr[6];
bthost_send_func send_handler;
@@ -111,6 +118,7 @@ struct bthost {
bthost_new_conn_cb new_conn_cb;
void *new_conn_data;
struct l2cap_conn_cb_data *new_l2cap_conn_data;
+ struct rfcomm_conn_cb_data *new_rfcomm_conn_data;
struct l2cap_pending_req *l2reqs;
uint8_t pin[16];
uint8_t pin_len;
@@ -248,6 +256,13 @@ void bthost_destroy(struct bthost *bthost)
free(cb);
}
+ while (bthost->new_rfcomm_conn_data) {
+ struct rfcomm_conn_cb_data *cb = bthost->new_rfcomm_conn_data;
+
+ bthost->new_rfcomm_conn_data = cb->next;
+ free(cb);
+ }
+
free(bthost);
}
@@ -1462,6 +1477,23 @@ void bthost_set_pin_code(struct bthost *bthost, const uint8_t *pin,
bthost->pin_len = pin_len;
}
+void bthost_add_rfcomm_server(struct bthost *bthost, uint8_t channel,
+ bthost_rfcomm_connect_cb func, void *user_data)
+{
+ struct rfcomm_conn_cb_data *data;
+
+ data = malloc(sizeof(struct rfcomm_conn_cb_data));
+ if (!data)
+ return;
+
+ data->channel = channel;
+ data->user_data = user_data;
+ data->func = func;
+ data->next = bthost->new_rfcomm_conn_data;
+
+ bthost->new_rfcomm_conn_data = data;
+}
+
void bthost_start(struct bthost *bthost)
{
if (!bthost)
diff --git a/emulator/bthost.h b/emulator/bthost.h
index 7458d5e..2fc21b5 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -83,5 +83,12 @@ void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm,
void bthost_set_pin_code(struct bthost *bthost, const uint8_t *pin,
uint8_t pin_len);
+typedef void (*bthost_rfcomm_connect_cb) (uint16_t handle, uint16_t cid,
+ uint8_t channel, void *user_data,
+ bool status);
+
+void bthost_add_rfcomm_server(struct bthost *bthost, uint8_t channel,
+ bthost_rfcomm_connect_cb func, void *user_data);
+
void bthost_start(struct bthost *bthost);
void bthost_stop(struct bthost *bthost);
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 06/19] emulator/bthost: Add recv_sabm imnplementation
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
This will handle sabm frames and send ua or dm frame.
---
emulator/bthost.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 111 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index bf63b2f..242ce19 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -49,6 +49,62 @@
#define cpu_to_le16(val) (val)
#define cpu_to_le32(val) (val)
+/* RFCOMM setters */
+#define RFCOMM_ADDR(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
+#define RFCOMM_CTRL(type, pf) (((type & 0xef) | (pf << 4)))
+#define RFCOMM_LEN8(len) (((len) << 1) | 1)
+#define RFCOMM_LEN16(len) ((len) << 1)
+
+/* RFCOMM FCS calculation */
+#define CRC(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
+
+static unsigned char rfcomm_crc_table[256] = {
+ 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
+ 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
+ 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
+ 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
+
+ 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
+ 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
+ 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
+ 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
+
+ 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
+ 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
+ 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
+ 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
+
+ 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
+ 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
+ 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
+ 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
+
+ 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
+ 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
+ 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
+ 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
+
+ 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
+ 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
+ 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
+ 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
+
+ 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
+ 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
+ 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
+ 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
+
+ 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
+ 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
+ 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
+ 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
+};
+
+static uint8_t rfcomm_fcs2(uint8_t *data)
+{
+ return 0xff - rfcomm_crc_table[CRC(data) ^ data[2]];
+}
+
struct cmd {
struct cmd *next;
struct cmd *prev;
@@ -222,6 +278,19 @@ static struct l2cap_conn_cb_data *bthost_find_l2cap_cb_by_psm(
return NULL;
}
+static struct rfcomm_conn_cb_data *bthost_find_rfcomm_cb_by_channel(
+ struct bthost *bthost, uint8_t channel)
+{
+ struct rfcomm_conn_cb_data *cb;
+
+ for (cb = bthost->new_rfcomm_conn_data; cb != NULL; cb = cb->next) {
+ if (cb->channel == channel)
+ return cb;
+ }
+
+ return NULL;
+}
+
void bthost_destroy(struct bthost *bthost)
{
if (!bthost)
@@ -1252,10 +1321,52 @@ static struct cid_hook *find_cid_hook(struct btconn *conn, uint16_t cid)
return NULL;
}
+static void rfcomm_ua_send(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, uint8_t cr, uint8_t dlci)
+{
+ struct rfcomm_cmd cmd;
+
+ cmd.address = RFCOMM_ADDR(cr, dlci);
+ cmd.control = RFCOMM_CTRL(RFCOMM_UA, 1);
+ cmd.length = RFCOMM_LEN8(0);
+ cmd.fcs = rfcomm_fcs2((uint8_t *)&cmd);
+
+ send_acl(bthost, conn->handle, l2conn->dcid, &cmd, sizeof(cmd));
+}
+
+static void rfcomm_dm_send(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, uint8_t cr, uint8_t dlci)
+{
+ struct rfcomm_cmd cmd;
+
+ cmd.address = RFCOMM_ADDR(cr, dlci);
+ cmd.control = RFCOMM_CTRL(RFCOMM_DM, 1);
+ cmd.length = RFCOMM_LEN8(0);
+ cmd.fcs = rfcomm_fcs2((uint8_t *)&cmd);
+
+ send_acl(bthost, conn->handle, l2conn->dcid, &cmd, sizeof(cmd));
+}
+
static void rfcomm_sabm_recv(struct bthost *bthost, struct btconn *conn,
struct l2conn *l2conn, const void *data,
uint16_t len)
{
+ const struct rfcomm_cmd *hdr = data;
+ uint8_t dlci = RFCOMM_GET_DLCI(hdr->address);
+ struct rfcomm_conn_cb_data *cb;
+
+ cb = bthost_find_rfcomm_cb_by_channel(bthost,
+ RFCOMM_GET_CHANNEL(hdr->address));
+
+ if (!dlci || cb) {
+ rfcomm_ua_send(bthost, conn, l2conn, 1, dlci);
+ if (cb && cb->func)
+ cb->func(conn->handle, l2conn->scid,
+ RFCOMM_GET_CHANNEL(hdr->address),
+ cb->user_data, true);
+ } else {
+ rfcomm_dm_send(bthost, conn, l2conn, 1, dlci);
+ }
}
static void rfcomm_disc_recv(struct bthost *bthost, struct btconn *conn,
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 07/19] monitor: Add mcc structs and types to rfcomm.h
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
---
monitor/rfcomm.h | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/monitor/rfcomm.h b/monitor/rfcomm.h
index 8dcb9c1..4222624 100644
--- a/monitor/rfcomm.h
+++ b/monitor/rfcomm.h
@@ -45,3 +45,35 @@ struct rfcomm_cmd {
uint8_t length;
uint8_t fcs;
} __attribute__((packed));
+
+#define RFCOMM_TEST 0x08
+#define RFCOMM_FCON 0x28
+#define RFCOMM_FCOFF 0x18
+#define RFCOMM_MSC 0x38
+#define RFCOMM_RPN 0x24
+#define RFCOMM_RLS 0x14
+#define RFCOMM_PN 0x20
+#define RFCOMM_NSC 0x04
+
+#define RFCOMM_TEST_CR(type) ((type & 0x02))
+#define RFCOMM_GET_MCC_TYPE(type) ((type & 0xfc) >> 2)
+
+struct rfcomm_mcc {
+ uint8_t type;
+ uint8_t length;
+} __attribute__((packed));
+
+struct rfcomm_msc {
+ uint8_t dlci;
+ uint8_t v24_sig;
+} __attribute__((packed));
+
+struct rfcomm_pn {
+ uint8_t dlci;
+ uint8_t flow_ctrl;
+ uint8_t priority;
+ uint8_t ack_timer;
+ uint16_t mtu;
+ uint8_t max_retrans;
+ uint8_t credits;
+} __attribute__((packed));
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 08/19] emulator/bthost: Add rfcomm_mcc_recv stub
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
It will handle mcc frames in bthost.
---
emulator/bthost.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 242ce19..591aae9 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -1387,10 +1387,29 @@ static void rfcomm_dm_recv(struct bthost *bthost, struct btconn *conn,
{
}
+static void rfcomm_mcc_recv(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, const void *data, uint16_t len)
+{
+}
+
static void rfcomm_uih_recv(struct bthost *bthost, struct btconn *conn,
struct l2conn *l2conn, const void *data,
uint16_t len)
{
+ const struct rfcomm_cmd *hdr = data;
+ const void *p;
+ uint8_t ea;
+
+ ea = RFCOMM_TEST_EA(hdr->length) ? true : false;
+
+ if (!RFCOMM_GET_DLCI(hdr->address)) {
+ if (ea)
+ p = data + sizeof(struct rfcomm_hdr);
+ else
+ p = data + sizeof(struct rfcomm_hdr) + sizeof(uint8_t);
+
+ rfcomm_mcc_recv(bthost, conn, l2conn, p, p - data);
+ }
}
static void process_rfcomm(struct bthost *bthost, struct btconn *conn,
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 09/19] emulator/bthost: Add recv_pn implementation
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
---
emulator/bthost.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 591aae9..83f1e96 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -54,6 +54,7 @@
#define RFCOMM_CTRL(type, pf) (((type & 0xef) | (pf << 4)))
#define RFCOMM_LEN8(len) (((len) << 1) | 1)
#define RFCOMM_LEN16(len) ((len) << 1)
+#define RFCOMM_MCC_TYPE(cr, type) (((type << 2) | (cr << 1) | 0x01))
/* RFCOMM FCS calculation */
#define CRC(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
@@ -105,6 +106,11 @@ static uint8_t rfcomm_fcs2(uint8_t *data)
return 0xff - rfcomm_crc_table[CRC(data) ^ data[2]];
}
+static uint8_t rfcomm_fcs(uint8_t *data)
+{
+ return 0xff - CRC(data);
+}
+
struct cmd {
struct cmd *next;
struct cmd *prev;
@@ -1387,9 +1393,56 @@ static void rfcomm_dm_recv(struct bthost *bthost, struct btconn *conn,
{
}
+static void rfcomm_pn_recv(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, uint8_t cr,
+ const struct rfcomm_pn *pn)
+{
+ if (cr) {
+ uint8_t buf[14];
+ struct rfcomm_hdr *hdr = (struct rfcomm_hdr *)buf;
+ struct rfcomm_mcc *mcc = (struct rfcomm_mcc *)(buf +
+ sizeof(*hdr));
+ struct rfcomm_pn *pn_cmd = (struct rfcomm_pn *)
+ (buf + sizeof(*hdr) + sizeof(*mcc));
+
+ memset(buf, 0, sizeof(buf));
+
+ hdr->address = RFCOMM_ADDR(1, 0);
+ hdr->control = RFCOMM_CTRL(RFCOMM_UIH, 0);
+ hdr->length = RFCOMM_LEN8(sizeof(*mcc) + sizeof(*pn_cmd));
+
+ mcc->type = RFCOMM_MCC_TYPE(0, RFCOMM_PN);
+ mcc->length = RFCOMM_LEN8(sizeof(*pn_cmd));
+
+ pn_cmd->dlci = pn->dlci;
+ pn_cmd->priority = pn->priority;
+ pn_cmd->ack_timer = pn->ack_timer;
+ pn_cmd->max_retrans = pn->max_retrans;
+ pn_cmd->mtu = pn->mtu;
+ pn_cmd->credits = pn->credits;
+
+ buf[sizeof(*hdr) + sizeof(*mcc) + sizeof(*pn_cmd)] =
+ rfcomm_fcs(buf);
+
+ send_acl(bthost, conn->handle, l2conn->dcid, buf, sizeof(buf));
+ }
+}
+
static void rfcomm_mcc_recv(struct bthost *bthost, struct btconn *conn,
struct l2conn *l2conn, const void *data, uint16_t len)
{
+ const struct rfcomm_mcc *mcc = data;
+ uint8_t type = RFCOMM_GET_MCC_TYPE(mcc->type);
+
+ switch (type) {
+ case RFCOMM_PN:
+ rfcomm_pn_recv(bthost, conn, l2conn,
+ RFCOMM_TEST_CR(mcc->type) / 2,
+ data + sizeof(*mcc));
+ break;
+ default:
+ break;
+ }
}
static void rfcomm_uih_recv(struct bthost *bthost, struct btconn *conn,
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 10/19] emulator/bthost: Service msc frames
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
---
emulator/bthost.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 83f1e96..1e2506e 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -1393,6 +1393,29 @@ static void rfcomm_dm_recv(struct bthost *bthost, struct btconn *conn,
{
}
+static void rfcomm_msc_recv(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, uint8_t cr,
+ const struct rfcomm_msc *msc)
+{
+ uint8_t buf[8];
+ struct rfcomm_hdr *hdr = (struct rfcomm_hdr *)buf;
+ struct rfcomm_mcc *mcc = (struct rfcomm_mcc *)(buf + sizeof(*hdr));
+ struct rfcomm_msc *msc_cmd = (struct rfcomm_msc *)(buf + sizeof(*hdr)
+ + sizeof(*mcc));
+
+ hdr->address = RFCOMM_ADDR(0, 0);
+ hdr->control = RFCOMM_CTRL(RFCOMM_UIH, 0);
+ hdr->length = RFCOMM_LEN8(sizeof(*mcc) + sizeof(*msc));
+ mcc->type = RFCOMM_MCC_TYPE(cr, RFCOMM_MSC);
+ mcc->length = RFCOMM_LEN8(sizeof(*msc));
+
+ msc_cmd->dlci = msc->dlci;
+ msc_cmd->v24_sig = msc->v24_sig;
+ buf[sizeof(*hdr) + sizeof(*mcc) + sizeof(*msc_cmd)] = rfcomm_fcs(buf);
+
+ send_acl(bthost, conn->handle, l2conn->dcid, buf, sizeof(buf));
+}
+
static void rfcomm_pn_recv(struct bthost *bthost, struct btconn *conn,
struct l2conn *l2conn, uint8_t cr,
const struct rfcomm_pn *pn)
@@ -1435,6 +1458,11 @@ static void rfcomm_mcc_recv(struct bthost *bthost, struct btconn *conn,
uint8_t type = RFCOMM_GET_MCC_TYPE(mcc->type);
switch (type) {
+ case RFCOMM_MSC:
+ rfcomm_msc_recv(bthost, conn, l2conn,
+ RFCOMM_TEST_CR(mcc->type) / 2,
+ data + sizeof(*mcc));
+ break;
case RFCOMM_PN:
rfcomm_pn_recv(bthost, conn, l2conn,
RFCOMM_TEST_CR(mcc->type) / 2,
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 11/19] emulator/bthost: Implement recv_disc rfcomm frame in bthost
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
---
emulator/bthost.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 1e2506e..391d6cd 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -1379,6 +1379,10 @@ static void rfcomm_disc_recv(struct bthost *bthost, struct btconn *conn,
struct l2conn *l2conn, const void *data,
uint16_t len)
{
+ const struct rfcomm_cmd *hdr = data;
+ uint8_t dlci = RFCOMM_GET_DLCI(hdr->address);
+
+ rfcomm_ua_send(bthost, conn, l2conn, 0, dlci);
}
static void rfcomm_ua_recv(struct bthost *bthost, struct btconn *conn,
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 12/19] tools/rfcomm-tester: Implement client test case
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
This will test RFCOMM client connection.
---
tools/rfcomm-tester.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 119 insertions(+)
diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index a4f1c8e..271f554 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -35,6 +35,7 @@
#include "lib/bluetooth.h"
#include "lib/mgmt.h"
+#include "bluetooth/rfcomm.h"
#include "monitor/bt.h"
#include "emulator/bthost.h"
@@ -49,6 +50,13 @@ struct test_data {
struct hciemu *hciemu;
enum hciemu_type hciemu_type;
const void *test_data;
+ unsigned int io_id;
+};
+
+struct rfcomm_client_data {
+ uint8_t server_channel;
+ uint8_t client_channel;
+ int expected_connect_err;
};
static void mgmt_debug(const char *str, void *user_data)
@@ -181,6 +189,11 @@ static void test_post_teardown(const void *test_data)
{
struct test_data *data = tester_get_data();
+ if (data->io_id > 0) {
+ g_source_remove(data->io_id);
+ data->io_id = 0;
+ }
+
hciemu_unref(data->hciemu);
data->hciemu = NULL;
}
@@ -244,6 +257,11 @@ static void setup_powered_client(const void *test_data)
NULL, NULL);
}
+const struct rfcomm_client_data connect_success = {
+ .server_channel = 0x0c,
+ .client_channel = 0x0c
+};
+
static void test_basic(const void *test_data)
{
int sk;
@@ -261,6 +279,104 @@ static void test_basic(const void *test_data)
tester_test_passed();
}
+static int create_rfcomm_sock(bdaddr_t *address, uint8_t channel)
+{
+ int sk;
+ struct sockaddr_rc addr;
+
+ sk = socket(PF_BLUETOOTH, SOCK_STREAM | SOCK_NONBLOCK, BTPROTO_RFCOMM);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.rc_family = AF_BLUETOOTH;
+ addr.rc_channel = channel;
+ bacpy(&addr.rc_bdaddr, address);
+
+ if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ close(sk);
+ return -1;
+ }
+
+ return sk;
+}
+
+static int connect_rfcomm_sock(int sk, bdaddr_t *address, uint8_t channel)
+{
+ struct sockaddr_rc addr;
+ int err;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.rc_family = AF_BLUETOOTH;
+ bacpy(&addr.rc_bdaddr, address);
+ addr.rc_channel = htobs(channel);
+
+ err = connect(sk, (struct sockaddr *) &addr, sizeof(addr));
+ if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS))
+ return err;
+
+ return 0;
+}
+
+static gboolean rc_connect_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct rfcomm_client_data *client_data = data->test_data;
+ socklen_t len = sizeof(int);
+ int sk, err, sk_err;
+
+ data->io_id = 0;
+
+ sk = g_io_channel_unix_get_fd(io);
+
+ if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &sk_err, &len) < 0)
+ err = -errno;
+ else
+ err = -sk_err;
+
+ if (client_data->expected_connect_err &&
+ err == client_data->expected_connect_err) {
+ tester_test_passed();
+ return false;
+ }
+
+ if (err < 0)
+ tester_test_failed();
+ else
+ tester_test_passed();
+
+ return false;
+}
+
+static void test_connect(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ const struct rfcomm_client_data *client_data = data->test_data;
+ GIOChannel *io;
+ int sk;
+
+ bthost_add_l2cap_server(bthost, 0x0003, NULL, NULL);
+ bthost_add_rfcomm_server(bthost, client_data->server_channel,
+ NULL, NULL);
+
+ sk = create_rfcomm_sock((bdaddr_t *)hciemu_get_master_bdaddr
+ (data->hciemu), 0);
+
+ if (connect_rfcomm_sock(sk, (bdaddr_t *)hciemu_get_client_bdaddr
+ (data->hciemu), client_data->client_channel) < 0) {
+ tester_test_failed();
+ }
+
+ io = g_io_channel_unix_new(sk);
+ g_io_channel_set_close_on_unref(io, TRUE);
+
+ data->io_id = g_io_add_watch(io, G_IO_OUT, rc_connect_cb, NULL);
+
+ g_io_channel_unref(io);
+
+ tester_print("Connect in progress %d", sk);
+}
+
#define test_rfcomm(name, data, setup, func) \
do { \
struct test_data *user; \
@@ -269,6 +385,7 @@ static void test_basic(const void *test_data)
break; \
user->hciemu_type = HCIEMU_TYPE_BREDR; \
user->test_data = data; \
+ user->io_id = 0; \
tester_add_full(name, data, \
test_pre_setup, setup, func, NULL, \
test_post_teardown, 2, user, test_data_free); \
@@ -280,6 +397,8 @@ int main(int argc, char *argv[])
test_rfcomm("Basic RFCOMM Socket - Success", NULL,
setup_powered_client, test_basic);
+ test_rfcomm("Basic RFCOMM Socket Client - Success", &connect_success,
+ setup_powered_client, test_connect);
return tester_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 13/19] tools/rfcomm-tester: Add Connection refused client test case
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
This will test RFCOMM client connection to wrong server channel.
---
tools/rfcomm-tester.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index 271f554..f471c3b 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -262,6 +262,12 @@ const struct rfcomm_client_data connect_success = {
.client_channel = 0x0c
};
+const struct rfcomm_client_data connect_nval = {
+ .server_channel = 0x0c,
+ .client_channel = 0x0e,
+ .expected_connect_err = -ECONNREFUSED
+};
+
static void test_basic(const void *test_data)
{
int sk;
@@ -399,6 +405,8 @@ int main(int argc, char *argv[])
setup_powered_client, test_basic);
test_rfcomm("Basic RFCOMM Socket Client - Success", &connect_success,
setup_powered_client, test_connect);
+ test_rfcomm("Basic RFCOMM Socket Client - Conn Refused",
+ &connect_nval, setup_powered_client, test_connect);
return tester_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 14/19] emulator/bthost: Implement bthost_connect_rfcomm
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
This method will start L2CAP connection on RFCOMM PSM and continue
connecting to rfcomm server. User can specify callback to be called
after connection.
---
emulator/bthost.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
emulator/bthost.h | 4 ++++
2 files changed, 66 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 391d6cd..4006b71 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -168,6 +168,13 @@ struct rfcomm_conn_cb_data {
struct rfcomm_conn_cb_data *next;
};
+struct rfcomm_connection_data {
+ uint8_t channel;
+ struct btconn *conn;
+ bthost_rfcomm_connect_cb cb;
+ void *user_data;
+};
+
struct bthost {
uint8_t bdaddr[6];
bthost_send_func send_handler;
@@ -179,6 +186,7 @@ struct bthost {
void *cmd_complete_data;
bthost_new_conn_cb new_conn_cb;
void *new_conn_data;
+ struct rfcomm_connection_data *rfcomm_conn_data;
struct l2cap_conn_cb_data *new_l2cap_conn_data;
struct rfcomm_conn_cb_data *new_rfcomm_conn_data;
struct l2cap_pending_req *l2reqs;
@@ -338,6 +346,10 @@ void bthost_destroy(struct bthost *bthost)
free(cb);
}
+ if (bthost->rfcomm_conn_data)
+ free(bthost->rfcomm_conn_data);
+
+
free(bthost);
}
@@ -977,6 +989,19 @@ static bool l2cap_conn_req(struct bthost *bthost, struct btconn *conn,
return true;
}
+static void rfcomm_sabm_send(struct bthost *bthost, struct btconn *conn,
+ struct l2conn *l2conn, uint8_t cr, uint8_t dlci)
+{
+ struct rfcomm_cmd cmd;
+
+ cmd.address = RFCOMM_ADDR(cr, dlci);
+ cmd.control = RFCOMM_CTRL(RFCOMM_SABM, 1);
+ cmd.length = RFCOMM_LEN8(0);
+ cmd.fcs = rfcomm_fcs2((uint8_t *)&cmd);
+
+ send_acl(bthost, conn->handle, l2conn->dcid, &cmd, sizeof(cmd));
+}
+
static bool l2cap_conn_rsp(struct bthost *bthost, struct btconn *conn,
uint8_t ident, const void *data, uint16_t len)
{
@@ -1000,6 +1025,10 @@ static bool l2cap_conn_rsp(struct bthost *bthost, struct btconn *conn,
l2cap_sig_send(bthost, conn, BT_L2CAP_PDU_CONFIG_REQ, 0,
&req, sizeof(req));
+ } else if (l2conn->psm == 0x0003 && le16_to_cpu(rsp->result) == 0 &&
+ le16_to_cpu(rsp->status) == 0 &&
+ bthost->rfcomm_conn_data) {
+ rfcomm_sabm_send(bthost, conn, l2conn, 1, 0);
}
return true;
@@ -1721,6 +1750,39 @@ void bthost_start(struct bthost *bthost)
send_command(bthost, BT_HCI_CMD_READ_BD_ADDR, NULL, 0);
}
+bool bthost_connect_rfcomm(struct bthost *bthost, uint16_t handle,
+ uint8_t channel, bthost_rfcomm_connect_cb func,
+ void *user_data)
+{
+ struct rfcomm_connection_data *data;
+ struct bt_l2cap_pdu_conn_req req;
+ struct btconn *conn;
+
+ if (bthost->rfcomm_conn_data)
+ return false;
+
+ conn = bthost_find_conn(bthost, handle);
+ if (!conn)
+ return false;
+
+ data = malloc(sizeof(struct rfcomm_connection_data));
+ if (!data)
+ return false;
+
+ data->channel = channel;
+ data->conn = conn;
+ data->cb = func;
+ data->user_data = user_data;
+
+ bthost->rfcomm_conn_data = data;
+
+ req.psm = cpu_to_le16(0x0003);
+ req.scid = cpu_to_le16(conn->next_cid++);
+
+ return bthost_l2cap_req(bthost, handle, BT_L2CAP_PDU_CONN_REQ,
+ &req, sizeof(req), NULL, NULL);
+}
+
void bthost_stop(struct bthost *bthost)
{
}
diff --git a/emulator/bthost.h b/emulator/bthost.h
index 2fc21b5..2c9a125 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -90,5 +90,9 @@ typedef void (*bthost_rfcomm_connect_cb) (uint16_t handle, uint16_t cid,
void bthost_add_rfcomm_server(struct bthost *bthost, uint8_t channel,
bthost_rfcomm_connect_cb func, void *user_data);
+bool bthost_connect_rfcomm(struct bthost *bthost, uint16_t handle,
+ uint8_t channel, bthost_rfcomm_connect_cb func,
+ void *user_data);
+
void bthost_start(struct bthost *bthost);
void bthost_stop(struct bthost *bthost);
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 15/19] emulator/bthost: Ad implementation of rfcomm_ua_recv
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
This will handle ua responses in bthost.
---
emulator/bthost.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 4006b71..ebf8789 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -1418,6 +1418,41 @@ static void rfcomm_ua_recv(struct bthost *bthost, struct btconn *conn,
struct l2conn *l2conn, const void *data,
uint16_t len)
{
+ const struct rfcomm_cmd *hdr = data;
+ uint8_t channel = RFCOMM_GET_CHANNEL(hdr->address);
+
+ if (!channel && RFCOMM_TEST_CR(RFCOMM_GET_TYPE(hdr->control)) &&
+ bthost->rfcomm_conn_data) {
+ uint8_t buf[14];
+ struct rfcomm_hdr *hdr = (struct rfcomm_hdr *)buf;
+ struct rfcomm_mcc *mcc = (struct rfcomm_mcc *)
+ (buf + sizeof(*hdr));
+ struct rfcomm_pn *pn_cmd = (struct rfcomm_pn *)
+ (buf + sizeof(*hdr)
+ + sizeof(*mcc));
+
+ memset(buf, 0, sizeof(buf));
+
+ hdr->address = RFCOMM_ADDR(1, 0);
+ hdr->control = RFCOMM_CTRL(RFCOMM_UIH, 0);
+ hdr->length = RFCOMM_LEN8(sizeof(*mcc) +
+ sizeof(*pn_cmd));
+
+ mcc->type = RFCOMM_MCC_TYPE(1, RFCOMM_PN);
+ mcc->length = RFCOMM_LEN8(sizeof(*pn_cmd));
+
+ pn_cmd->dlci = bthost->rfcomm_conn_data->channel * 2;
+ pn_cmd->priority = 7;
+ pn_cmd->ack_timer = 0;
+ pn_cmd->max_retrans = 0;
+ pn_cmd->mtu = 667;
+ pn_cmd->credits = 7;
+
+ buf[sizeof(*hdr) + sizeof(*mcc) + sizeof(*pn_cmd)] =
+ rfcomm_fcs(buf);
+
+ send_acl(bthost, conn->handle, l2conn->dcid, buf, sizeof(buf));
+ }
}
static void rfcomm_dm_recv(struct bthost *bthost, struct btconn *conn,
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 16/19] emulator/bthost: Add implementation to PN RSP
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
This will send sabm command if PN_RSP will be received.
---
emulator/bthost.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index ebf8789..96200a0 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -1516,6 +1516,9 @@ static void rfcomm_pn_recv(struct bthost *bthost, struct btconn *conn,
rfcomm_fcs(buf);
send_acl(bthost, conn->handle, l2conn->dcid, buf, sizeof(buf));
+ } else if (bthost->rfcomm_conn_data) {
+ rfcomm_sabm_send(bthost, conn, l2conn,
+ 1, bthost->rfcomm_conn_data->channel * 2);
}
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 17/19] emulator/bthost: Call rfcomm_connect_cb when connected
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
This will call connect callback when connected or failed to connect.
---
emulator/bthost.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 96200a0..9b342ce 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -1452,6 +1452,15 @@ static void rfcomm_ua_recv(struct bthost *bthost, struct btconn *conn,
rfcomm_fcs(buf);
send_acl(bthost, conn->handle, l2conn->dcid, buf, sizeof(buf));
+ } else if (bthost->rfcomm_conn_data &&
+ bthost->rfcomm_conn_data->channel == channel) {
+ if (bthost->rfcomm_conn_data->cb)
+ bthost->rfcomm_conn_data->cb(conn->handle,
+ l2conn->scid, channel,
+ bthost->rfcomm_conn_data->user_data,
+ true);
+ free(bthost->rfcomm_conn_data);
+ bthost->rfcomm_conn_data = NULL;
}
}
@@ -1459,6 +1468,19 @@ static void rfcomm_dm_recv(struct bthost *bthost, struct btconn *conn,
struct l2conn *l2conn, const void *data,
uint16_t len)
{
+ const struct rfcomm_cmd *hdr = data;
+ uint8_t channel = RFCOMM_GET_CHANNEL(hdr->address);
+
+ if (bthost->rfcomm_conn_data &&
+ bthost->rfcomm_conn_data->channel == channel) {
+ if (bthost->rfcomm_conn_data->cb)
+ bthost->rfcomm_conn_data->cb(conn->handle,
+ l2conn->scid, channel,
+ bthost->rfcomm_conn_data->user_data,
+ false);
+ free(bthost->rfcomm_conn_data);
+ bthost->rfcomm_conn_data = NULL;
+ }
}
static void rfcomm_msc_recv(struct bthost *bthost, struct btconn *conn,
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 18/19] tools/rfcomm-tester: Add RFCOMM server test case
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
This test case create RFCOMM server and accept incoming connection from
client bthost.
---
tools/rfcomm-tester.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 144 insertions(+)
diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index f471c3b..72e765f 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -59,6 +59,12 @@ struct rfcomm_client_data {
int expected_connect_err;
};
+struct rfcomm_server_data {
+ uint8_t server_channel;
+ uint8_t client_channel;
+ bool expected_status;
+};
+
static void mgmt_debug(const char *str, void *user_data)
{
const char *prefix = user_data;
@@ -257,6 +263,37 @@ static void setup_powered_client(const void *test_data)
NULL, NULL);
}
+static void setup_powered_server_callback(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ if (status != MGMT_STATUS_SUCCESS) {
+ tester_setup_failed();
+ return;
+ }
+
+ tester_print("Controller powered on");
+
+ tester_setup_complete();
+}
+
+static void setup_powered_server(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ unsigned char param[] = { 0x01 };
+
+ tester_print("Powering on controller");
+
+ mgmt_send(data->mgmt, MGMT_OP_SET_CONNECTABLE, data->mgmt_index,
+ sizeof(param), param,
+ NULL, NULL, NULL);
+ mgmt_send(data->mgmt, MGMT_OP_SET_SSP, data->mgmt_index,
+ sizeof(param), param, NULL, NULL, NULL);
+
+ mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
+ sizeof(param), param, setup_powered_server_callback,
+ NULL, NULL);
+}
+
const struct rfcomm_client_data connect_success = {
.server_channel = 0x0c,
.client_channel = 0x0c
@@ -268,6 +305,12 @@ const struct rfcomm_client_data connect_nval = {
.expected_connect_err = -ECONNREFUSED
};
+const struct rfcomm_server_data listen_success = {
+ .server_channel = 0x0c,
+ .client_channel = 0x0c,
+ .expected_status = true
+};
+
static void test_basic(const void *test_data)
{
int sk;
@@ -383,6 +426,105 @@ static void test_connect(const void *test_data)
tester_print("Connect in progress %d", sk);
}
+static gboolean rfcomm_listen_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ int sk, new_sk;
+
+ data->io_id = 0;
+
+ sk = g_io_channel_unix_get_fd(io);
+
+ new_sk = accept(sk, NULL, NULL);
+ if (new_sk < 0) {
+ tester_test_failed();
+ return false;
+ }
+
+ close(new_sk);
+
+ tester_test_passed();
+
+ return false;
+}
+
+static void connection_cb(uint16_t handle, uint16_t cid,
+ uint8_t channel, void *user_data,
+ bool status)
+{
+ struct test_data *data = tester_get_data();
+ const struct rfcomm_server_data *server_data = data->test_data;
+
+ if (server_data->expected_status == status)
+ tester_test_passed();
+ else
+ tester_test_failed();
+}
+
+static void client_new_conn(uint16_t handle, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct rfcomm_server_data *server_data = data->test_data;
+ struct bthost *bthost;
+
+ bthost = hciemu_client_get_host(data->hciemu);
+ bthost_connect_rfcomm(bthost, handle, server_data->client_channel,
+ connection_cb, NULL);
+}
+
+static void test_server(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct rfcomm_server_data *server_data = data->test_data;
+ const uint8_t *master_bdaddr;
+ uint8_t addr_type;
+ struct bthost *bthost;
+ GIOChannel *io;
+ int sk;
+
+ sk = create_rfcomm_sock((bdaddr_t *)
+ hciemu_get_master_bdaddr(data->hciemu),
+ server_data->server_channel);
+ if (sk < 0) {
+ tester_test_failed();
+ return;
+ }
+
+ if (listen(sk, 5) < 0) {
+ tester_warn("listening on socket failed: %s (%u)",
+ strerror(errno), errno);
+ tester_test_failed();
+ close(sk);
+ return;
+ }
+
+ io = g_io_channel_unix_new(sk);
+ g_io_channel_set_close_on_unref(io, TRUE);
+
+ data->io_id = g_io_add_watch(io, G_IO_IN, rfcomm_listen_cb, NULL);
+ g_io_channel_unref(io);
+
+ tester_print("Listening for connections");
+
+ master_bdaddr = hciemu_get_master_bdaddr(data->hciemu);
+ if (!master_bdaddr) {
+ tester_warn("No master bdaddr");
+ tester_test_failed();
+ return;
+ }
+
+ bthost = hciemu_client_get_host(data->hciemu);
+ bthost_set_connect_cb(bthost, client_new_conn, data);
+
+ if (data->hciemu_type == HCIEMU_TYPE_BREDR)
+ addr_type = BDADDR_BREDR;
+ else
+ addr_type = BDADDR_LE_PUBLIC;
+
+ bthost_hci_connect(bthost, master_bdaddr, addr_type);
+}
+
#define test_rfcomm(name, data, setup, func) \
do { \
struct test_data *user; \
@@ -407,6 +549,8 @@ int main(int argc, char *argv[])
setup_powered_client, test_connect);
test_rfcomm("Basic RFCOMM Socket Client - Conn Refused",
&connect_nval, setup_powered_client, test_connect);
+ test_rfcomm("Basic RFCOMM Socket Server - Success", &listen_success,
+ setup_powered_server, test_server);
return tester_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv3 19/19] tools/rfcomm-tester: Add RFCOMM server negative test case
From: Marcin Kraglak @ 2014-01-10 9:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389345509-27206-1-git-send-email-marcin.kraglak@tieto.com>
This test case create RFCOMM server and reject incoming connection
from bthost.
---
tools/rfcomm-tester.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index 72e765f..7997a4b 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -311,6 +311,12 @@ const struct rfcomm_server_data listen_success = {
.expected_status = true
};
+const struct rfcomm_server_data listen_nval = {
+ .server_channel = 0x0c,
+ .client_channel = 0x0e,
+ .expected_status = false
+};
+
static void test_basic(const void *test_data)
{
int sk;
@@ -551,6 +557,8 @@ int main(int argc, char *argv[])
&connect_nval, setup_powered_client, test_connect);
test_rfcomm("Basic RFCOMM Socket Server - Success", &listen_success,
setup_powered_server, test_server);
+ test_rfcomm("Basic RFCOMM Socket Server - Conn Refused", &listen_nval,
+ setup_powered_server, test_server);
return tester_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2] android/tester: Multi property check for test case
From: Grzegorz Kolodziejczyk @ 2014-01-10 9:22 UTC (permalink / raw)
To: linux-bluetooth
This patch allows to check multiple properties for test case. Properties
can be prioritized to allow check if they'll come in right order. Now
properties aren't treated as a "single" callback. In future in one
callback multiple properties can come.
---
android/android-tester.c | 530 ++++++++++++++++++++++++++++++++++-------------
1 file changed, 386 insertions(+), 144 deletions(-)
diff --git a/android/android-tester.c b/android/android-tester.c
index a29c982..a3c5f58 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -43,13 +43,19 @@
#include "utils.h"
+struct priority_property {
+ bt_property_t prop;
+ int prio;
+};
+
struct generic_data {
int expected_adapter_status;
uint32_t expect_settings_set;
int expected_cb_count;
bt_property_t set_property;
- bt_property_t expected_property;
bt_callbacks_t expected_hal_cb;
+ struct priority_property *expected_properties;
+ uint8_t expected_properties_num;
};
struct socket_data {
@@ -91,6 +97,7 @@ struct test_data {
bool test_init_done;
int cb_count;
+ GSList *expected_properties_list;
};
static char exec_dir[PATH_MAX + 1];
@@ -185,9 +192,18 @@ static void expected_status_init(struct test_data *data)
static void test_property_init(struct test_data *data)
{
const struct generic_data *test_data = data->test_data;
+ GSList *l = data->expected_properties_list;
+ int i;
- if (!test_data->expected_property.type)
+ if (!test_data->expected_hal_cb.adapter_properties_cb) {
data->property_checked = true;
+ return;
+ }
+
+ for (i = 0; i < test_data->expected_properties_num; i++)
+ l = g_slist_prepend(l, &(test_data->expected_properties[i]));
+
+ data->expected_properties_list = l;
}
static void init_test_conditions(struct test_data *data)
@@ -212,6 +228,75 @@ static void check_expected_status(uint8_t status)
tester_test_failed();
}
+static int locate_property(gconstpointer expected_data,
+ gconstpointer received_prop)
+{
+ bt_property_t rec_prop = *((bt_property_t *)received_prop);
+ bt_property_t exp_prop =
+ ((struct priority_property *)expected_data)->prop;
+
+ if (exp_prop.type && (exp_prop.type != rec_prop.type))
+ return 1;
+ if (exp_prop.len && (exp_prop.len != rec_prop.len))
+ return 1;
+ if (exp_prop.val && memcmp(exp_prop.val, rec_prop.val, exp_prop.len))
+ return 1;
+
+ return 0;
+}
+
+static int compare_priorities(gconstpointer prop_list, gconstpointer priority)
+{
+ int prio = GPOINTER_TO_INT(priority);
+ int comp_prio = ((struct priority_property *)prop_list)->prio;
+
+ if (prio > comp_prio)
+ return 0;
+
+ return 1;
+}
+
+static bool check_prop_priority(int rec_prop_prio)
+{
+ struct test_data *data = tester_get_data();
+ GSList *l = data->expected_properties_list;
+
+ if (!rec_prop_prio || !g_slist_length(l))
+ return true;
+
+ if (g_slist_find_custom(l, GINT_TO_POINTER(rec_prop_prio),
+ &compare_priorities))
+ return false;
+
+ return true;
+}
+
+static void check_expected_property(bt_property_t received_prop)
+{
+ struct test_data *data = tester_get_data();
+ int rec_prio;
+ GSList *l = data->expected_properties_list;
+ GSList *found_exp_prop;
+
+ found_exp_prop = g_slist_find_custom(l, &received_prop,
+ &locate_property);
+
+ if (found_exp_prop) {
+ rec_prio = ((struct priority_property *)
+ (found_exp_prop->data))->prio;
+ if (check_prop_priority(rec_prio))
+ l = g_slist_remove(l, found_exp_prop->data);
+ }
+
+ data->expected_properties_list = l;
+
+ if (g_slist_length(l))
+ return;
+
+ data->property_checked = true;
+ test_update_state();
+}
+
static bool check_test_property(bt_property_t received_prop,
bt_property_t expected_prop)
{
@@ -625,27 +710,18 @@ static void device_found_cb(int num_properties, bt_property_t *properties)
if (data->test_init_done && test->expected_hal_cb.device_found_cb) {
test->expected_hal_cb.device_found_cb(num_properties,
properties);
- check_cb_count();
}
}
static void check_count_properties_cb(bt_status_t status, int num_properties,
bt_property_t *properties)
{
- struct test_data *data = tester_get_data();
+ int i;
- data->cb_count--;
+ for (i = 0; i < num_properties; i++)
+ check_expected_property(properties[i]);
}
-static void getprop_success_cb(bt_status_t status, int num_properties,
- bt_property_t *properties)
-{
- struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
-
- if (check_test_property(properties[0], test->expected_property))
- data->cb_count--;
-}
static void adapter_properties_cb(bt_status_t status, int num_properties,
bt_property_t *properties)
@@ -658,21 +734,87 @@ static void adapter_properties_cb(bt_status_t status, int num_properties,
test->expected_hal_cb.adapter_properties_cb(
status, num_properties,
properties);
- check_cb_count();
}
}
+static bt_bdaddr_t enable_done_bdaddr_val = {
+ .address = { 0x00, 0xaa, 0x01, 0x00, 0x00, 0x00 },
+};
+static const char enable_done_bdname_val[] = "";
+static bt_uuid_t enable_done_uuids_val = {
+ .uu = { 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00,
+ 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb},
+};
+static uint32_t enable_done_cod_val = 0;
+static bt_device_type_t enable_done_tod_val = BT_DEVICE_DEVTYPE_BREDR;
+static bt_scan_mode_t enable_done_scanmode_val = BT_SCAN_MODE_NONE;
+static uint32_t enable_done_disctimeout_val = 120;
+
+static struct priority_property enable_done_props[] = {
+ {
+ .prop.type = BT_PROPERTY_BDADDR,
+ .prop.len = sizeof(enable_done_bdaddr_val),
+ .prop.val = &enable_done_bdaddr_val,
+ .prio = 1,
+ },
+ {
+ .prop.type = BT_PROPERTY_BDNAME,
+ .prop.len = sizeof(enable_done_bdname_val) - 1,
+ .prop.val = &enable_done_bdname_val,
+ .prio = 2,
+ },
+ {
+ .prop.type = BT_PROPERTY_UUIDS,
+ .prop.len = sizeof(enable_done_uuids_val),
+ .prop.val = &enable_done_uuids_val,
+ .prio = 3,
+ },
+ {
+ .prop.type = BT_PROPERTY_CLASS_OF_DEVICE,
+ .prop.len = sizeof(enable_done_cod_val),
+ .prop.val = &enable_done_cod_val,
+ .prio = 4,
+ },
+ {
+ .prop.type = BT_PROPERTY_TYPE_OF_DEVICE,
+ .prop.len = sizeof(enable_done_tod_val),
+ .prop.val = &enable_done_tod_val,
+ .prio = 5,
+ },
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
+ .prop.len = sizeof(enable_done_scanmode_val),
+ .prop.val = &enable_done_scanmode_val,
+ .prio = 6,
+ },
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_BONDED_DEVICES,
+ .prop.len = 0,
+ .prop.val = NULL,
+ .prio = 7,
+ },
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
+ .prop.len = sizeof(enable_done_disctimeout_val),
+ .prop.val = &enable_done_disctimeout_val,
+ .prio = 8,
+ },
+};
+
static const struct generic_data bluetooth_enable_success_test = {
.expected_hal_cb.adapter_state_changed_cb = enable_success_cb,
.expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
- .expected_cb_count = 9,
+ .expected_cb_count = 1,
+ .expected_properties_num = 8,
+ .expected_properties = enable_done_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
};
static const struct generic_data bluetooth_enable_done_test = {
.expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
- .expected_cb_count = 8,
.expected_adapter_status = BT_STATUS_DONE,
+ .expected_properties_num = 8,
+ .expected_properties = enable_done_props,
};
static const struct generic_data bluetooth_disable_success_test = {
@@ -683,94 +825,148 @@ static const struct generic_data bluetooth_disable_success_test = {
static char test_set_bdname[] = "test_bdname_set";
+static struct priority_property setprop_bdname_props[] = {
+ {
+ .prop.type = BT_PROPERTY_BDNAME,
+ .prop.val = test_set_bdname,
+ .prop.len = sizeof(test_set_bdname) - 1,
+ .prio = 0,
+ },
+};
+
static const struct generic_data bluetooth_setprop_bdname_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
- .expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_BDNAME,
- .expected_property.val = test_set_bdname,
- .expected_property.len = sizeof(test_set_bdname) - 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = setprop_bdname_props,
};
static bt_scan_mode_t test_setprop_scanmode_val =
BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
+static struct priority_property setprop_scanmode_props[] = {
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
+ .prop.val = &test_setprop_scanmode_val,
+ .prop.len = sizeof(bt_scan_mode_t),
+ },
+};
+
static const struct generic_data bluetooth_setprop_scanmode_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = setprop_scanmode_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
- .expected_property.val = &test_setprop_scanmode_val,
- .expected_property.len = sizeof(bt_scan_mode_t),
};
static uint32_t test_setprop_disctimeout_val = 120;
+static struct priority_property setprop_disctimeout_props[] = {
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
+ .prop.val = &test_setprop_disctimeout_val,
+ .prop.len = sizeof(test_setprop_disctimeout_val),
+ },
+};
+
static const struct generic_data bluetooth_setprop_disctimeout_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = setprop_disctimeout_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
- .expected_property.val = &test_setprop_disctimeout_val,
- .expected_property.len = sizeof(test_setprop_disctimeout_val),
+};
+
+static bt_bdaddr_t test_getprop_bdaddr_val = {
+ .address = { 0x00, 0xaa, 0x01, 0x00, 0x00, 0x00 }
+};
+
+static struct priority_property getprop_bdaddr_props[] = {
+ {
+ .prop.type = BT_PROPERTY_BDADDR,
+ .prop.val = &test_getprop_bdaddr_val,
+ .prop.len = sizeof(test_getprop_bdaddr_val),
+ },
};
static const struct generic_data bluetooth_getprop_bdaddr_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = getprop_bdaddr_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_BDADDR,
- .expected_property.val = NULL,
- .expected_property.len = sizeof(bt_bdaddr_t),
};
static char test_bdname[] = "test_bdname_setget";
+static struct priority_property getprop_bdname_props[] = {
+ {
+ .prop.type = BT_PROPERTY_BDNAME,
+ .prop.val = &test_bdname,
+ .prop.len = sizeof(test_bdname) - 1,
+ },
+};
+
static const struct generic_data bluetooth_getprop_bdname_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = getprop_bdname_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_BDNAME,
- .expected_property.val = test_bdname,
- .expected_property.len = sizeof(test_bdname) - 1,
};
static unsigned char setprop_uuids[] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00,
0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00 };
+static struct priority_property setprop_uuid_prop[] = {
+ {
+ .prop.type = BT_PROPERTY_UUIDS,
+ .prop.val = &setprop_uuids,
+ .prop.len = sizeof(setprop_uuids),
+ },
+};
+
static const struct generic_data bluetooth_setprop_uuid_invalid_test = {
.expected_adapter_status = BT_STATUS_FAIL,
- .set_property.type = BT_PROPERTY_UUIDS,
- .set_property.val = &setprop_uuids,
- .set_property.len = sizeof(setprop_uuids),
};
static uint32_t setprop_class_of_device = 0;
+static struct priority_property setprop_cod_props[] = {
+ {
+ .prop.type = BT_PROPERTY_CLASS_OF_DEVICE,
+ .prop.val = &setprop_class_of_device,
+ .prop.len = sizeof(setprop_class_of_device),
+ },
+};
+
static const struct generic_data bluetooth_setprop_cod_invalid_test = {
.expected_adapter_status = BT_STATUS_FAIL,
- .set_property.type = BT_PROPERTY_CLASS_OF_DEVICE,
- .set_property.val = &setprop_class_of_device,
- .set_property.len = sizeof(setprop_class_of_device),
};
static bt_device_type_t setprop_type_of_device = BT_DEVICE_DEVTYPE_BREDR;
+static struct priority_property setprop_tod_props[] = {
+ {
+ .prop.type = BT_PROPERTY_TYPE_OF_DEVICE,
+ .prop.val = &setprop_type_of_device,
+ .prop.len = sizeof(setprop_type_of_device),
+ },
+};
+
static const struct generic_data bluetooth_setprop_tod_invalid_test = {
.expected_adapter_status = BT_STATUS_FAIL,
- .set_property.type = BT_PROPERTY_TYPE_OF_DEVICE,
- .set_property.val = &setprop_type_of_device,
- .set_property.len = sizeof(setprop_type_of_device),
};
static int32_t setprop_remote_rssi = 0;
+static struct priority_property setprop_remote_rssi_props[] = {
+ {
+ .prop.type = BT_PROPERTY_REMOTE_RSSI,
+ .prop.val = &setprop_remote_rssi,
+ .prop.len = sizeof(setprop_remote_rssi),
+ },
+};
+
static const struct generic_data bluetooth_setprop_remote_rssi_invalid_test = {
.expected_adapter_status = BT_STATUS_FAIL,
- .set_property.type = BT_PROPERTY_REMOTE_RSSI,
- .set_property.val = &setprop_remote_rssi,
- .set_property.len = sizeof(setprop_remote_rssi),
};
static bt_service_record_t setprop_remote_service = {
@@ -779,91 +975,136 @@ static bt_service_record_t setprop_remote_service = {
.name = "bt_name",
};
+static struct priority_property setprop_service_record_props[] = {
+ {
+ .prop.type = BT_PROPERTY_SERVICE_RECORD,
+ .prop.val = &setprop_remote_service,
+ .prop.len = sizeof(setprop_remote_service),
+ },
+};
+
static const struct generic_data
bluetooth_setprop_service_record_invalid_test = {
.expected_adapter_status = BT_STATUS_FAIL,
- .set_property.type = BT_PROPERTY_SERVICE_RECORD,
- .set_property.val = &setprop_remote_service,
- .set_property.len = sizeof(setprop_remote_service),
};
static bt_bdaddr_t setprop_bdaddr = {
.address = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
};
+static struct priority_property setprop_bdaddr_props[] = {
+ {
+ .prop.type = BT_PROPERTY_BDADDR,
+ .prop.val = &setprop_bdaddr,
+ .prop.len = sizeof(setprop_bdaddr),
+ },
+};
+
static const struct generic_data bluetooth_setprop_bdaddr_invalid_test = {
.expected_adapter_status = BT_STATUS_FAIL,
- .set_property.type = BT_PROPERTY_BDADDR,
- .set_property.val = &setprop_bdaddr,
- .set_property.len = sizeof(setprop_bdaddr),
};
static bt_scan_mode_t setprop_scanmode_connectable = BT_SCAN_MODE_CONNECTABLE;
+static struct priority_property setprop_scanmode_connectable_props[] = {
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
+ .prop.val = &setprop_scanmode_connectable,
+ .prop.len = sizeof(setprop_scanmode_connectable),
+ },
+};
+
static const struct generic_data
bluetooth_setprop_scanmode_connectable_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = setprop_scanmode_connectable_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
- .expected_property.val = &setprop_scanmode_connectable,
- .expected_property.len = sizeof(setprop_scanmode_connectable),
};
static bt_bdaddr_t setprop_bonded_devices = {
.address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 },
};
+static struct priority_property setprop_bonded_devices_props[] = {
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_BONDED_DEVICES,
+ .prop.val = &setprop_bonded_devices,
+ .prop.len = sizeof(setprop_bonded_devices),
+ },
+};
+
static const struct generic_data
bluetooth_setprop_bonded_devices_invalid_test = {
.expected_adapter_status = BT_STATUS_FAIL,
- .set_property.type = BT_PROPERTY_ADAPTER_BONDED_DEVICES,
- .set_property.val = &setprop_bonded_devices,
- .set_property.len = sizeof(setprop_bonded_devices),
};
static uint32_t getprop_cod = 0;
+static struct priority_property getprop_cod_props[] = {
+ {
+ .prop.type = BT_PROPERTY_CLASS_OF_DEVICE,
+ .prop.val = &getprop_cod,
+ .prop.len = sizeof(getprop_cod),
+ },
+};
+
static const struct generic_data bluetooth_getprop_cod_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = getprop_cod_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_CLASS_OF_DEVICE,
- .expected_property.val = &getprop_cod,
- .expected_property.len = sizeof(getprop_cod),
};
static bt_device_type_t getprop_tod = BT_DEVICE_DEVTYPE_BREDR;
+static struct priority_property getprop_tod_props[] = {
+ {
+ .prop.type = BT_PROPERTY_TYPE_OF_DEVICE,
+ .prop.val = &getprop_tod,
+ .prop.len = sizeof(getprop_tod),
+ },
+};
+
static const struct generic_data bluetooth_getprop_tod_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = getprop_tod_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_TYPE_OF_DEVICE,
- .expected_property.val = &getprop_tod,
- .expected_property.len = sizeof(getprop_tod),
};
static bt_scan_mode_t getprop_scanmode = BT_SCAN_MODE_NONE;
+static struct priority_property getprop_scanmode_props[] = {
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
+ .prop.val = &getprop_scanmode,
+ .prop.len = sizeof(getprop_scanmode),
+ },
+};
+
static const struct generic_data bluetooth_getprop_scanmode_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = getprop_scanmode_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
- .expected_property.val = &getprop_scanmode,
- .expected_property.len = sizeof(getprop_scanmode),
};
static uint32_t getprop_disctimeout_val = 120;
+static struct priority_property getprop_disctimeout_props[] = {
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
+ .prop.val = &getprop_disctimeout_val,
+ .prop.len = sizeof(getprop_disctimeout_val),
+ },
+};
+
static const struct generic_data bluetooth_getprop_disctimeout_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = getprop_disctimeout_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
- .expected_property.val = &getprop_disctimeout_val,
- .expected_property.len = sizeof(getprop_disctimeout_val),
};
static bt_uuid_t getprop_uuids = {
@@ -871,33 +1112,51 @@ static bt_uuid_t getprop_uuids = {
0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB },
};
+static struct priority_property getprop_uuids_props[] = {
+ {
+ .prop.type = BT_PROPERTY_UUIDS,
+ .prop.val = &getprop_uuids,
+ .prop.len = sizeof(getprop_uuids),
+ },
+};
+
static const struct generic_data bluetooth_getprop_uuids_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = getprop_uuids_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_UUIDS,
- .expected_property.val = &getprop_uuids,
- .expected_property.len = sizeof(getprop_uuids),
+};
+
+static struct priority_property getprop_bondeddev_props[] = {
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_BONDED_DEVICES,
+ .prop.val = NULL,
+ .prop.len = 0,
+ },
};
static const struct generic_data bluetooth_getprop_bondeddev_success_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = getprop_bondeddev_props,
.expected_adapter_status = BT_STATUS_SUCCESS,
- .expected_property.type = BT_PROPERTY_ADAPTER_BONDED_DEVICES,
- .expected_property.val = NULL,
- .expected_property.len = 0,
};
static bt_scan_mode_t setprop_scanmode_none = BT_SCAN_MODE_NONE;
+static struct priority_property setprop_scanmode_none_props[] = {
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
+ .prop.val = &setprop_scanmode_none,
+ .prop.len = sizeof(setprop_scanmode_none),
+ },
+};
+
static const struct generic_data bluetooth_setprop_scanmode_none_done_test = {
- .expected_hal_cb.adapter_properties_cb = getprop_success_cb,
- .expected_cb_count = 1,
+ .expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
+ .expected_properties_num = 1,
+ .expected_properties = setprop_scanmode_none_props,
.expected_adapter_status = BT_STATUS_DONE,
- .expected_property.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
- .expected_property.val = &setprop_scanmode_none,
- .expected_property.len = sizeof(setprop_scanmode_none),
};
static const struct generic_data bluetooth_discovery_start_success_test = {
@@ -1073,6 +1332,9 @@ static void teardown(const void *test_data)
data->if_bluetooth = NULL;
}
+ if (data->expected_properties_list)
+ g_slist_free(data->expected_properties_list);
+
data->device->close(data->device);
if (data->bluetoothd_pid)
@@ -1122,22 +1384,19 @@ static void test_disable(const void *test_data)
static void test_setprop_bdname_success(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop = &(setprop_bdname_props[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
adapter_status = data->if_bluetooth->set_adapter_property(prop);
-
check_expected_status(adapter_status);
}
static void test_setprop_scanmode_succes(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop = &(setprop_scanmode_props[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1149,8 +1408,7 @@ static void test_setprop_scanmode_succes(const void *test_data)
static void test_setprop_disctimeout_succes(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop = &(setprop_disctimeout_props[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1162,8 +1420,7 @@ static void test_setprop_disctimeout_succes(const void *test_data)
static void test_getprop_bdaddr_success(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t prop = test->expected_property;
+ const bt_property_t prop = setprop_bdaddr_props[0].prop;
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1175,8 +1432,7 @@ static void test_getprop_bdaddr_success(const void *test_data)
static void test_getprop_bdname_success(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop = &(getprop_bdname_props[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1187,12 +1443,10 @@ static void test_getprop_bdname_success(const void *test_data)
adapter_status = data->if_bluetooth->get_adapter_property((*prop).type);
check_expected_status(adapter_status);
}
-
static void test_setprop_uuid_invalid(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop = &(setprop_uuid_prop[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1204,8 +1458,7 @@ static void test_setprop_uuid_invalid(const void *test_data)
static void test_setprop_cod_invalid(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop = &(setprop_cod_props[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1230,8 +1483,7 @@ static void test_setprop_tod_invalid(const void *test_data)
static void test_setprop_rssi_invalid(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop = &(setprop_remote_rssi_props[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1243,8 +1495,7 @@ static void test_setprop_rssi_invalid(const void *test_data)
static void test_setprop_service_record_invalid(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop = &(setprop_service_record_props[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1256,8 +1507,7 @@ static void test_setprop_service_record_invalid(const void *test_data)
static void test_setprop_bdaddr_invalid(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop = &(setprop_bdaddr_props[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1269,8 +1519,8 @@ static void test_setprop_bdaddr_invalid(const void *test_data)
static void test_setprop_scanmode_connectable_success(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop =
+ &(setprop_scanmode_connectable_props[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1282,8 +1532,7 @@ static void test_setprop_scanmode_connectable_success(const void *test_data)
static void test_setprop_bonded_devices_invalid(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop = &(setprop_bonded_devices_props[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1295,8 +1544,7 @@ static void test_setprop_bonded_devices_invalid(const void *test_data)
static void test_getprop_cod_success(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t prop = test->expected_property;
+ const bt_property_t prop = setprop_cod_props[0].prop;
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1308,8 +1556,7 @@ static void test_getprop_cod_success(const void *test_data)
static void test_getprop_tod_success(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t prop = test->expected_property;
+ const bt_property_t prop = setprop_tod_props[0].prop;
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1321,8 +1568,7 @@ static void test_getprop_tod_success(const void *test_data)
static void test_getprop_scanmode_success(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t prop = test->expected_property;
+ const bt_property_t prop = setprop_scanmode_props[0].prop;
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1334,8 +1580,7 @@ static void test_getprop_scanmode_success(const void *test_data)
static void test_getprop_disctimeout_success(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t prop = test->expected_property;
+ const bt_property_t prop = setprop_disctimeout_props[0].prop;
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1347,8 +1592,7 @@ static void test_getprop_disctimeout_success(const void *test_data)
static void test_getprop_uuids_success(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t prop = test->expected_property;
+ const bt_property_t prop = getprop_uuids_props[0].prop;
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1360,8 +1604,7 @@ static void test_getprop_uuids_success(const void *test_data)
static void test_getprop_bondeddev_success(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t prop = test->expected_property;
+ const bt_property_t prop = getprop_bondeddev_props[0].prop;
bt_status_t adapter_status;
init_test_conditions(data);
@@ -1373,8 +1616,7 @@ static void test_getprop_bondeddev_success(const void *test_data)
static void test_setprop_scanmode_none_done(const void *test_data)
{
struct test_data *data = tester_get_data();
- const struct generic_data *test = data->test_data;
- const bt_property_t *prop = &test->expected_property;
+ const bt_property_t *prop = &(setprop_scanmode_none_props[0].prop);
bt_status_t adapter_status;
init_test_conditions(data);
--
1.8.5.2
^ permalink raw reply related
* [PATCH v3 01/15] Bluetooth: Add LMP feature definitions for Secure Connections support
From: Marcel Holtmann @ 2014-01-10 9:29 UTC (permalink / raw)
To: linux-bluetooth
The support for Secure Connections introduces two new controller
features and one new host feature.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 4 ++++
include/net/bluetooth/hci_core.h | 3 +++
2 files changed, 7 insertions(+)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 66c1cd87bfe7..cd40219d32aa 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -282,10 +282,14 @@ enum {
#define LMP_SYNC_TRAIN 0x04
#define LMP_SYNC_SCAN 0x08
+#define LMP_SC 0x01
+#define LMP_PING 0x02
+
/* Host features */
#define LMP_HOST_SSP 0x01
#define LMP_HOST_LE 0x02
#define LMP_HOST_LE_BREDR 0x04
+#define LMP_HOST_SC 0x08
/* Connection modes */
#define HCI_CM_ACTIVE 0x0000
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f2f0cf5865c4..bb984d0626b7 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -803,9 +803,12 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_csb_slave_capable(dev) ((dev)->features[2][0] & LMP_CSB_SLAVE)
#define lmp_sync_train_capable(dev) ((dev)->features[2][0] & LMP_SYNC_TRAIN)
#define lmp_sync_scan_capable(dev) ((dev)->features[2][0] & LMP_SYNC_SCAN)
+#define lmp_sc_capable(dev) ((dev)->features[2][1] & LMP_SC)
+#define lmp_ping_capable(dev) ((dev)->features[2][1] & LMP_PING)
/* ----- Host capabilities ----- */
#define lmp_host_ssp_capable(dev) ((dev)->features[1][0] & LMP_HOST_SSP)
+#define lmp_host_sc_capable(dev) ((dev)->features[1][0] & LMP_HOST_SC)
#define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE))
#define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR))
--
1.8.4.2
^ permalink raw reply related
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