This adds the following tests for encrypted broadcast: ISO Broadcaster Encrypted - Success ISO Broadcaster Receiver Encrypted - Success --- emulator/btdev.c | 8 ++++++ emulator/bthost.c | 5 +++- emulator/bthost.h | 4 ++- monitor/bt.h | 2 ++ tools/iso-tester.c | 64 +++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 74 insertions(+), 9 deletions(-) diff --git a/emulator/btdev.c b/emulator/btdev.c index a04f34d4b..7980a5280 100644 --- a/emulator/btdev.c +++ b/emulator/btdev.c @@ -5,6 +5,7 @@ * * Copyright (C) 2011-2012 Intel Corporation * Copyright (C) 2004-2010 Marcel Holtmann <marcel@xxxxxxxxxxxx> + * Copyright 2023 NXP * * */ @@ -6162,6 +6163,13 @@ static int cmd_big_create_sync_complete(struct btdev *dev, const void *data, dev->big_handle = cmd->handle; bis = conn->data; + if (bis->encryption != cmd->encryption) { + pdu.ev.status = BT_HCI_ERR_ENC_MODE_NOT_ACCEPTABLE; + le_meta_event(dev, BT_HCI_EVT_LE_BIG_SYNC_ESTABILISHED, &pdu, + sizeof(pdu.ev)); + return 0; + } + pdu.ev.handle = cmd->handle; memcpy(pdu.ev.latency, bis->sdu_interval, sizeof(pdu.ev.interval)); pdu.ev.nse = 0x01; diff --git a/emulator/bthost.c b/emulator/bthost.c index 8cdfa0c06..3179bb3d2 100644 --- a/emulator/bthost.c +++ b/emulator/bthost.c @@ -3137,7 +3137,8 @@ void bthost_set_pa_enable(struct bthost *bthost, uint8_t enable) send_command(bthost, BT_HCI_CMD_LE_SET_PA_ENABLE, &cp, sizeof(cp)); } -void bthost_create_big(struct bthost *bthost, uint8_t num_bis) +void bthost_create_big(struct bthost *bthost, uint8_t num_bis, + uint8_t enc, const uint8_t *bcode) { struct bt_hci_cmd_le_create_big cp; @@ -3150,6 +3151,8 @@ void bthost_create_big(struct bthost *bthost, uint8_t num_bis) cp.bis.latency = cpu_to_le16(10); cp.bis.rtn = 0x02; cp.bis.phy = 0x02; + cp.bis.encryption = enc; + memcpy(cp.bis.bcode, bcode, sizeof(cp.bis.bcode)); send_command(bthost, BT_HCI_CMD_LE_CREATE_BIG, &cp, sizeof(cp)); } diff --git a/emulator/bthost.h b/emulator/bthost.h index 92182687f..cdc12dc1c 100644 --- a/emulator/bthost.h +++ b/emulator/bthost.h @@ -5,6 +5,7 @@ * * Copyright (C) 2011-2012 Intel Corporation * Copyright (C) 2004-2010 Marcel Holtmann <marcel@xxxxxxxxxxxx> + * Copyright 2023 NXP * * */ @@ -102,7 +103,8 @@ void bthost_set_ext_adv_params(struct bthost *bthost); void bthost_set_ext_adv_enable(struct bthost *bthost, uint8_t enable); void bthost_set_pa_params(struct bthost *bthost); void bthost_set_pa_enable(struct bthost *bthost, uint8_t enable); -void bthost_create_big(struct bthost *bthost, uint8_t num_bis); +void bthost_create_big(struct bthost *bthost, uint8_t num_bis, uint8_t enc, + const uint8_t *bcode); bool bthost_search_ext_adv_addr(struct bthost *bthost, const uint8_t *addr); void bthost_set_cig_params(struct bthost *bthost, uint8_t cig_id, diff --git a/monitor/bt.h b/monitor/bt.h index 97501c7dc..2548f0dcd 100644 --- a/monitor/bt.h +++ b/monitor/bt.h @@ -5,6 +5,7 @@ * * Copyright (C) 2011-2014 Intel Corporation * Copyright (C) 2002-2010 Marcel Holtmann <marcel@xxxxxxxxxxxx> + * Copyright 2023 NXP * * */ @@ -3720,6 +3721,7 @@ struct bt_hci_evt_le_big_info_adv_report { #define BT_HCI_ERR_CONN_FAILED_TO_ESTABLISH 0x3e #define BT_HCI_ERR_UNKNOWN_ADVERTISING_ID 0x42 #define BT_HCI_ERR_CANCELLED 0x44 +#define BT_HCI_ERR_ENC_MODE_NOT_ACCEPTABLE 0x25 struct bt_l2cap_hdr { uint16_t len; diff --git a/tools/iso-tester.c b/tools/iso-tester.c index aad4b6574..c5c6f0aec 100644 --- a/tools/iso-tester.c +++ b/tools/iso-tester.c @@ -214,7 +214,10 @@ #define AC_11ii_1 QOS_1(10000, 10, 40, 0x02, 2) #define AC_11ii_2 QOS_1(10000, 10, 40, 0x02, 2) -#define QOS_BCAST_FULL(_big, _bis, _in, _out) \ +#define BCODE {0x01, 0x02, 0x68, 0x05, 0x53, 0xf1, 0x41, 0x5a, \ + 0xa2, 0x65, 0xbb, 0xaf, 0xc6, 0xea, 0x03, 0xb8} + +#define QOS_BCAST_FULL(_big, _bis, _encryption, _bcode, _in, _out) \ { \ .bcast = { \ .big = _big, \ @@ -224,8 +227,8 @@ .framing = 0x00, \ .in = _in, \ .out = _out, \ - .encryption = 0x00, \ - .bcode = {0}, \ + .encryption = _encryption, \ + .bcode = _bcode, \ .options = 0x00, \ .skip = 0x0000, \ .sync_timeout = 0x4000, \ @@ -237,24 +240,40 @@ #define BCAST_QOS_OUT(_interval, _latency, _sdu, _phy, _rtn) \ QOS_BCAST_FULL(BT_ISO_QOS_BIG_UNSET, BT_ISO_QOS_BIS_UNSET, \ - {}, QOS_IO(_interval, _latency, _sdu, _phy, _rtn)) + 0x00, {0x00}, {}, \ + QOS_IO(_interval, _latency, _sdu, _phy, _rtn)) + +#define BCAST_QOS_OUT_ENC(_interval, _latency, _sdu, _phy, _rtn) \ + QOS_BCAST_FULL(BT_ISO_QOS_BIG_UNSET, BT_ISO_QOS_BIS_UNSET, \ + 0x01, BCODE, {}, \ + QOS_IO(_interval, _latency, _sdu, _phy, _rtn)) #define BCAST_QOS_OUT_1(_interval, _latency, _sdu, _phy, _rtn) \ QOS_BCAST_FULL(0x01, BT_ISO_QOS_BIS_UNSET, \ - {}, QOS_IO(_interval, _latency, _sdu, _phy, _rtn)) + 0x00, {0x00}, {}, \ + QOS_IO(_interval, _latency, _sdu, _phy, _rtn)) #define BCAST_QOS_OUT_1_1(_interval, _latency, _sdu, _phy, _rtn) \ QOS_BCAST_FULL(0x01, 0x01, \ - {}, QOS_IO(_interval, _latency, _sdu, _phy, _rtn)) + 0x00, {0x00}, {}, \ + QOS_IO(_interval, _latency, _sdu, _phy, _rtn)) #define BCAST_QOS_IN(_interval, _latency, _sdu, _phy, _rtn) \ QOS_BCAST_FULL(BT_ISO_QOS_BIG_UNSET, BT_ISO_QOS_BIS_UNSET, \ + 0x00, {0x00}, \ + QOS_IO(_interval, _latency, _sdu, _phy, _rtn), {}) + +#define BCAST_QOS_IN_ENC(_interval, _latency, _sdu, _phy, _rtn) \ + QOS_BCAST_FULL(BT_ISO_QOS_BIG_UNSET, BT_ISO_QOS_BIS_UNSET, \ + 0x01, BCODE, \ QOS_IO(_interval, _latency, _sdu, _phy, _rtn), {}) #define QOS_OUT_16_2_1 BCAST_QOS_OUT(10000, 10, 40, 0x02, 2) +#define QOS_OUT_ENC_16_2_1 BCAST_QOS_OUT_ENC(10000, 10, 40, 0x02, 2) #define QOS_OUT_1_16_2_1 BCAST_QOS_OUT_1(10000, 10, 40, 0x02, 2) #define QOS_OUT_1_1_16_2_1 BCAST_QOS_OUT_1_1(10000, 10, 40, 0x02, 2) #define QOS_IN_16_2_1 BCAST_QOS_IN(10000, 10, 40, 0x02, 2) +#define QOS_IN_ENC_16_2_1 BCAST_QOS_IN_ENC(10000, 10, 40, 0x02, 2) struct test_data { const void *test_data; @@ -870,6 +889,13 @@ static const struct iso_client_data bcast_16_2_1_send = { .bcast = true, }; +static const struct iso_client_data bcast_enc_16_2_1_send = { + .qos = QOS_OUT_ENC_16_2_1, + .expect_err = 0, + .send = &send_16_2_1, + .bcast = true, +}; + static const struct iso_client_data bcast_1_16_2_1_send = { .qos = QOS_OUT_1_16_2_1, .expect_err = 0, @@ -892,6 +918,14 @@ static const struct iso_client_data bcast_16_2_1_recv = { .server = true, }; +static const struct iso_client_data bcast_enc_16_2_1_recv = { + .qos = QOS_IN_ENC_16_2_1, + .expect_err = 0, + .recv = &send_16_2_1, + .bcast = true, + .server = true, +}; + static void client_connectable_complete(uint16_t opcode, uint8_t status, const void *param, uint8_t len, void *user_data) @@ -1008,7 +1042,9 @@ static void setup_powered_callback(uint8_t status, uint16_t length, if (isodata->bcast) { bthost_set_pa_params(host); bthost_set_pa_enable(host, 0x01); - bthost_create_big(host, 1); + bthost_create_big(host, 1, + isodata->qos.bcast.encryption, + isodata->qos.bcast.bcode); } else if (!isodata->send && isodata->recv) { const uint8_t *bdaddr; @@ -1883,6 +1919,13 @@ static int listen_iso_sock(struct test_data *data) } } + if (setsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, &isodata->qos, + sizeof(isodata->qos)) < 0) { + tester_print("Can't set socket BT_ISO_QOS option: %s (%d)", + strerror(errno), errno); + goto fail; + } + if (listen(sk, 10)) { err = -errno; tester_warn("Can't listen socket: %s (%d)", strerror(errno), @@ -2257,6 +2300,9 @@ int main(int argc, char *argv[]) test_iso("ISO Broadcaster - Success", &bcast_16_2_1_send, setup_powered, test_bcast); + test_iso("ISO Broadcaster Encrypted - Success", &bcast_enc_16_2_1_send, + setup_powered, + test_bcast); test_iso("ISO Broadcaster BIG 0x01 - Success", &bcast_1_16_2_1_send, setup_powered, test_bcast); @@ -2268,6 +2314,10 @@ int main(int argc, char *argv[]) test_iso("ISO Broadcaster Receiver - Success", &bcast_16_2_1_recv, setup_powered, test_bcast_recv); + test_iso("ISO Broadcaster Receiver Encrypted - Success", + &bcast_enc_16_2_1_recv, + setup_powered, + test_bcast_recv); return tester_run(); } -- 2.34.1